OK, I give up. Actually I asked another question related to this topic before developing the application but the answers were similar to yours. (https://groups.google.com/forum/#!topic/django-developers/EnMn9_hU5g0)
I had to use monkey-patching to allow dynamic AUTH_USER_MODEL but it wasn't a good idea so later I decided to separate the admin part and use different AUTH_USER_MODEL settings for each app. However, even separating the applications does not solve the problem because the core Django code does not assume that I can have different AUTH_USER_MODEL settings even if I use them in different server instances. Actually the customer model and staff model don't share and fields except password, last_login and created_at but since I use OneToOneField in order to map extra fields it's ok to store all common type of data in one table. I don't really like the idea of providing a regular customer user for staffs because when a staff logins into admin site, he/she also logins into the frontend site which makes harder to view the site as anonymous. Also it becomes much more difficult if I develop a feature "Login as x customer". The only useful solution that I found is to move the admin page to another subdomain (with reverse proxies like nginx) in order to prevent them to share cookies. And I also created 2 proxy models called customer and staff and modified their managers so that they can act like separate models. On Friday, February 14, 2014 12:45:16 AM UTC+2, Russell Keith-Magee wrote: > > > On Fri, Feb 14, 2014 at 1:06 AM, Burak Emre Kabakcı > <[email protected]<javascript:> > > 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/414e4c4e-b5a0-47cc-a217-e65a18ce2cb1%40googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
