You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何用序列化器替换表单实现用户注册登录API?

Got it, let's convert your existing form-based registration and login views into REST APIs using Django REST Framework (DRF). Here's a step-by-step solution that preserves your original business logic while following REST best practices:

1. First, Tweak Your Serializers (for Security & Correctness)

First, update your UserSerializer to mark the password as write_only — this ensures the password is never returned in API responses, which is a critical security practice:

# Serializer.py
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import UserProfileInfo

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)  # Add this line
    
    class Meta():
        model = User
        fields = ('username','email','password')

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta():
        model = UserProfileInfo
        fields = ('phone_no',)

2. Create the Registration API View

Replace your existing register function view with a DRF APIView class. This handles POST requests to create both a User and linked UserProfileInfo:

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import authenticate
from rest_framework.authtoken.models import Token
from .serializers import UserSerializer, UserProfileSerializer
from .models import UserProfileInfo

class RegisterAPIView(APIView):
    def post(self, request):
        # Validate incoming data against both serializers
        user_serializer = UserSerializer(data=request.data)
        profile_serializer = UserProfileSerializer(data=request.data)
        
        if user_serializer.is_valid() and profile_serializer.is_valid():
            # Create and save the User with hashed password
            user = user_serializer.save()
            user.set_password(user.password)  # Hash the password
            user.save()
            
            # Create and link the UserProfileInfo
            profile = profile_serializer.save(commit=False)
            profile.user = user
            profile.registered = True  # Preserve your original logic
            profile.save()
            
            # Generate an auth token for the new user (optional but useful)
            token, created = Token.objects.get_or_create(user=user)
            
            # Return cleaned response (exclude password)
            user_data = user_serializer.data
            return Response({
                "message": "Registration successful",
                "user": user_data,
                "profile": profile_serializer.data,
                "auth_token": token.key
            }, status=status.HTTP_201_CREATED)
        else:
            # Combine errors from both serializers for clarity
            errors = {**user_serializer.errors, **profile_serializer.errors}
            return Response(errors, status=status.HTTP_400_BAD_REQUEST)

3. Create the Login API View

You have two solid options here — a fully custom view (to match your original logic closely) or a modified version of DRF's built-in token view:

Option 1: Custom Login View (Matches Your Original Logic)

class LoginAPIView(APIView):
    def post(self, request):
        username = request.data.get("username")
        password = request.data.get("password")
        
        # Validate required fields
        if not username or not password:
            return Response(
                {"error": "Please provide both username and password"},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # Authenticate the user
        user = authenticate(username=username, password=password)
        
        if user:
            if user.is_active:
                # Get or create auth token
                token, created = Token.objects.get_or_create(user=user)
                return Response({
                    "message": "Login successful",
                    "user": {
                        "username": user.username,
                        "email": user.email
                    },
                    "auth_token": token.key
                }, status=status.HTTP_200_OK)
            else:
                return Response(
                    {"error": "Account not active"},
                    status=status.HTTP_403_FORBIDDEN
                )
        else:
            return Response(
                {"error": "Invalid login credentials"},
                status=status.HTTP_401_UNAUTHORIZED
            )

Option 2: Modified DRF Built-In Token View (Shorter, DRF-Native)

If you prefer using DRF's built-in tools, extend ObtainAuthToken to return additional user data:

from rest_framework.authtoken.views import ObtainAuthToken

class CustomAuthToken(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data, context={"request": request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data["user"]
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            "auth_token": token.key,
            "user_id": user.pk,
            "username": user.username,
            "email": user.email
        })

4. Configure Your URLs

Update urls.py to point to your new API views:

# urls.py
from django.urls import path
from .views import RegisterAPIView, LoginAPIView, CustomAuthToken

urlpatterns = [
    # Registration API
    path("api/register/", RegisterAPIView.as_view(), name="api_register"),
    # Login API (use either your custom view or the DRF modified one)
    path("api/login/", LoginAPIView.as_view(), name="api_login"),
    # path("api/login/", CustomAuthToken.as_view(), name="api_login"),
]

5. Update Settings.py

Enable token authentication in your project settings:

# settings.py
INSTALLED_APPS = [
    # ... your existing apps
    "rest_framework",
    "rest_framework.authtoken",
    "your_app_name",  # Replace with your actual app name
]

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.TokenAuthentication",
    ],
}

6. Test the APIs

You can test these endpoints using tools like Postman, curl, or DRF's built-in browsable API:

  • Registration: Send a POST request to /api/register/ with JSON body:
    {
        "username": "testuser",
        "email": "test@example.com",
        "password": "testpass123",
        "phone_no": "1234567890"
    }
    
  • Login: Send a POST request to /api/login/ with JSON body:
    {
        "username": "testuser",
        "password": "testpass123"
    }
    

The response will include an auth token that you can use to authenticate subsequent API requests (add a header Authorization: Token <your-token>).

内容的提问来源于stack exchange,提问作者Ankit0395

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:18:13