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).
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With