Reputation: 371
Here is the post to add first_name, last_name to the registration view. I want to add some other custom user field beside first_name or last_name. As these field already exist in the user model, He didn't have to edit the user model. But for my case what to do to edit the user model provided by the dj_rest_auth and add some new models?
Upvotes: 3
Views: 3497
Reputation: 37
It works for me in this way:
# serializer.py
from dj_rest_auth.registration.serializers import RegisterSerializer
...
class CustomUserRegisterSerializer(RegisterSerializer, serializers.ModelSerializer):
class Meta:
model = User
fields = ['username','email','usertype','password1', 'password2']
def custom_signup(self, request, user):
user.username = self.validated_data['username']
user.email = self.validated_data['email']
user.usertype = self.validated_data['usertype']
user.password1 = self.validated_data['password1']
user.password2 = self.validated_data['password2']
user.save()
return user
# view.py
class UserRegisterView(CreateAPIView):
def get_queryset(self):
return User.objects.all()
def get_serializer_class(self):
return user_serializers.CustomUserRegisterSerializer
def perform_create(self, serializer):
serializer.save(self.request)
Upvotes: 1
Reputation: 11
It is important to note that you also need to create your CustomRegisterView (or another view) and change the urlpatterns as described in this answer Dj Rest Auth custom registration not working . After that, everything worked for me.
Upvotes: 1
Reputation: 11
I have a better approach, simpler and more flexible. You can use the function custom_signup() provided by django-allauth especially for this case.
class CreateUser_Serializer(RegisterSerializer, serializers.ModelSerializer): class Meta: model = User fields = ("username", "first_name", "last_name", 'email', 'nationality', 'bio', 'phone', 'phone2', 'gender', 'birthday', 'pin_code', 'password1', 'password2') def custom_signup(self, request: Request, user: User) -> None: for f in self.Meta.fields: if hasattr(user, f) and not getattr(user, f): setattr(user, f, self.initial_data[f]) user.save()
output:
Upvotes: 1
Reputation: 371
Ok, you have to create a custom user. Actually I was unsure of what to do as I was using dj_rest_auth package which uses django's default user table to create a api responses. I am leaving this solution, if anyone get stuck in this.
Create an app. I named it accounts. Open models.py and add custom user like this:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
department = models.CharField(max_length=5)
university = models.CharField(max_length=100)
reg_no = models.CharField(max_length=10, blank=True, null=True)
Don't forget to edit the admin.py of this app:
from django.contrib import admin
from .models import CustomUser
admin.site.register(CustomUser)
Create a serializers.py and edit this:
from dj_rest_auth.serializers import UserDetailsSerializer
from rest_framework import serializers
from django.conf import settings
from allauth.account.adapter import get_adapter
from allauth.account.utils import setup_user_email
from dj_rest_auth.registration.serializers import RegisterSerializer
class CustomRegisterSerializer(RegisterSerializer):
reg_no = serializers.CharField(max_length=10)
department = serializers.CharField(required=True, max_length=5)
university = serializers.CharField(required=True, max_length=100)
def get_cleaned_data(self):
data_dict = super().get_cleaned_data()
data_dict['reg_no'] = self.validated_data.get('reg_no', '')
data_dict['department'] = self.validated_data.get('department', '')
data_dict['university'] = self.validated_data.get('university', '')
return data_dict
class CustomUserDetailsSerializer(UserDetailsSerializer):
class Meta(UserDetailsSerializer.Meta):
fields = UserDetailsSerializer.Meta.fields + \
('reg_no', 'is_staff', 'department', 'university',)
You also have to add a adapter.py and add this code:
from allauth.account.adapter import DefaultAccountAdapter
class CustomAccountAdapter(DefaultAccountAdapter):
def save_user(self, request, user, form, commit=False):
user = super().save_user(request, user, form, commit)
data = form.cleaned_data
user.reg_no = data.get('reg_no')
user.department = data.get('department')
user.university = data.get('university')
user.save()
return user
Lastly, you have to add these to the settings.py of your project:
Add your app to the installed app:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts',
'rest_framework',
'rest_framework.authtoken',
'dj_rest_auth',
'allauth',
'allauth.account',
'dj_rest_auth.registration',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.twitter',
]
Add rest auth serializers:
REST_AUTH_SERIALIZERS = {
'USER_DETAILS_SERIALIZER': 'accounts.serializers.CustomUserDetailsSerializer',
'PASSWORD_RESET_SERIALIZER': 'accounts.serializers.CustomPasswordResetSerializer',
}
REST_AUTH_REGISTER_SERIALIZERS = {
'REGISTER_SERIALIZER': 'accounts.serializers.CustomRegisterSerializer',
}
Add adapter and CustomUser model
ACCOUNT_ADAPTER = 'accounts.adapter.CustomAccountAdapter'
AUTH_USER_MODEL = 'accounts.CustomUser'
This problem is solved by this solution. A massive thanks to Rik Schoonbeek for this. Here I also provided the code for showing the extra fields returned in api json data. And that solution was written for django_rest_auth. That package use custom user model from the beginning to do the api calls but dj_rest_auth package uses the default django model and that's why I was unsure to what to do.
Here are some pictures to see this works:
Upvotes: 11