In my project I was handling User profiles by creating a OneToOneField linking to Django’s User table, like so:
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('User'), related_name='settings', auto_created=True, on_delete=models.CASCADE)
Now I’m switching to (my) library that handles this a bit differently: it uses model inheritance for user profiles, declares some fields of its own in an abstract class. I’m now basing my model upon the library’s. Me and my team decided this is the best way to implement user profiles and it simply differs from one of my oldest implementations in this particular project. The intent is, of course, to utilise the library’s APIs for handling profiles and gain from common development benefits.
Anyway, upon basing my Profile model on the new inheritance-based model, like so:
class UserSettings(BaseProfile):
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('User'), related_name='settings',
auto_created=True, on_delete=models.CASCADE, parent_link=True, primary_key=True)
when running makemigrations, django now complains that:
<class 'nalet.admin.UserSettingsInline'>: (admin.E202) 'nalet.UserSettings' has more than one ForeignKey to 'auth.User'.
I have investigated the issue and Django seems to be forcing this OneToOneField to have to be named user_ptr. Simply declaring a dummy user_ptr field eliminates issues with makemigrations command.
The documentation says nothing about the field having to be named exactly like that. From the docs I surmised that adding the parent_link=True
should be enough, but it seems I was only reading what suited me.
OTOH, I was surprised that django didn’t complain that my dummy user_ptr = models.IntegerField(null=True)
did not result in a name clash as there’s a check in django code if the field name had been used already.
Questions:
- Is the documentation imprecise or does the code have a bug not using my customised link field, but accepting it when I override its own idea of the field name?
- Will my dummy field workaround even work or will it just mess everything up?