0
点赞
收藏
分享

微信扫一扫

Django模板标签CSRF

在这里插入图片描述

系列文章目录

  • Django入门全攻略:从零搭建你的第一个Web项目
  • Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作
  • Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解
  • Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践
  • 跨域问题与Django解决方案:深入解析跨域原理、请求处理与CSRF防护
  • Django视图层探索:GET/POST请求处理、参数传递与响应方式详解
  • Django路由与会话深度探索:静态、动态路由分发,以及Cookie与Session的奥秘
  • Django API开发实战:前后端分离、Restful风格与DRF序列化器详解
  • Django REST framework序列化器详解:普通序列化器与模型序列化器的选择与运用
  • 还在写0.0…

文章目录


前言

    在 Django REST framework 中,数据序列化至关重要。本文将探讨 普通序列化器模型序列化器,了解它们的基本功能和差异,帮助您根据项目需求选择合适的序列化器。


Response是不能直接返回ORM数据的,所以需要我们进行序列化操作,可以通过手动将其转为字典或JSON,也可以使用DRF所提供的序列化器,一般建议使用序列化器
如果你经常使用的是自己去将数据封装为JSON,那么常见的代码模型就像这样

data = models.objects.all()
json_data = {}
for d in data:
    json_data['age'] = d.age
    json_data['name'] = d.name
return Response(json_data)

随字段越来越多,工作量会越来越大,而且有关于时间(DateTimeField、DateField)等字段类型的序列化直接通过JSON也是不行的,需要自己手动编写JSON的序列化器,非常麻烦,于是乎 DRF 就提供了更为便捷的两种序列化器,普通序列化器模型序列化器


一、普通序列化器-Serializer

1. 普通序列化器编写方式

普通序列化器,可以按照给定字段,将所匹配的ORM数据字段转换为JSON数据,不光可以对一条数据,也可以对一个QuerySet所对应的结果集


例如:

#models.py
from django.db import models

# Create your models here.
class UserModel(models.Model):
    name = models.CharField(max_length=50)
    phone = models.CharField(max_length=11)
    password = models.CharField(max_length=30)
    info = models.CharField(max_length=100, null=True)

    def __str__(self):
        return self.name
    class Meta:
        db_table = 'user'
#userSerializer.py
class UserSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=50)
    phone = serializers.CharField(validators=[validators_phone])
    password = serializers.CharField(max_length=30)
    info = serializers.CharField(max_length=100,default="默认值")


2. 普通序列化器序列化

序列化就是将ORM数据放入序列化器加工,诞生出JSON数据对象,序列化器对象的data属性即为处理好的 JSON 数据对象

#views.py
class UserIdView(APIView):
    def get(self, request, id):
        user = UserModel.objects.get(pk=id)
        usSer = UserSerializer(instance=user)

        return Response({"message": "get测试成功!", "data": usSer.data})

#views.py
class UserView(APIView):

    def get(self, request):
        users = UserModel.objects.all()
        usSer = UserSerializer(instance=users, many=True)
        return Response({"message":"get测试成功!","data":usSer.data})


Serializer属性中选项参数

选项参数名称作用
max_length最大长度
min_length最小长度
allow_blank是否允许为空
trim_whitespace是否截断空白字符
max_value最大值
min_value最小值
通用参数名称作用
read_only该字段仅用于序列化输出,需要序列化输出时设置:read_only=True;默认为False
write_only该字段仅用于反序列输入,需要序列化输入时设置:write_only=True;默认为False
required该字段表示在反序列化输入时必须输入
default反序列化时使用的默认值
allow_null表明该字段是否允许传入None,默认False
validators对字段进行校验,定义在字段中
error_message当字段校验不通过时,报error_message的value值
label用于HTML展示API页面时,显示的字段名称
help_text用于HTML展示API页面时,显示的字段帮助提示信息

3. 普通序列化器反序列化创建


#userSerializer.py
from rest_framework import serializers
from app.models import UserModel
import re

def validators_phone(values):
    r_phone = r"^1[3-9]\d{9}$"
    if re.match(r_phone, values):
        print("手机号匹配成功!")
    else:
        print("手机号匹配失败,抛出异常!")
        raise serializers.ValidationError("手机号匹配失败!不满足规则!")


class UserSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=50)
    phone = serializers.CharField(validators=[validators_phone])
    password = serializers.CharField(max_length=30)
    info = serializers.CharField(max_length=100,default="默认值")
#userSerializer.py
class UserSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=50)
    phone = serializers.CharField(validators=[validators_phone])
    password = serializers.CharField(max_length=30)
    info = serializers.CharField(max_length=100,default="默认值")

    def create(self, validated_data):
        object = UserModel.objects.create(**validated_data)
        return object
        
#具体来说,**validated_data的作用是:解包字典。
#它将validated_data字典中的键值对解包为一系列的关键字参数。
# views.py
class UserView(APIView):

    def post(self, request):
        ser = UserSerializer(data=request.data) # 传参data,进行反序列化
        if ser.is_valid():
            print("校验成功!")
            ser.save()
            return Response({"message":"[POST]信息添加成功!"})
        else:
            print("校验失败!")
            return Response({"message": ser.errors})

4. 普通序列化器反序列化更新

# userSerializer.py
class UserSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=50)
    phone = serializers.CharField(validators=[validators_phone])
    password = serializers.CharField(max_length=30)
    info = serializers.CharField(max_length=100,default="默认值")

    def update(self, instance, validated_data):
        # instance 要更新的数据,validated_data 是新数据
        instance.name = validated_data.get('name', instance.name)
        instance.phone = validated_data.get('phone', instance.phone)
        instance.password = validated_data.get('password', instance.password)
        instance.info = validated_data.get('info', instance.info)
        instance.save()
        return instance

#获取字段值:
#validated_data.get('name') 尝试从 validated_data 字典中获取键为 'name' 的值。
#validated_data 是由序列化器在验证请求数据后生成的一个字典,它包含了经过验证的字段和它们的值。

#默认值机制:
#get 方法有一个可选的第二个参数,即默认值。如果 'name' 这个键不存在于validated_data 中,get 方法将返回这个默认值。
#在这个例子中,如果请求数据中没有包含 'name' 字段,那么默认值就是 instance.name,即当前模型实例的 name 字段的值。

然后通过PUT传递要更新数据的ID,以及更新后的值,来为某条数据更新

class UserIdView(APIView):
    def put(self, request, id):
        user = UserModel.objects.get(pk=id)
        ser = UserSerializer(instance=user, data=request.data)
        if ser.is_valid():
            print("校验成功!")
            ser.save()
            return Response({"message": "[PUT]信息修改成功!"})
        else:
            print("校验失败!")
            return Response({"message": ser.errors})

5. 普通序列化器完整代码

models.py:

from django.db import models

# Create your models here.
class UserModel(models.Model):
    name = models.CharField(max_length=50)
    phone = models.CharField(max_length=11)
    password = models.CharField(max_length=30)
    info = models.CharField(max_length=100, null=True)

    def __str__(self):
        return self.name
    class Meta:
        db_table = 'user'

userSerializer.py:

from rest_framework import serializers
from app.models import UserModel
import re

def validators_phone(values):
    r_phone = r"^1[3-9]\d{9}$"
    if re.match(r_phone, values):
        print("手机号匹配成功!")
    else:
        print("手机号匹配失败,抛出异常!")
        raise serializers.ValidationError("手机号匹配失败!不满足规则!")


class UserSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=50)
    phone = serializers.CharField(validators=[validators_phone])
    password = serializers.CharField(max_length=30)
    info = serializers.CharField(max_length=100,default="默认值")

    def create(self, validated_data):
        object = UserModel.objects.create(**validated_data)
        return object

    def update(self, instance, validated_data):
        # instance 要更新的数据,validated_data 是新数据
        instance.name = validated_data.get('name', instance.name)
        instance.phone = validated_data.get('phone', instance.phone)
        instance.password = validated_data.get('password', instance.password)
        instance.info = validated_data.get('info', instance.info)
        instance.save()
        return instance

views.py:

