DRF 入门教程 02

Django-Rest 入门教程

在进行序列化的时候,serializers 帮我我们创建好了, save 方法 通过了 is_valid 就可以保存到数据库中。

但是有的什么我们要需要自定义验证的时候, 就不能这样做了。

在序列化器中使用 create函数和调用save函数的区别在于,create函数会在保存对象之前执行一些额外的逻辑,例如验证数据或设置默认值。而调用save函数则直接保存对象,不会执行任何额外的逻辑。因此,如果需要在保存对象之前执行一些额外的逻辑,应该使用create函数。如果不需要执行额外的逻辑,可以直接调用save函数。

创建一个Views

# appdemo/views.py
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK, HTTP_404_NOT_FOUND, HTTP_201_CREATED, HTTP_400_BAD_REQUEST, \
    HTTP_204_NO_CONTENT
from rest_framework.views import APIView

from appdemo.models import User
from appdemo.serializers import UserViewSerializer


class UserViewsApi(APIView):
    def get(self, request, pk, *args, **kwargs):
        try:
            user_info = User.objects.get(id=pk)
        except ObjectDoesNotExist:
            return Response({"error": "User not found"}, status=HTTP_404_NOT_FOUND)

        serializer = UserViewSerializer(instance=user_info)
        return Response({
            'status': HTTP_200_OK,
            "msg": "get user list successful..",
            "data": serializer.data
        })

    def post(self, request, *args, **kwargs):
        serializer = UserViewSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response({
            "msg": serializer.errors
        }, status=HTTP_400_BAD_REQUEST)

    def put(self, request, pk, *args, **kwargs):
        try:
            user = User.objects.get(id=pk)
        except ObjectDoesNotExist:
            return Response({'error': 'User not found'}, status=HTTP_404_NOT_FOUND)
        serializer = UserViewSerializer(instance=user, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"msg": " update successful", "status": HTTP_200_OK, "data": serializer.data})
        return Response({
            "msg": serializer.errors
        }, status=HTTP_400_BAD_REQUEST)

添加序列化器

# appdemo/serializers.py

from appdemo.models import User
from rest_framework import serializers
from django.contrib.auth.hashers import make_password

class UserViewSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

    # 局部钩子
    def validate_u_name(self, value):
        """ 验证用户注册的时候, 用户名必须全为字母, 否则抛出异常 """
        if not value.isalpha():
            raise serializers.ValidationError('Username must be alphabetic')
        # 返回全是字母的用户名
        return value

    # 全局钩子
    def validate(self, data):
        u_password = data.get('u_password')
        "验证密码, 首字母必须大写 否则抛出异常"
        if u_password.istitle():
            return data
        raise serializers.ValidationError('The first letter of the password must be capitalized')


    def create(self, validated_data):
        """
        自定义 create, 入库之前, 密码加密!
        """
        """
        视图中调用serializer.save()方法时,Django REST framework会根据请求的方法(POST、PUT、PATCH等)
        自动调用序列化器的create()或update()方法来创建或更新对象。如果您在序列化器中定义了create()或update()方法,
        那么这些方法将会被调用来执行相应的操作。如果您没有定义这些方法,Django REST framework会使用默认的实现来创建或更新对象。
        因此,如果您想要在创建或更新对象时执行一些自定义的操作,可以在序列化器中重写create()或update()方法。
        """
        # validated_data 返回的是一个字典, pop 是一个字典的方法, 删除key 的时候, 返回对应的 values.
        password = validated_data.pop('u_password')
        # make_password django, 自带的密码加密!
        encrypted_password = make_password(password)
        # 创建一条数据
        user = User.objects.create(
            **validated_data,
            u_password=encrypted_password
        )
        # 返回
        return user

    def update(self, instance, validated_data):
        # 检查更新后的用户名是否已经存在
        """ 数据库自带验证了。 """
        username = validated_data.get('u_name')
        if User.objects.filter(u_name=username).exclude(id=instance.id).exists():
            raise serializers.ValidationError('Username already exists !')


        """ 获取在更新之前,更新日志 等 """
        """ 这只是模拟, 但是你可以在这里实现 相应的代码逻辑 """
        print('update, logging')

        # 调用父类的update()方法来更新对象
        instance = super().update(instance, validated_data)
        return instance

添加路由

# /DjangoRestDemo/DjangoRestDemo/urls.py
# 增加如下内容:
from django.urls import path
from appdemo.views import UserViewsApi
urlpatterns = [
    path('user/<int:pk>', UserViewsApi.as_view()),
]






posted @ 2023-07-04 09:55  Handsome、Snake  阅读(14)  评论(0编辑  收藏  举报