2011-11-02 2 views
2

En tant que projet pour comprendre Django, j'essaye de construire un petit jeu.Modèles Django: Champ de référence renvoyer plusieurs types de modèles

Un joueur a une base. Une base a plusieurs types d'objets qu'elle peut abriter. (Véhicule, Défense, Bâtiment).

J'ai 3 tables statiques qui contiennent des informations pour le premier niveau de chaque élément (dans le jeu, ces valeurs sont utilisées dans les formules pour calculer des choses pour les mises à niveau). J'ai utilisé une séquence pour insérer tous ces éléments dans ces différentes tables afin que les ID soient uniques à travers les tables.

Pour garder une trace de ce que le joueur a par base j'ai une table 'Propriété'. Je veux utiliser un seul champ comme référence à l'identifiant d'un objet et essayer de le faire avec les modèles Django. Attention: mes connaissances sur les modèles Django sont assez limitées et je suis coincé avec ça depuis quelques jours maintenant. Est-ce possible et si oui, comment cela peut-il être fait? J'ai essayé d'utiliser des annotations sur la méthode save pour changer la valeur d'un champ en écrasant le champ avec l'identifiant de cet objet avant d'essayer d'interroger l'objet par l'identifiant en essayant d'obtenir l'objet, mais je peux t franchir la restriction évidente du modèle lors de la définition ce champ comme un entier - je l'espérais ne validerait pas jusqu'à ce que j'appelé sauvegarde()

def getPropertyItemID(func): 
    """ 
    This method sets the referral ID to an item to the actual ID. 
    """ 

    def decoratedFunction(*args): 
     # Grab a reference to the data object we want to update. 
     data_object=args[0] 

     # Set the ID if item is not empty. 
     if data_object.item is not None: 
      data_object.item=data_object.item.id 

     # Execute the function we're decorating 
     return func(*args) 

    return decoratedFunction 

class Property(models.Model): 
    """ 
    This class represents items that a user has per base. 
    """ 

    user=models.ForeignKey(User) 
    base=models.ForeignKey(Base) 
    item=models.IntegerField() 
    amount=models.IntegerField(default=0) 
    level=models.SmallIntegerField(default=0) 

    class Meta: 
     db_table='property' 

    @getPropertyItemID 
    def save(self): 
     # Now actually save the object 
     super(Property, self).save() 

J'espère que vous pouvez me aider. Le résultat final, je voudrais être en mesure de mettre à profit serait quelque chose comme:

# Adding - automatically saving the ID of item regardless of the class 
    # of item 
    item = Property(user=user, base=base, item=building) 
    item.save() 

    # Retrieving - automatically create an instance of an object based on the ID 
    # of item, regardless of the table this ID is found in. 
    building = Property.objects.all().distinct(True).get(base=base, item=Building.objects.all().distinct(True).get(name='Tower')) 
    # At this point building should be an instance of the Building model 

Si je suis complètement et je peux y parvenir autrement je suis toutes les oreilles :)

Répondre

3

I pensez que vous êtes à la recherche d'un Generic Relationship:

class Property(models.Model): 
    user=models.ForeignKey(User) 
    base=models.ForeignKey(Base) 
    content_type = models.ForeignKey(ContentType) # Which model is `item` representing? 
    object_id = models.PositiveIntegerField() # What is its primary key? 
    item=generic.GenericForeignKey('content_type', 'object_id') # Easy way to access it. 
    amount=models.IntegerField(default=0) 
    level=models.SmallIntegerField(default=0) 

Cela vous permet de créer des articles que vous avez mentionné, mais vous auriez besoin probablement de regarder une autre façon de filtrer les articles sur.

+0

C'est génial. La sauvegarde des propriétés fonctionne parfaitement. Le seul inconvénient est que je dois utiliser "building = Property.objects.all(). Get (base = base, object_id = building.id)" au lieu de item = building, mais cela fonctionnera très bien. Merci! – Cornelis