restframework——序列化组件

models.py前端

from django.db import models # Create your models here.
__all__ = ["Book", "Publisher", "Author"] class Book(models.Model): title = models.CharField(max_length=32) CHOICES = ((1, "Python"), (2, "Linux"), (3, "go")) category = models.IntegerField(choices=CHOICES, null=True, blank=True) pub_time = models.DateField() publisher = models.ForeignKey(to="Publisher") authors = models.ManyToManyField(to="Author") class Publisher(models.Model): title = models.CharField(max_length=32) def __str__(self): return self.title class Author(models.Model): name = models.CharField(max_length=32) def __str__(self): return self.name

  urls.pypython

from django.conf.urls import url, include from .views import BookView,BookEditView urlpatterns = [ url(r'^book/$', BookView.as_view()), url(r'^book/(?P<id>\d+)', BookEditView.as_view()), ]

 

序列化 post请求(新增数据)数据库

 视图函数django

from rest_framework.response import Response from djangoDemo.models import Book from .serializers import BookSerializer class BookView(APIView): def get(self, request): book_queryset = Book.objects.all() # [book_obj, ]
        # 用序列化器进行序列化
        ser_obj = BookSerializer(book_queryset, many=True) return Response(ser_obj.data) # 新增数据
    def post(self, request): # 从前端获得的请求数据
        book_obj = request.data # print(book_obj)
        # BookSerializer(data=book_obj) 反序列化的时候必须指定data=
        ser_obj = BookSerializer(data=book_obj) # 对数据进行校验
        if ser_obj.is_valid(): ser_obj.save() print(ser_obj.validated_data) return Response(ser_obj.validated_data) return Response(ser_obj.errors)

 

 序列化器: serializers.pyide

一.声明序列化类函数

from rest_framework import serializers from djangoDemo.models import Book class PublisherSerializer(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) class AuthorSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(max_length=32)

 

二.外键关系的序列化post

class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) title = serializers.CharField(max_length=32, validators=[my_validate,]) pub_time = serializers.DateField() category = serializers.CharField(source="get_category_display", read_only=True) post_category = serializers.IntegerField(write_only=True) publisher = PublisherSerializer(read_only=True) # 内部经过外键关系的id找到了publisher_obj
    # PublisherSerializer(publisher_obj)
    authors = AuthorSerializer(many=True, read_only=True)

 

反序列化ui

当前端给咱们发post的请求的时候~前端给咱们传过来的数据~咱们要进行一些校验而后保存到数据库~url

这些校验以及保存工做,DRF的Serializer也给咱们提供了一些方法了~~spa

首先~咱们要写反序列化用的一些字段~有些字段要跟序列化区分开~~

Serializer提供了.is_valid()  和.save()方法~~

-- 正序和反序列化字段不统一 -- required=False 只序列化不走校验 -- read_only=True 只序列化用 -- write_only=True 只反序列化用 -- 重写create方法

-- 验证经过返回ser_obj.validated_data

-- 验证不经过返回ser_obj.errors

 

class BookSerializer(serializers.Serializer): # required=False 表示不作校验
    id = serializers.IntegerField(required=False) title = serializers.CharField(max_length=32,validators=[my_validate,]) pub_time = serializers.DateField() category = serializers.CharField(source="get_category_display", read_only=True) publisher = PublisherSerializer(read_only=True) authors = AuthorSerializer(many=True, read_only=True) post_category = serializers.IntegerField(write_only=True) publisher_id = serializers.IntegerField(write_only=True) author_list = serializers.ListField(write_only=True) def create(self, validated_data): # print(validated_data)
        # 这是validated_data
        ''' { 'title': '侠客行', 'pub_time': datetime.date(2018, 11, 14), 'post_category': 1, 'publisher_id': 1, 'author_list': [1, 2] } ''' book_obj = Book.objects.create(title=validated_data['title'], pub_time=validated_data['pub_time'], category=validated_data['post_category'], publisher_id=validated_data['publisher_id']) # 多对多字段添加
        book_obj.authors.add(*validated_data['author_list']) return book_obj
View Code

 

反序列化put/patch请求(更新数据)

视图函数 views.py

