2010-02-07 35 views
7

En primer lugar, sé cómo solucionar el problema, solo estoy tratando de entender por qué está ocurriendo. El mensaje de error:Modelos Django: ¿Por qué el nombre choca?

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'.

Y el código:

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 he entendido bien, esta línea:

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

causará un atributo que se añadirán a la clase Address con el nombre profile. ¿Qué está creando el otro nombre de "perfil"?


¿Qué sucede si no necesito un nombre inverso? ¿Hay alguna forma de desactivarlo? Las direcciones se utilizan para una docena de cosas, por lo que la mayoría de las relaciones inversas estarán en blanco de todos modos.

¿Hay alguna forma de copiar los campos de dirección en el modelo en lugar de tener una tabla separada para las direcciones? Sin la herencia de Python (esto no tiene sentido, y si un Modelo tiene 2 direcciones, no funciona).

Respuesta

24

en el django docs que dice:

Si prefiere Django no creó una relación hacia atrás, ajuste related_name a '+'. Por ejemplo, esto asegurará que el modelo de usuario no obtendrá una relación imposible para este modelo:

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

pero nunca he probado a mí mismo ....

+0

¡No vi eso, gracias! Sintaxis extraña – mpen

+0

Esta es definitivamente la forma correcta de desactivarlo. – Exelian

+0

se originó a partir de ese https://code.djangoproject.com/ticket/5537 –

1

no estoy seguro de que el campo profile errante está viniendo ... Pero una manera de averiguarlo sería: retirando temporalmente la address = models.ForeignKey(…) de perfil, ./manage.py shell, from ... import Address luego ver lo que Address.profile le dirá.

No creo que hay alguna manera oficial para heredar sólo los campos de algún otro modelo sin necesidad de utilizar la herencia ... Pero se podría fingir como este (donde SourceModel es, por ejemplo, Address y TargetModel es, por ejemplo, Profile) :

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

(esto viene de Django's ModelBase __new__ implementation)

+0

hizo lo que usted ha dicho. 'AttributeError: type object 'Address' no tiene atributo 'profile''. En realidad ... sin nombrarlo ya no me está dando un error. No estoy seguro de lo que cambié>. mpen

0

no creo que es posible desactivar el nombre inverso.

Acabo de hacer una rápida grep sobre el código y no parece que haya ninguna lógica que evitará la configuración del campo related_name en el modelo relacionado.

Cuestiones relacionadas