from rest_framework.views import APIView
from rest_framework.response import Response
from app.models import UserModel
from app.serializer.userSerializer import UserSerializer
from django.shortcuts import render

# Create your views here.


class UserView(APIView):

    def get(self, request):
        users = UserModel.objects.all()
        usSer = UserSerializer(instance=users, many=True)
        return Response({"message":"get测试成功!","data":usSer.data})

    def post(self, request):
        ser = UserSerializer(data=request.data) # 传参data,进行反序列化
        if ser.is_valid():
            print("校验成功!")
            ser.save()
            return Response({"message":"[POST]信息添加成功!"})
        else:
            print("校验失败!")
            return Response({"message": ser.errors})

class UserIdView(APIView):
    def get(self, request, id):
        user = UserModel.objects.get(pk=id)
        usSer = UserSerializer(instance=user)

        return Response({"message": "get测试成功!", "data": usSer.data})

    def put(self, request, id):
        user = UserModel.objects.get(pk=id)
        ser = UserSerializer(instance=user, data=request.data)
        if ser.is_valid():
            print("校验成功!")
            ser.save()
            return Response({"message": "[PUT]信息修改成功!"})
        else:
            print("校验失败!")
            return Response({"message": ser.errors})

urls.py:

from django.urls import path
from app.views import UserView,UserIdView

urlpatterns = [
    path('user/', UserView.as_view()),
    path('user/<int:id>/', UserIdView.as_view()),
]


二、模型序列化器-ModelSerializer

1. 模型序列化器编写方式



模型类关联序列化器用的是新的序列化器基类

from rest_framework.serializers import ModelSerializer
# userModelSerializer.py
from rest_framework import serializers
from app.models import UserModel

class UserModelSerializer(serializers.ModelSerializer):
    # 不需要再重写 create 和 update 方法了,可查看ModelSerializer源码
    class Meta:
        model = UserModel
        fields = '__all__' # 指明所有模型类字段

        # exclude = ('password',) # 排除掉的字段
        # read_only_fields = ('name','info') # 只用于序列化的字段
        # fields = ('name','phone','password','info')
        # extra_kwargs = {
        #     'info':{'min_length':5, 'required':True},
        # } #修改原有字段的选项参数

2. 模型序列化器反序列化创建、更新

from rest_framework.views import APIView
from rest_framework.response import Response
from app.models import UserModel
from app.serializer.userModelSerializer import UserModelSerializer

# Create your views here.

class UserView(APIView):

    def get(self, request):
        users = UserModel.objects.all()
        usSer = UserModelSerializer(instance=users, many=True)
        return Response({"message":"get测试成功!","data":usSer.data})

    def post(self, request):
        ser = UserModelSerializer(data=request.data) # 传参data,进行反序列化
        if ser.is_valid():
            print("校验成功!")
            ser.save()
            return Response({"message":"[POST]信息添加成功!"})
        else:
            print("校验失败!")
            return Response({"message": ser.errors})

class UserIdView(APIView):
    def get(self, request, id):
        user = UserModel.objects.get(pk=id)
        usSer = UserModelSerializer(instance=user)

        return Response({"message": "get测试成功!", "data": usSer.data})

    def put(self, request, id):
        user = UserModel.objects.get(pk=id)
        ser = UserModelSerializer(instance=user, data=request.data)
        if ser.is_valid():
            print("校验成功!")
            ser.save()
            return Response({"message": "[PUT]信息修改成功!"})
        else:
            print("校验失败!")
            return Response({"message": ser.errors})

3. 模型序列化器与普通序列化器的对比

  • 序列化时,将模型类对象传入instance参数
    • 序列化结果使用序列化器对象的data属性获取得到
  • 反序列化创建时,将要被反序列化的数据传入data参数
    • 反序列化一定要记得先使用is_valid校验
  • 反序列化更新时,将要更新的数据对象传入instance参数,更新后的数据传入data参数
  • 模型序列化器普通序列化器更加方便,自动生成序列化映射字段,createupdate方法等
  • 关联外键序列化,字段属性外键为时要记得加many=True

在这里插入图片描述

举报

相关推荐

0 条评论