class BookEditView(APIView): def get(self, request, id): book_obj = Book.objects.filter(id=id).first() ser_obj = BookSerializer(book_obj) return Response(ser_obj.data) # put post 都是反序
    # 更新数据
    def put(self, request, id): book_obj = Book.objects.filter(id=id).first() ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) return Response(ser_obj.errors)

 

序列化器 serializers.py

-- 重写update方法 -- ser_obj = BookSerializer(instance=obj, data=request.data, partial=True) -- 验证经过返回ser_obj.validated_data -- 验证不经过返回ser_obj.errors

 

def update(self, instance, validated_data): instance.title = validated_data.get('title', instance.title) instance.pub_time = validated_data.get('pub_time', instance.pub_time) instance.category = validated_data.get('category', instance.category) instance.publisher_id = validated_data.get('publisher_id', instance.publisher_id) if validated_data.get('author_list'): instance.authors.set(validated_data['author_list']) instance.save() return instance

 

验证

单个字段的验证  权重 222
    def validate_title(self, value): print(2222) # value就是title的值 对value处理
        if "python" not in value.lower(): raise serializers.ValidationError("标题必须含有python") 多个字段的验证 权重 333
    def validate(self, attrs): print(33333) # attrs 字典有你传过来的全部的字段 >>>>OrderedDict([('title', 'python'), ('post_category', 2)])
        print(attrs) if "python" in attrs["title"].lower() or attrs["post_category"] == 1: return attrs else: raise serializers.ValidationError("分类或标题不合符要求") 自定义的验证 权重 111
def my_validate(value): print(111, value) if '敏感信息' in value.lower(): raise serializers.ValidationError('有敏感词汇') return value 配置: 给字段加validators=[my_validate] title = serializers.CharField(max_length=32,validators=[my_validate,]) 

ModelSerializer

如今咱们已经清楚了Serializer的用法,会发现咱们全部的序列化跟咱们的模型都紧密相关~

那么,DRF也给咱们提供了跟模型紧密相关的序列化器~~ModelSerializer~~

  -- 它会根据模型自动生成一组字段

  -- 它简单的默认实现了.update()以及.create()方法

一.定义一个ModelSerializer序列化器

class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = "__all__"
        # fields = ["id", "title", "pub_time"]
        # exclude = ["user"]
        # 分别是全部字段 包含某些字段 排除某些字段

外键关系的序列化

class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = "__all__"
        # fields = ["id", "title", "pub_time"]
        # exclude = ["user"]
        # 分别是全部字段 包含某些字段 排除某些字段
        depth = 1
# depth 表明找嵌套关系的第几层
 外键关系序列化

 

方法字段-- SerializerMethodField() 

def get_字段名称(self, obj): obj 每次序列化的模型对象 return 自定义的数据

 

class BookSerializer(serializers.ModelSerializer): # category_display = serializers.SerializerMethodField(read_only=True)
    # # publisher_info = serializers.SerializerMethodField(read_only=True)
    # # authors_info = serializers.SerializerMethodField(read_only=True)
    # def get_category_display(self,obj):
    # return obj.get_category_display()
    publisher_info = serializers.SerializerMethodField(read_only=True) category_info = serializers.SerializerMethodField(read_only=True) authors_info = serializers.SerializerMethodField(read_only=True) # category = serializers.SerializerMethodField()

    def get_publisher_info(self, obj): print(111, obj) publisher_obj = obj.publisher return {'id': publisher_obj.id, 'title': publisher_obj.title} def get_category_info(self, obj): return obj.get_category_display() def get_authors_info(self, obj): authors_querset = obj.authors.all() return [{"id": author.id, "name": author.name} for author in authors_querset]

Meta中其它关键字参数

class BookSerializer(serializers.ModelSerializer): chapter = serializers.CharField(source="get_chapter_display", read_only=True) class Meta: model = Book fields = "__all__"
        # fields = ["id", "title", "pub_time"]
        # exclude = ["user"]
        # 分别是全部字段 包含某些字段 排除某些字段
        depth = 1 read_only_fields = ["id"] extra_kwargs = {"title": {"validators": [my_validate,]}} Meta中参数
相关文章
相关标签/搜索