UserProfile.user clash

787 views
Skip to first unread message

Brian Rutledge

unread,
Sep 22, 2016, 3:26:38 PM9/22/16
to Wagtail support
Hi there! I'm experimenting with integrating Wagtail into an existing Django project. We've already got a UserProfile class with a ForeignKey to User. So, when I run "manage.py migrate", I get:

accounts.UserProfile.user: (fields.E304) Reverse accessor for 'UserProfile.user' clashes with reverse accessor for 'UserProfile.user'.
        HINT: Add or change a related_name argument to the definition for 'UserProfile.user' or 'UserProfile.user'.
accounts.UserProfile.user: (fields.E305) Reverse query name for 'UserProfile.user' clashes with reverse query name for 'UserProfile.user'.
        HINT: Add or change a related_name argument to the definition for 'UserProfile.user' or 'UserProfile.user'.
wagtailusers.UserProfile.user: (fields.E304) Reverse accessor for 'UserProfile.user' clashes with reverse accessor for 'UserProfile.user'.
        HINT: Add or change a related_name argument to the definition for 'UserProfile.user' or 'UserProfile.user'.
wagtailusers.UserProfile.user: (fields.E305) Reverse query name for 'UserProfile.user' clashes with reverse query name for 'UserProfile.user'.
        HINT: Add or change a related_name argument to the definition for 'UserProfile.user' or 'UserProfile.user'.

I was able to work around it by removing the "wagtailusers" app, but I definitely want to be able to assign Editor/Moderator roles to users. Looks like I can do that in the Django admin; are there any caveats to that approach? Any other suggested workarounds?

Matthew Westcott

unread,
Sep 23, 2016, 10:18:03 AM9/23/16
to wag...@googlegroups.com
Hi Brian,
I'd consider this to be an oversight on Wagtail's part - we should have given our UserProfile model a related_name like wagtail_userprofile to prevent it from colliding. Will open a ticket to address that...

Setting up users through Django admin should be fine - defining group-level permissions (the other thing provided by the wagtailusers app) would be a bit more fiddly, as that relies on a number of Wagtail-specific models that aren't exposed as standard on Django admin. Another issue is that the wagtailusers.UserProfile model defines whether users receive notification emails for page moderation, so with wagtailusers uninstalled, notification emails will never be sent.

An alternative workaround (which may or may not be practical, depending on the size of your project...) would be to set a custom related_name on your own UserProfile so that it doesn't collide with Wagtail's:
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='myapp_userprofile')

- or disable it entirely with related_name='+'. (Looking through Wagtail's code, it looks like we always access the UserProfile using UserProfile.get_for_user, rather than following the relation - if your app does the same, you shouldn't need related_name at all.)

Cheers,
- Matt

Brian Rutledge

unread,
Sep 23, 2016, 1:18:45 PM9/23/16
to Wagtail support
Thanks, Matt. We're already using the default reverse relationship all over our code, so it'd be a pain to add related_name. I'll keep an eye on the issue.

Laurence Gellert

unread,
Oct 15, 2016, 3:13:15 PM10/15/16
to Wagtail support
This just bit me as well on an Django project where we've already got a customer UserProfile model setup. Adding the related_name='myapp_userprofile' worked, and unit tests caught the places that needed updates.  Let me know the ticket so I can follow it.  Thank you!

Matthew Westcott

unread,
Oct 15, 2016, 3:19:06 PM10/15/16
to wag...@googlegroups.com
Hi Laurence,
This issue is fixed in the forthcoming Wagtail 1.7. The issue / pull request are:
https://github.com/torchbox/wagtail/issues/3025
https://github.com/torchbox/wagtail/pull/3037

Cheers,
- Matt

Scot Hacker

unread,
Nov 9, 2016, 3:36:25 PM11/9/16
to Wagtail support
I'm using wagtail 1.7 and also hitting this issue. In our settings:

`AUTH_USER_MODEL = 'people.UserProfile'`

Now:

`./manage.py shell_plus`  # From django_extensions - shell_plus automatically imports all models

>>> UserProfile.objects.first()
>>> u = UserProfile.objects.first()
>>> type(u)
<class 'NoneType'>

Huh? Ah, it's picking up Wagtail's UserProfile model, and I have no users stored in that table. I can be explicit on the import: 

>>> from people.models import UserProfile
>>> u = UserProfile.objects.first()
>>> type(u)
<class 'people.models.UserProfile'>

I don't see how I can alter the related_name on our own UserProfile since it just subclasses Django's AbstractUser:

`class UserProfile(AbstractUser):`

(i.e. it doesn't have a 'user' field). 
Are there any other ways to disambiguate this? 

Matthew Westcott

unread,
Nov 10, 2016, 5:34:08 AM11/10/16
to wag...@googlegroups.com
Hi Scot,
What you're describing is a somewhat different setup to the others in this thread - conventionally, a UserProfile is a model that's distinct from the main User model and linked through a OneToOneField. The related_name on that field was where we had the naming collision. In your case, you're inheriting from AbstractUser and so your UserProfile model _is_ the main User model.

In this case, what you're seeing isn't really a bug as such. It's valid in Django for two models in different apps to have the same name - indeed, it's fairly unavoidable if those apps originate from different sources - but by automatically importing everything into a flat namespace where one model or the other has to take precedence, django_extensions is disregarding that possibility (or, more likely, they decided it was an acceptable tradeoff to have a feature that adds convenience 98% of the time, even if you still need an explicit import the other 2% of the time). You might find that you can give your own app precedence by reordering them in INSTALLED_APPS.

Cheers,
- Matt
> --
> You received this message because you are subscribed to the Google Groups "Wagtail support" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to wagtail+u...@googlegroups.com.
> To post to this group, send email to wag...@googlegroups.com.
> Visit this group at https://groups.google.com/group/wagtail.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/wagtail/aea29ae6-5fe2-4ccf-afc5-a278286788da%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Scot Hacker

unread,
Nov 10, 2016, 4:38:43 PM11/10/16
to Wagtail support
On Thursday, November 10, 2016 at 2:34:08 AM UTC-8, Matthew Westcott wrote:


In this case, what you're seeing isn't really a bug as such. It's valid in Django for two models in different apps to have the same name - indeed, it's

 OK,  that makes perfect sense now that I think about it. And the only time it would ever be a problem would be with shell_plus, since import paths are explicit everywhere else in our code. Thanks much.

./s

Reply all
Reply to author
Forward
0 new messages