2👍
The problem here is that you inherit your model twice, and both the child models have the same name. This results in having twice the same related_name, which is a problem for Django.
Your solution to add
member = models.OneToOneField(Member, related_name="%(app_label)s_%(class)s_related")"
in your MemberExtra
model works, but you loose the implicit inheritance magic that Django do to let you access both your models in one:
With your solution you have to do:
from programsite.models import MemberExtra
m = MemberExtra.objects.get(member__full_name = "Foobar")
m.email # -> returns the email of your MemberExtra instance
m.member.b_add # -> returns the address of the inherited member instance
Where, with the Django native inheritance, you can do:
from programsite.models import MemberExtra
m = MemberExtra.objects.get(full_name = "Foobar")
m.email # -> returns the email of your MemberExtra instance
m.b_add # -> returns the address of the inherited member instance
Which is much cleaner in my opinion.
To manage the inheritance, Django actually creates a OneToOneField
(https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance).
This field is called <parentclass>_ptr
, member_ptr
in you case.
If you manually create a OneToOneField
named <parentclass>_ptr
, and give it a related_name, Django is still able to find the parent model, and will not complain about identical related_names.
In your case, just add
member_ptr = models.OneToOneField(Member, related_name="%(app_label)s_%(class)s_related")"
in both your MemberExtra
model definitions.
This solution works, but is not how it should be done. Django provides a flag parent_link
that, when set to true, will tell Django that this is the field that will be used to access the parent class.
So you can add a field
member = models.OneToOneField(Member, parent_link=True, related_name="%(app_label)s_%(class)s_related")"
which will still work if, for some reason, Django needs to rename the default pointer to the parent.
1👍
The related_name
for a FK has to be unique. When you have an FK with a default related_name
(unspecified), that is inherited by multiple other models, all of the models end up with the same related_name
. See the section in the Django docs entitled Be careful with related_name
.
The solution is to set the related_name
argument of the FK to something like:
prog = models.ForeignKey(Program, verbose_name=_("Program"), related_name="%(app_label)s_%(class)s_related")
Django will then sub the app label and module name into to the string, making the related_name
unique for each of the subclasses.