Django models: Why the name clash?

Firstly, I know how to fix the problem, I'm just trying to understand why it's occuring. The error message:

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

And the 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)

If I understand correctly, this line:

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

Will cause an attribute to be added to the Address class with the name profile. What's creating the other "profile" name?


What if I don't need a reverse name? Is there a way to disable it? Addresses are used for a dozen things, so most of the reverse relationships will be blank anyway.

Is there a way to copy the address fields into the model rather than having a separate table for addresses? Without Python inheritance (this doesn't make sense, and if an Model has 2 addresses, it doesn't work).

Answers


in the django docs it says:

If you'd prefer Django didn't create a backwards relation, set related_name to '+'. For example, this will ensure that the User model won't get a backwards relation to this model:

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

but I never tried it myself....


I'm not sure where the errant profile field is coming from… But one way to find out would be: temporary remove address = models.ForeignKey(…) from Profile, ./manage.py shell, from ... import Address then see what Address.profile will tell you.

I don't think there is any official way to inherit only the fields from some other Model without using inheritance… But you could fake it like this (where SourceModel is, eg, Address and TargetModel is, eg, Profile):

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

(this is coming from Django's ModelBase __new__ implementation)


I don't think it's possible to disable the reverse name.

I've just done a quick grep over the code and it doesn't look like there is any logic which will bypass setting up the related_name field on the related model.


Need Your Help

How to reset or change the passphrase for a GitHub SSH key?

git github ssh ssh-keys passphrase

I have forgoten my passphrase in Git. How do I reset it? I found two solutions on Stack Overflow, but I want to know what process to follow to reset it or to get it.

PostgreSQL "DESCRIBE TABLE"

postgresql psql table-structure

How do you perform the equivalent of Oracle's DESCRIBE TABLE in PostgreSQL (using the psql command)?