1
votes

I created Django custom user model and added restframework to it. Custom User fields are fname, lname, email,username,password,phone ,gender,acctype. when I register user through the Django restframework, it only takes username,email and password and other field are become empty. what is the problem

my models.py file

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager,User

# Create your models here.

GENDER_CHOICES = (
   ('M', 'Male'),
   ('F', 'Female')
)


class AccountManager(BaseUserManager):
    def create_user(self, email, username, phone, gender, password=None, **extrafields):
        if not email:
            raise ValueError("email is needed")
        if not username:
            raise ValueError("username is needed")
        if not phone:
            raise ValueError("Phone is needed")
        if not gender:
            raise ValueError("gender is needed")
        user= self.model(
            email=self.normalize_email(email),
            username=username,
            phone=phone,
            gender=gender,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self,email,username,phone,gender,password,**extrafields):
        user=self.create_user(
            email=self.normalize_email(email),
            password=password,
            username=username,
            phone=phone,
            gender=gender,

        )
        user.is_admin=True
        user.is_staff=True
        user.is_superuser=True
        user.save(using=self._db)
        return user



class Account(AbstractBaseUser):
    ACCTYPE = (
        ('Student', 'Student'),
        ('Staff', 'Staff')
    )
    fname=models.CharField(verbose_name='fname', max_length=30)
    lname=models.CharField(verbose_name='lname', max_length=30)
    email = models.EmailField(verbose_name='E-mail', max_length=30, unique=True)
    username = models.CharField(verbose_name='Username', max_length=30, unique=True)
    last_login = models.DateTimeField(verbose_name='Last Login', auto_now=True)
    phone = models.CharField(verbose_name='Phone', max_length=10)
    gender = models.CharField(choices=GENDER_CHOICES, max_length=128)
    acctype = models.CharField(max_length=16, choices=ACCTYPE)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_verified = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS=['email', 'phone', 'gender']
    objects=AccountManager()

    def __str__(self):
        return self.username

    def has_perm(self,perm,obj=None):
        return self.is_admin

    def has_module_perms(self, app_lebel):
        return True

serializer.py

from rest_framework import serializers
from rest_auth.registration.serializers import RegisterSerializer
from accounts.models import Account

from rest_auth.registration.serializers import RegisterSerializer


class CustomRegisterSerializer(RegisterSerializer):
        fname = serializers.CharField(required=True)
        lname = serializers.CharField(required=True)
        username=serializers.CharField(required=True)
        email = serializers.EmailField(required=True)
        password1 = serializers.CharField(write_only=True)
        phone=serializers.CharField(required=True)
        gender=serializers.CharField(required=True)
        acctype=serializers.CharField(required=True)

        def get_cleaned_data(self):
            super(CustomRegisterSerializer, self).get_cleaned_data()
            return {
                'password1': self.validated_data.get('password1', ''),
                'email': self.validated_data.get('email', ''),
                'username': self.validated_data.get('username', ''),
                'fname': self.validated_data.get('fname', ''),
                'lname': self.validated_data.get('lname', ''),
                'phone': self.validated_data.get('phone', ''),
                'acctype': self.validated_data.get('acctype', ''),
                'gender': self.validated_data.get('gender', ''),
            }

class CustomUserDetailsSerializer(serializers.ModelSerializer):

        class Meta:
            model = Account
            fields = ('pk','email','fname','lname','username','phone','gender','acctype')
            read_only_fields = ('email','acctype','fname','lname')

views.py

from django.shortcuts import render
from rest_framework import generics
from rest_auth.registration.views import RegisterView
from .models import Account


# Create your views here.


class CustomRegisterView(RegisterView):
    queryset = Account.objects.all()
2

2 Answers

1
votes

Django-allauth doesn't allow saving custom fields by default

To solve this problem I refined a save function inside CustomRegisterSerializer and simply assign the custom field values. Then saved it using user.save()

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.fname=self.cleaned_data.get('fname')
        user.lname=self.cleaned_data.get('lname')
        user.phone=self.cleaned_data.get('phone')
        user.acctype=self.cleaned_data.get('acctype')
        user.gender=self.cleaned_data.get('gender')

        user.save()

        return user
0
votes
serializer.py

from rest_framework import serializers
from accounts.models import Account


class CustomRegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = '__all__'


views.py

from rest_framework import viewsets
from .models import Account
from .serializer import CustomRegisterSerializer # import serializer as your path defined

class CustomRegisterView(viewsets.ModelViewSet):
    serializer_class = CustomRegisterSerializer
    queryset = Account.objects.all()