2011-06-06 3 views
3

I ont les modèles suivants (simplifié):Django Champ de modèle avec plusieurs types?

class Structure(models.Model): 
name=models.CharField(max_length=100, unique=True) 

class Unit(models.Model): 
name=models.CharField(max_length=100, unique=True) 

Chaque modèle, dispose également d'un champ builtFrom, qui montre ce que l'élément est construit à partir, par exemple:

class Unit(models.Model): 
name=models.CharField(max_length=100, unique=True) 
builtFrom=models.ForeignKey(Structure) 

Cependant, builtFrom peut être rempli à partir d'un type d'unité ou d'un type de structure. Y at-il un moyen facile de représenter cela dans mes modèles?

La seule chose que je peux penser est d'avoir un modèle distinct, comme ceci:

class BuiltFromItem(models.Model): 
structure=models.ForeignKey(Structure) 
unit=models.ForeignKey(Structure) 


class Unit(models.Model): 
name=models.CharField(max_length=100, unique=True) 
builtFrom=models.ForeignKey(BuiltFromItem) 

Et alors l'un des champs BuiltFromItem être juste nul. Ensuite, lorsque j'ai besoin des données, déterminez si c'est une structure ou une unité à partir de laquelle elles sont construites. Y a-t-il une meilleure solution pour cela?

Répondre

3

Vous voulez que les documents Django se réfèrent à un "generic relation". Le support pour eux est intégré dans Django.

1

La relation générique est probablement la meilleure approche, mais elle peut être un peu problématique, si vous prévoyez de gérer de tels modèles via le panneau d'administration. Vous devrez alors ajouter un ModelInline aux modèles, que la relation générique pointe vers, mais pour autant que je sache (corrigez-moi si je me trompe), il n'y a aucun moyen pratique de choisir l'objet connexe de l'autre côté (du modèle , où relation est définie), autre que le choix de la classe du modèle et la saisie manuelle de la clé primaire de l'instance.

La meilleure solution dépend de la structure de vos modèles et de ce qu'ils ont en commun. Une autre idée que j'ai, est d'utiliser Multi-table inheritance, en définissant une BasicObject qui est un objet parent à Structure et Unit modèles:

class BasicObject(models.Model): 
    name=models.CharField(max_length=100, unique=True) 
    #other common data 
    builtFrom=models.ForeignKey('BasicObject') 

class Structure(BasicObject): 
    #data specific to Structure 

class Unit(BasicObject): 
    #data specific to Unit 

Maintenant, tous les objets Structure et Unit aura aussi BasicObject cas, et vous serez en mesure de remplir le champ builtFrom avec l'instance BasicObject appropriée. Cela rend les requêtes plus coûteuses, car les données sont divisées en deux tables différentes, vous devriez donc considérer si cette approche est bénéfique dans votre cas.

Questions connexes