问题
I wonder if is it possible to use the default django.contrib.auth.models.User
to store admins users, users created with python manage.py createsuperuser
, but use another table to store registered by form users, also users that will be registered with Social provides (python-social-auth
). By using another table for users I will need to use the same password hashing also.
Use a 1-to-1 relationship with auth_users
is not an option.
Thanks.
回答1:
Well, this is how I did this:
From python-social-auth docs is possible define a custom model:
SOCIAL_AUTH_USER_MODEL = 'foo.bar.User'
Here I got an error when I tried 'myapp.models.MyUserModel'
, this must be: 'myapp.MyUserModel'
.
This fixed the python-social-auth
register.
For a common form register I just did a form and create a user in MyUserModel
:
class RegisterAction(FormView):
form_class = RegisterForm
def form_valid(self, form):
MyUserModel.objects.create(
first_name=form.data.get('f_name'),
password=form.data.get('pwd'),
email=form.data.get('email'),
newsletter=form.data.get('newsletter')
)
return super(RegisterAction, self).form_valid(form)
def get_success_url(self):
return reverse('home')
You can find docs for FormView
here.
To fix the autentication methods I created a custom authentication backend:
from django.contrib.auth.hashers import check_password
from myapp.models import MyUserModel
class MyAuthenticationBackend(object):
MODEL = MyUserModel
def authenticate(self, email, password):
"""
Returns a User (MODEL instance) if email and password match
"""
if email and password:
try:
user = self.MODEL.objects.get(email=email)
if check_password(password=password, encoded=user.password):
return user
return None
except self.MODEL.DoesNotExist:
return None
return None
def get_user(self, user_id):
"""
Returns a User based on user_id
"""
try:
user = self.MODEL.objects.get(pk=user_id)
return user
except self.MODEL.DoesNotExist:
return None
except self.MODEL.MultipleObjectsReturned:
return None
You can find authentication backends docs here and how write your own backend here.
Then you need to register your new backend:
# Authentication Backends
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'myapp.backends.MyAuthenticationBackend',
'social.backends.facebook.FacebookOAuth2',
'social.backends.twitter.TwitterOAuth',
]
You will find AUTHENTICATION_BACKENDS
settings docs here
Now I can go to a shell:
>>> from django.contrib.auth import authenticate
>>> authenticate(email='someuser@somemail.com', password='123')
<MyUserModel: MyUserModel object>
>>>
And still can create user with python manage.py createsuperuser
, which are stored in default auth_user
table.
来源:https://stackoverflow.com/questions/35775374/work-with-two-users-table