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中參數
相關文章
相關標籤/搜索