Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest-auth allauth registration with email, first and last name, and without username

I am using django-rest-auth and allauth for login and registration in my django app. I haven't written any extra single line of code of my own for login or registration. Registration is successful with emailid and provided password.

I am not using username for authentication, instead email.

In my browsable api for registration I get following:

enter image description here

Along with these fields I want to have first_name and last_name (the default auth_user table had these columns) so that my newly created auth_user also has these fields set along with email and hashed password.

How can I achieve this? This browsable form itself is not so important but being able to store first_name and last_name is what I need primarily.

like image 613
Thinker Avatar asked Apr 28 '16 09:04

Thinker


2 Answers

  1. Make sure you have ACCOUNT_USERNAME_REQUIRED = False in your settings.py file.

  2. For first_name and last_name you need to write a custom RegisterSerializer (https://github.com/Tivix/django-rest-auth/blob/master/rest_auth/registration/serializers.py#L166)

here's a sample code for serializers.py

from allauth.account import app_settings as allauth_settings from allauth.utils import email_address_exists from allauth.account.adapter import get_adapter from allauth.account.utils import setup_user_email  class RegisterSerializer(serializers.Serializer):     email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)     first_name = serializers.CharField(required=True, write_only=True)     last_name = serializers.CharField(required=True, write_only=True)     password1 = serializers.CharField(required=True, write_only=True)     password2 = serializers.CharField(required=True, write_only=True)      def validate_email(self, email):         email = get_adapter().clean_email(email)         if allauth_settings.UNIQUE_EMAIL:             if email and email_address_exists(email):                 raise serializers.ValidationError(                     _("A user is already registered with this e-mail address."))         return email      def validate_password1(self, password):         return get_adapter().clean_password(password)      def validate(self, data):         if data['password1'] != data['password2']:             raise serializers.ValidationError(                 _("The two password fields didn't match."))         return data      def get_cleaned_data(self):         return {             'first_name': self.validated_data.get('first_name', ''),             'last_name': self.validated_data.get('last_name', ''),             'password1': self.validated_data.get('password1', ''),             'email': self.validated_data.get('email', ''),         }      def save(self, request):         adapter = get_adapter()         user = adapter.new_user(request)         self.cleaned_data = self.get_cleaned_data()         adapter.save_user(request, user, self)         setup_user_email(request, user, [])         user.save()         return user 
  1. In settings.py make sure you add to refer to new Serializer.

    REST_AUTH_REGISTER_SERIALIZERS = {         'REGISTER_SERIALIZER': 'path.to.RegisterSerializer', } 
like image 81
girish Avatar answered Sep 27 '22 22:09

girish


You can also just overwrite the custom_signup method on RegisterSerializer, which is intended for this purpose.

from rest_auth.registration.serializers import RegisterSerializer from rest_auth.registration.views import RegisterView from rest_framework import serializers   class NameRegistrationSerializer(RegisterSerializer):    first_name = serializers.CharField(required=False)   last_name = serializers.CharField(required=False)    def custom_signup(self, request, user):     user.first_name = self.validated_data.get('first_name', '')     user.last_name = self.validated_data.get('last_name', '')     user.save(update_fields=['first_name', 'last_name'])   class NameRegistrationView(RegisterView):   serializer_class = NameRegistrationSerializer 

Then use the following in your urls.py

url(r'^rest-auth/registration/name-registration/$', NameRegistrationView.as_view(), name="rest_name_register") 

or set REGISTER_SERIALIZER in settings.py

REST_AUTH_REGISTER_SERIALIZERS = {     'REGISTER_SERIALIZER': 'path.to.RegisterSerializer', } 
like image 37
Tritlo Avatar answered Sep 27 '22 23:09

Tritlo