On Fri, Feb 14, 2014 at 1:06 AM, Burak Emre Kabakcı
<[email protected]>wrote:
> I have two applications: One of them uses default auth.User model and the
> other one uses another AbstractUser class configured as AUTH_USER_MODEL.
> These two apps uses same codebase except their settings.py file. One of the
> models has a ForeignKey field in relation with auth.User model (I use
> auth.User as the staff model) and due to restriction of auth.User I'm not
> able to run the other application since I use custom AUTH_USER_MODEL.
> Django throws this error:
>
> django.core.management.base.CommandError: One or more models did not
> validate:
> model: 'staff' defines a relation with the model 'auth.User', which has
> been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
>
> I couldn't get why the usage of User model is restricted in this case. The
> only workaround I can found is monkey-patching the swappable field in User
> model's Meta field.
>
It's not clear if this question is better suited for django-users, or if
you're asking with a view to contributing a patch to Django. For future
reference, if this is a "How can I do this" question, it's better suited to
Django-users.
However, if you're considering options for "fixing" this: The reason the
validation code does this is to ensure that the authentication code will
work.
At a conceptual data storage level, what you describe would be fine - admin
users are normal auth.Users, regular users are myauth.MyUser. However, a
user model isn't just used for data storage -- it's used for authentication
and login, and Django's authentication framework can only handle one
authentication model. AUTH_USER_MODEL defines which model that will be.
So - if the model validation code allowed for the situation you describe,
you would have an admin user model, but no admin user would ever be able to
log in.
This isn't *necessarily* insurmountable; the auth backends tool would, in
principle, allow authentication against different data sources; we'd just
need to have a "I don't care what AUTH_USER_MODEL says, use auth.User"
ModelBackend in addition to the actual ModelBackend that Django provides
out of the box. You'd also need to make some changes to ensure that even
though AUTH_USER_MODEL has been swapped out, you still want it to be
synchronised - as currently set up, defining a value for AUTH_USER_MODEL
other than auth.User causes auth.User to not be created on disk.
However, I'm not convinced that this would be a worthwhile set of changes.
If you go back to your original use case - why do you need two user models?
Is there any reason that this can't be done the way Django does this right
now - with a single user model that has a concept of "admin"? If 'system'
users have additional data requirements, or you want to maintain a
foreign-key level protection to ensure that admin users can't "own" data,
then add a profile model to capture the idea of a 'system' user, and keep a
foreign key between that user and the base User model. This approach
separates the two concepts of authentication and authorisation -- the User
model is used to identify that person X is who they say they are, the
profile model is used to determine that person X is allowed to see
particular content.
This approach has the added bonus that administrative users can be regular
users in the system if the need arises without requiring a separate login
to the system.
Alternatively, if you really do have a strong reason why you need to have
two different types of user model, you could define your own version of
auth.User -- using the abstract base classes provided, this is a 3 line
definition:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
and then duplicate the logic in django.contrib.auth.backends.ModelBackend
to provide authentication against this model. Essentially this is
duplicating all the auth.User functionality in your own set of "admin auth"
models.
Yours,
Russ Magee %-)
--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/CAJxq84--MZHZ5zu8fxgbP__bKCb9hyNTL-58tSg%3DAnwYhmqJOg%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.