我使用dj-rest-auth,django-allauth和djangorestframework-simplejwt.I,我想自定义dj-rest-auth登录器,以包括以下附加字段:(first_name,last_name,phone_number),验证它们,验证它们并正确登录。另外,我使用电子邮件而不是用户名作为我的主要标识符。这是我的自定义用户模型:
from django.db import models
from django.contrib.auth.models import AbstractUser, BaseUserManager
from phonenumber_field.modelfields import PhoneNumberField
class CustomUserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
if not email:
raise ValueError("An email has to be set")
user = self.model(email=self.normalize_email(email), **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password, **extra_fields):
extra_fields.setdefault("is_staff", False)
extra_fields.setdefault("is_superuser", False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
if extra_fields.get("is_staff") is not True:
raise ValueError("Superuser must have is_staff=True.")
if extra_fields.get("is_superuser") is not True:
raise ValueError("Superuser must have is_superuser=True.")
return self._create_user(email, password, **extra_fields)
class CustomUserModel(AbstractUser):
username = None
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
phone_number = PhoneNumberField()
bio = models.TextField(null=True, blank=True)
age = models.PositiveIntegerField(null=True, blank=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = [
"first_name",
"last_name",
"phone_number",
]
def __str__(self):
return self.first_name + " " + self.last_name
objects = CustomUserManager()这是我的serializer.py:
from django.conf import settings
from django.contrib.auth import get_user_model, authenticate
from rest_framework import serializers, exceptions
from dj_rest_auth.registration.serializers import RegisterSerializer
from dj_rest_auth.serializers import LoginSerializer
from allauth.account.adapter import get_adapter
from phonenumber_field.serializerfields import PhoneNumberField
class UserListSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
read_only_fields = [
"id",
"is_superuser",
"first_name",
"last_name",
"phone_number",
"bio",
"age",
"date_joined",
]
fields = [
"id",
"is_superuser",
"first_name",
"last_name",
"phone_number",
"bio",
"age",
"date_joined",
]
class UserDetailSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = [
"id",
"is_superuser",
"email",
"password",
"first_name",
"last_name",
"phone_number",
"date_joined",
"last_login",
"bio",
"age",
]
read_only_fields = [
"is_superuser",
"password",
]
class CustomRegisterSerializer(RegisterSerializer):
username = None
first_name = serializers.CharField(max_length=50)
last_name = serializers.CharField(max_length=50)
phone_number = PhoneNumberField()
class Meta:
model = get_user_model()
fields = [
"email",
"first_name",
"last_name",
"phone_number",
"password",
]
def get_cleaned_data(self):
return {
"email": self.validated_data.get("email", ""),
"first_name": self.validated_data.get("first_name", ""),
"last_name": self.validated_data.get("last_name", ""),
"phone_number": self.validated_data.get("phone_number", ""),
"password1": self.validated_data.get("password1", ""),
"password2": self.validated_data.get("password2", ""),
}
def save(self, request):
adapter = get_adapter()
user = adapter.new_user(request)
self.cleaned_data = self.get_cleaned_data()
user.first_name = self.cleaned_data.get("first_name")
user.last_name = self.cleaned_data.get("last_name")
user.phone_number = self.cleaned_data.get("phone_number")
user.save()
adapter.save_user(request, user, self)
return user
UserModel = get_user_model()
class CustomLoginSerializer(LoginSerializer):
username = None
first_name = serializers.CharField()
last_name = serializers.CharField()
phone_number = PhoneNumberField()
def authenticate(self, **options):
return authenticate(self.context["request"], **options)
def validate(self, attrs):
email = attrs.get("email")
first_name = attrs.get("first_name")
last_name = attrs.get("last_name")
phone_number = attrs.get("phone_number")
password = attrs.get("password")
if email and first_name and last_name and phone_number and password:
user = authenticate(
email=email,
first_name=first_name,
last_name=last_name,
phone_number=phone_number,
pasword=password,
)
if not user:
msg = "Incorrect credentials."
raise serializers.ValidationError(msg, code="authorization")
else:
msg = "No email provided."
raise exceptions.ValidationError(msg)
attrs["user"] = user
return attrs这是我的views.py:
from django.contrib.auth import get_user_model
from rest_framework import generics
from .serializers import UserListSerializer, UserDetailSerializer
class UserListView(generics.ListCreateAPIView):
queryset = get_user_model().objects.all()
serializer_class = UserListSerializer
class UserDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = get_user_model().objects.all()
serializer_class = UserDetailSerializer我有所有的设置正确的设置,所以我没有问题。我的定制注册工作也很好,每件事都很好。我只是不能正确地覆盖登录序列化程序。对于我的端点url,我使用的是address auth的默认地址“address auth/配准/”地址。
发布于 2022-12-03 19:20:03
我希望你能找到正确的方法。我在LoginSerializer上也有同样的问题,直到我将它添加到settings.py中
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True这是我的serializers.py
class AccountLoginSerializer(LoginSerializer):
username = None
def authenticate(self, **options):
return authenticate(self.context["request"], **options)
def validate(self, attrs):
email = attrs.get("email")
ip_address = get_client_ip(self.context["request"])[0]
password = attrs.get("password")
if email and password:
'''Check if IP address belongs to account with given email address'''
try:
if Account.objects.get(email=email).ip_address.filter(ip_address=ip_address).exists():
user = authenticate(
email=email,
password=password,
)
else:
msg = "IP address doesn't match. An email has been sent to verify this IP address."
raise serializers.ValidationError(msg, code="authorization")
if not user:
msg = "Invalid credentials."
raise serializers.ValidationError(msg, code="authorization")
except ObjectDoesNotExist:
msg = "Invalid credentials."
raise serializers.ValidationError(msg, code="authorization")
else:
msg = "No email provided."
raise exceptions.ValidationError(msg)
attrs["user"] = user
return attrs希望它能帮助有同样问题的人。
https://stackoverflow.com/questions/73455860
复制相似问题