10
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:
1
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:
- [Django]-Zsh: command not found: django-admin when starting a django project
- [Django]-How to serialize recursive relationship with self in Django REST Framework?
- [Django]-Import data into Django model with existing data?
- [Django]-Form loses ability to send POST requests after 2 ajax updates
- [Django]-Django Unittest doesn't load fixtures
1
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.
- [Django]-How to use math remainder in django template?
- [Django]-Deploying django app with heroku β gunicorn not installing
- [Django]-Resource temporarily unavailable: mod_wsgi (pid=28433): Unable to connect to WSGI daemon process
- [Django]-Django channels 'No application configured for scope type 'websocket''
- [Django]-Forcing Django to use INNER JOIN instead of LEFT OUTER JOIN
0
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)
- [Django]-Django β queryset with extra method returns empty, count() says otherwise
- [Django]-Collectstatic command not run when deploying to Heroku, but setup is perfectly fine