2010-02-07 6 views
7

In primo luogo, so come risolvere il problema, sto solo cercando di capire perché si sta verificando. Il messaggio di errore:Modelli di Django: perché il nome si scontra?

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

E il codice:

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) 

Se ho capito bene, questa linea:

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

causerà un attributo da aggiungere alla classe Address con la nome profile. Cosa sta creando il altro nome "profilo" ?


Cosa succede se non ho bisogno di un nome inverso? C'è un modo per disabilitarlo? Gli indirizzi sono usati per una dozzina di cose, quindi la maggior parte delle relazioni inverse sarà comunque vuota.

C'è un modo per copiare i campi dell'indirizzo nel modello piuttosto che avere una tabella separata per gli indirizzi? Senza ereditarietà di Python (questo non ha senso, e se un modello ha 2 indirizzi, non funziona).

risposta

24

nel django docs si dice:

se si preferisce Django non ha creato una relazione a ritroso, impostare related_name a '+'. Ad esempio, questo farà sì che il modello utente non sarà possibile ottenere un rapporto all'indietro per questo modello:

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

ma non ho mai provato io stesso ....

+0

Non l'ho visto, grazie! Sintassi strana. – mpen

+0

Questo è sicuramente il modo corretto per disabilitarlo. – Exelian

+0

originato da https://code.djangoproject.com/ticket/5537 –

1

non sono sicuro dove il errante profile campo viene da ... Ma un modo per scoprirlo sarebbe: rimuovere temporanea address = models.ForeignKey(…) dal profilo, ./manage.py shell, from ... import Address poi vedere che cosa Address.profile vi dirà.

Io non credo che ci sia alcun modo ufficiale per ereditare solo i campi da qualche altro modello senza usare l'ereditarietà ... Ma si poteva fingere come questo (dove SourceModel è, ad esempio, Address e TargetModel è, ad esempio, Profile) :

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

(questo viene da Django's ModelBase __new__ implementation)

+0

Forse quello che hai detto. 'AttributeError: type object 'Address' non ha attributo 'profile''. In realtà ... senza nominarlo non mi dà più errori. Non sono sicuro di cosa ho cambiato>. mpen

0

non credo che sia possibile disabilitare il nome inverso.

Ho appena fatto un rapido grep sul codice e non sembra che ci sia una logica che aggirerà l'impostazione del campo related_name sul modello correlato.

Problemi correlati