2010-02-07 2 views
7

Tout d'abord, je sais comment résoudre le problème, j'essaie simplement de comprendre pourquoi cela se produit. Le message d'erreur:Modèles Django: Pourquoi le nom est-il en conflit?

users.profile: Reverse query name for field 'address' clashes with related field 'Address.profile'. Add a related_name a rgument to the definition for 'address'.

Et le code:

class Address(models.Model): 
    country = fields.CountryField(default='CA') 
    province = fields.CAProvinceField() 
    city = models.CharField(max_length=80) 
    postal_code = models.CharField(max_length=6) 
    street1 = models.CharField(max_length=80) 
    street2 = models.CharField(max_length=80, blank=True, null=True) 
    street3 = models.CharField(max_length=80, blank=True, null=True) 

class Profile(Address): 
    user = models.ForeignKey(User, unique=True, related_name='profile') 
    primary_phone = models.CharField(max_length=20) 
    address = models.ForeignKey(Address, unique=True) 

Si je comprends bien, cette ligne:

address = models.ForeignKey(Address, unique=True) 

PROVOQUERONT un attribut à ajouter à la classe Address avec le nom profile. Que crée le autre "profil" nom?


Que faire si je n'ai pas besoin d'un nom inversé? Y a-t'il une manière de le désactiver? Les adresses sont utilisées pour une douzaine de choses, donc la plupart des relations inverses seront vides de toute façon.

Existe-t-il un moyen de copier les champs d'adresse dans le modèle plutôt que d'avoir une table distincte pour les adresses? Sans l'héritage Python (cela n'a pas de sens, et si un Model a 2 adresses, ça ne marche pas).

Répondre

24

dans le django docs il est dit:

Si vous préférez Django n'a pas créé une relation en arrière, mis à related_name '+'. Par exemple, il veillera à ce que le modèle de l'utilisateur ne sera pas obtenir un rapport en arrière pour ce modèle:

user = models.ForeignKey(User, related_name='+') 

mais je jamais essayé moi-même ....

+0

Je n'ai pas vu ça, merci! Syntaxe bizarre. – mpen

+0

C'est certainement le bon moyen de le désactiver. – Exelian

+0

provient de ce https://code.djangoproject.com/ticket/5537 –

1

Je ne suis pas sûr où le champ profile errante vient ... Mais une façon de savoir serait: supprimer temporaire address = models.ForeignKey(…) de profil, ./manage.py shell, from ... import Address voir alors ce que Address.profile vous le dira.

Je ne pense pas qu'il y ait de façon officielle d'hériter seulement les champs d'un autre modèle sans utiliser l'héritage ... Mais vous pourriez faux comme ça (où SourceModel est, par exemple, Address et TargetModel est, par exemple, Profile) :

for field in SourceModel._meta.fields: 
    TargetModel.add_to_class(field.name, copy.deepcopy(field)) 

(cela vient de Django's ModelBase __new__ implementation)

+0

fait ce que vous avez dit. 'AttributeError: l'objet type 'Address' n'a pas d'attribut 'profile''. En fait .... sans le nommer, ça ne me donne plus d'erreur. Je ne suis pas sûr de ce que j'ai changé>. mpen

0

Je ne pense pas qu'il est possible de désactiver le nom inverse.

Je viens de faire un rapide grep sur le code et il ne semble pas y avoir de logique qui contournera la configuration du champ related_name sur le modèle associé.