Django REST Auth定制咨询:移除password2与重复邮箱错误解决
Hey there! Let's fix your two Django REST Auth customization issues step by step:
password2 Field from Registration The default RegisterSerializer includes both password and password2 for confirmation. To keep only one password field, we need to override the serializer to exclude password2 and skip the password confirmation check.
Here's how to update your customRegisterSerializer:
from .models import User from rest_framework import serializers from rest_auth.registration.serializers import RegisterSerializer from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenRefreshSerializer from rest_framework_simplejwt.tokens import RefreshToken from allauth.account import app_settings as allauth_settings from allauth.utils import email_address_exists from allauth.account.adapter import get_adapter from allauth.account.utils import setup_user_email from django.utils.translation import ugettext_lazy as _ from datetime import datetime, timedelta from django.db import IntegrityError class customRegisterSerializer(RegisterSerializer): username = None # Explicitly remove the password2 field from the serializer password2 = None userName = serializers.CharField(required=True) profile = serializers.ImageField(use_url=True) def validate_email(self, email): email = get_adapter().clean_email(email) if allauth_settings.UNIQUE_EMAIL: if email and email_address_exists(email): raise serializers.ValidationError(_("A user is already registered with this e-mail address.")) return email def validate_password(self, password): # Only validate the single password field, no cross-check needed return get_adapter().clean_password(password) def get_cleaned_data(self): return { 'email': self.validated_data.get('email', ''), 'password': self.validated_data.get('password', ''), 'userName': self.validated_data.get('userName', ''), 'profile': self.validated_data.get('profile', ''), } def save(self, request): adapter = get_adapter() user = adapter.new_user(request) self.cleaned_data = self.get_cleaned_data() try: # Use allauth's adapter to handle base user setup adapter.save_user(request, user, self) # Set password directly from the validated single password field user.set_password(self.cleaned_data['password']) user.save() # Maintain allauth's email setup flow setup_user_email(request, user, []) except IntegrityError as e: # Fallback for edge cases where validation might miss duplicates if 'UNIQUE constraint failed: api_user.email' in str(e): raise serializers.ValidationError(_("A user is already registered with this e-mail address.")) raise e return user
Key changes made:
- Added
password2 = Noneto remove the redundant confirmation field - Updated the
savemethod to properly use allauth'sadapter.save_user()for consistent user setup - Added a fallback
try-exceptblock to catch database-level duplicate errors just in case - Ensured we still call
setup_user_emailto keep allauth's email functionality intact
The raw UNIQUE constraint failed error occurred because your original save method was saving the user before the serializer's validation could run properly. With the updated code above:
- The
validate_emailmethod runs first, checking for existing users via allauth'semail_address_exists()function and throwing a friendly validation error - The fallback
try-exceptblock catches any edge cases where the validation might miss a duplicate, converting the database error into a user-friendly message
Make sure you've configured your urls.py to use your custom serializer for registration:
from rest_auth.registration.views import RegisterView from .serializers import customRegisterSerializer urlpatterns = [ # ... your other URLs path('rest-auth/registration/', RegisterView.as_view(serializer_class=customRegisterSerializer), name='rest_register'), ]
That should resolve both of your issues: users will only need to enter one password during registration, and duplicate emails will show a clear, user-friendly error instead of a raw database constraint message.
内容的提问来源于stack exchange,提问作者leedjango

