Work with two Users table

痞子三分冷 提交于 2019-12-24 16:39:52

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!