ARTICLE AD BOX
I need some advice from the devs out there who are experienced in Django. I am relatively new to this framework and am working on a pharmacy management app with a Django-powered backend. I plan to use mobile number as the way to sign up into the app. Most built-in classes provide email as the default way to register and create new users. I am using DRF for the REST API stuff, dj-rest-auth and django-allauth for handling authentication. Right now I am working only on user accounts within the app. Could you please give a check and point out the mistakes. Any advice on the best practices would be appreciated.
Here's the custom user model
from django.contrib.auth.models import AbstractUser from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ from .managers import CustomUserManager from django.core.validators import RegexValidator phone_validator = RegexValidator(regex=r"^[1-9]\d{9}$", message="Invalid Number") class UserRole(models.TextChoices): RETAILER = "RETAILER", "retailer" STAFF = "STAFF", "staff" class CustomUser(AbstractUser): username = None mobile = models.CharField(max_length=10, validators=[phone_validator], unique=True) role = models.CharField( max_length=20, choices=UserRole.choices, default=UserRole.STAFF ) tenant = models.ForeignKey( "tenants.Tenant", on_delete=models.CASCADE, null=True, blank=True, related_name="users", ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) objects = CustomUserManager() USERNAME_FIELD = "mobile" REQUIRED_FIELDS = [] def __str__(self): return f"{self.mobile} ({self.get_full_name()})"Here are the custom serializers.
from dj_rest_auth.serializers import LoginSerializer from dj_rest_auth.registration.serializers import RegisterSerializer from rest_framework import serializers from allauth.account.adapter import get_adapter class MobileLoginSerializer(LoginSerializer): username = None mobile = serializers.CharField(required=True) def validate(self, attrs): attrs["username"] = attrs.get("mobile") return super().validate(attrs) class MobileRegisterSerializer(RegisterSerializer): username = None first_name = serializers.CharField() last_name = serializers.CharField() mobile = serializers.CharField() pharmacy_name = serializers.CharField(write_only=True) role = serializers.ChoiceField(choices=["RETAILER", "STAFF"]) def get_cleaned_data(self): data = super().get_cleaned_data() data.update( { "first_name": self.validated_data.get("first_name", ""), "last_name": self.validated_data.get("last_name", ""), "mobile": self.validated_data.get("mobile", ""), "pharmacy_name": self.validated_data.get("pharmacy_name", ""), "role": self.validated_data.get("role", ""), } ) return data def save(self, request): adapter = get_adapter() user = adapter.new_user(request) self.cleaned_data = self.get_cleaned_data() user = adapter.save_user(request, user, self, commit=False) user.first_name = self.cleaned_data.get("first_name") user.last_name = self.cleaned_data.get("last_name") user.mobile = self.cleaned_data.get("mobile") # user.pharmacy_name = self.cleaned_data.get("pharmacy_name") user.role = self.cleaned_data.get("role") user.save() self.custom_signup(request, user) return userHere are the relevant code snippets from settings.py
... REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["dj_rest_auth.jwt_auth.JWTCookieAuthentication"] } REST_AUTH = { "USE_JWT": True, "JWT_AUTH_COOKIE": "access", "JWT_AUTH_REFRESH_COOKIE": "refresh", "JWT_AUTH_HTTPONLY": True, "LOGIN_SERIALIZER": "accounts.serializers.MobileLoginSerializer", "REGISTER_SERIALIZER": "accounts.serializers.MobileRegisterSerializer", } AUTH_USER_MODEL = "accounts.CustomUser" ACCOUNT_USER_MODEL_USERNAME_FIELD = "mobile" ACCOUNT_EMAIL_REQUIRED = False ACCOUNT_USERNAME_REQUIRED = False ACCOUNT_AUTHENTICATION_METHOD = "username" ... SITE_ID = 1P.S.: I do not trust the AI responses. Different agents are suggesting different approaches and now I am confused.
