• RESTful-rest_framework应用第二篇(get、post的序列化与反序列化)


    目的是:

      利用rest_framework实现对数据库内容的查看get请求(序列化)、提交保存数据post请求 (反序列化)

    rest_framework序列化组件(即查看和)

    第一步:基于Django搭建RESTful框架

    第二步:配置信息

     settings.py配置

    settings里面全局解析器:

    1 #设置解析器(对发送过来的数据信息格式进项校验并做进一步处理)
    2 #全局可以配好多个,局部配一个就行(先走局部的)
    3 REST_FRAMEWORK = {
    4     'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser']
    5 }

    views.py局部解析器:

     1 #JSONParser,FormParser局部解析器,一般只需要写一个就行
     2 from rest_framework.parsers import JSONParser,FormParser
     3 class Book(APIView):
     4 
     5     #解析器:对浏览器发送post请求过来的数据类型做解析
     6     #当指向下面post请求,运行request.data的时候才会去执行解析器
     7     parser_classes = [JSONParser,FormParser]
     8 
     9     def get(self,request):                 #request是已经处理好的request
    10 
    11         ret = models.Book.objects.all()
    12         print(ret,type(ret)) #ret是QuerySet对象  <class 'django.db.models.query.QuerySet'>
    13 
    14         # 实例化上面的BookSerializer拿到一个book_ser对象
    15         # BookSerializer参数(ret:queryset对象,many=True代表序列化多条,many=False 代表序列化一条)
    16         book_ser=BookSerializer(ret,many=True)
    17         #book_ser.data不是json格式的字符串,而是个字典
    18         #所以Response内部一定是对book_ser.data做了序列化
    19         return Response(book_ser.data)
    20 
    21 
    22     def post(self,request):
    23         print('111')
    24         print(request.data)
    25         return HttpResponse('ok')
    26 
    27         # 杂乱内容整理:
    28         # print(request.POST)
    29         #对请求过来的数据进项验证,检验每个字段是否符合录入要求,并保存
    30         ser = BookSerializer(data=request.data)
    31 
    32         #post请求过来数据符合每个字段要求,就允许写入数据库
    33         if ser.is_valid():
    34             ser.save()
    35             return Response(ser.save())
    36 
    37         #不符合要求就返回错误信息
    38         else:
    39             print(ser.errors)
    40 
    41 
    42             return HttpResponse(json.dumps(ser.errors))

    models.py里面的设置:

     1 from django.db import models
     2 
     3 # Create your models here.
     4 
     5 from django.db import models
     6 
     7 class Book(models.Model):
     8     title=models.CharField(max_length=32)
     9     price=models.IntegerField()
    10     pub_date=models.DateField()
    11     publish=models.ForeignKey("Publish")
    12     authors=models.ManyToManyField("Author")
    13 
    14     def __str__(self):
    15         return self.title
    16 
    17     #我了验证可以覆盖重写字段的方法
    18     def test(self):
    19         return '555'
    20 
    21 
    22 class Publish(models.Model):
    23     name=models.CharField(max_length=32)
    24     email=models.EmailField()
    25     # def __str__(self):
    26     #     return self.name
    27 
    28 class Author(models.Model):
    29     name=models.CharField(max_length=32)
    30     age=models.IntegerField()
    31     def __str__(self):
    32         return self.name

    views.py配置:

      1 from django.shortcuts import render,HttpResponse,redirect
      2 import json
      3 from api import models
      4 # Create your views here.
      5 
      6 # from api.models import Book
      7 
      8 from rest_framework.views import  APIView
      9 from rest_framework import serializers
     10 from rest_framework.response import Response
     11 
     12 from rest_framework.serializers import SerializerMethodField
     13 
     14 #为了验证方式三
     15 class AuthorsSerializer(serializers.Serializer):
     16     id = serializers.CharField()
     17     name = serializers.CharField()
     18     age = serializers.CharField()
     19 
     20 class PublishSerializer(serializers.Serializer):
     21    id = serializers.CharField()
     22    name = serializers.CharField()
     23    email = serializers.CharField()
     24 
     25 #RESful提供的一个序列化组件BookSerializer,可以控制传入的参数
     26 class BookSerializer(serializers.Serializer):
     27     #指定字段重命名,例如:将title重命名为xx
     28     xx = serializers.CharField(source='title')
     29     #添加新字段:只要models里面指定一个test方法,就会执行并显示一条新的字段
     30     qqq=serializers.CharField(source='test')
     31 
     32     title=serializers.CharField()
     33     price=serializers.CharField()
     34     pub_date=serializers.DateField()
     35     #publish是个object对象,所以可以.name查看里面的内容
     36     publish=serializers.CharField(source="publish.name")
     37 
     38     #查询所有作者:
     39     #方式一:
     40     authors=serializers.CharField(source="authors.all")
     41 
     42 
     43     #方式二:for循环拿到作者对象
     44     authors=serializers.SerializerMethodField()
     45     def get_authors(self,obj):
     46         ll=[]
     47         for author in obj.authors.all():
     48             print(author)
     49             ll.append({'name':author.name,'age':author.age})
     50         return ll
     51 
     52     #方式三:将作者实例化
     53     authors=serializers.SerializerMethodField()
     54     def get_authors(self,obj):
     55         ret_authors = obj.authors.all()
     56 
     57         ser=AuthorsSerializer(ret_authors,many=True)
     58         return ser.data
     59 
     60 
     61 #方式四:
     62 class BookSerializer(serializers.ModelSerializer):
     63     class Meta:
     64         #第一步:先拿到所有字段
     65         model = models.Book
     66         #__all__要去所有字段
     67         fields = '__all__'
     68         # 指定显示要取的字段 (注意指定和去除不能同时用)
     69         # fields=('id','title')
     70         # 去除某个或某几个字段不显示
     71         # exclude=('id','publish')
     72 
     73     # 重新tiltle字段,进行重命名
     74     # xx = serializers.CharField(source='title')
     75 
     76     #第二步:查看书对应的所有作者,(再重写authors字段,让其所以作者信息,而不只是显示序列号)
     77     authors=serializers.SerializerMethodField()
     78     def get_authors(self,obj):
     79         ret_authors = obj.authors.all()
     80         # print(ret_authors,type(ret_authors))
     81 
     82         ser=AuthorsSerializer(ret_authors,many=True)
     83         return ser.data
     84 
     85     #同理,查看书对应的的出版社
     86     publish=serializers.SerializerMethodField()
     87     def get_publish(self,obj):
     88         ret_publish= obj.publish
     89         print(ret_publish,type(ret_publish))   #Publish object
     90         ser = PublishSerializer(ret_publish,many=False)
     91         print(ser.data)
     92         return ser.data
     93 
     94 
     95 
     96     #设置title字段为必填字段,并设计中文提示信息
     97     title = serializers.CharField(error_messages={'required':'标题为必填字段'})
     98 
     99 
    100 #字段校验和反序列化:
    101 
    102     #局部钩子:用来校验1个字段
    103     def validate_title(self,value):
    104         from rest_framework.exceptions import ValidationError
    105         print(value)
    106         # raise ValidationError('就是看你不爽')
    107         return value
    108 
    109     #全局钩子:多个字段间对比检验
    110     def validate(self,attrs):
    111         from rest_framework.exceptions import ValidationError
    112         if attrs.get('title') == attrs.get('price'):
    113             return attrs
    114         else:
    115             raise ValidationError('书名和价格不一样')
    116 
    117 
    118 
    119 
    120 class Book(APIView):
    121     def get(self,request):
    122         ret = models.Book.objects.all()
    123         # BookSerializer可以获取请求的数据
    124         book_ser = BookSerializer(ret,many=True)
    125         print(book_ser.data)
    126         return Response(book_ser.data)
    127     #post请求,及实现保存数据
    128     def post(self,request):
    129         # BookSerializer也可以保存数据信息到数据库
    130         ser=BookSerializer(data=request.data)
    131         if ser.is_valid():
    132             ser.save()
    133             return HttpResponse('提交的post请求数据符合要求,已成功录入后台')
    134 
    135         else:
    136             print(ser.errors)
    137             # return Response(ser.errors)
    138             return HttpResponse(json.dumps(ser.errors))
    139 
    140 
    141 
    142 
    143 
    144 
    145 #RESTfu自带的处理请求的模块方法
    146 #JSONParser,FormParser局部解析器,一般只需要写一个就行
    147 from rest_framework.parsers import JSONParser,FormParser
    148 class Book(APIView):
    149 
    150     #解析器:对浏览器发送post请求过来的数据类型做解析
    151     #当指向下面post请求,运行request.data的时候才会去执行解析器
    152     parser_classes = [JSONParser,FormParser]
    153 
    154     def get(self,request):                 #request是已经处理好的request
    155 
    156         ret = models.Book.objects.all()
    157         print(ret,type(ret)) #ret是QuerySet对象  <class 'django.db.models.query.QuerySet'>
    158 
    159         # 实例化上面的BookSerializer拿到一个book_ser对象
    160         # BookSerializer参数(ret:queryset对象,many=True代表序列化多条,many=False 代表序列化一条)
    161         book_ser=BookSerializer(ret,many=True)
    162         #book_ser.data不是json格式的字符串,而是个字典
    163         #所以Response内部一定是对book_ser.data做了序列化
    164         return Response(book_ser.data)
    165 
    166 
    167     def post(self,request):
    168         print('111')
    169         print(request.data)
    170         return HttpResponse('ok')
    171 
    172         # 杂乱内容整理:
    173         # print(request.POST)
    174         #对请求过来的数据进项验证,检验每个字段是否符合录入要求,并保存
    175         ser = BookSerializer(data=request.data)
    176 
    177         #post请求过来数据符合每个字段要求,就允许写入数据库
    178         if ser.is_valid():
    179             ser.save()
    180             return Response(ser.save())
    181 
    182         #不符合要求就返回错误信息
    183         else:
    184             print(ser.errors)
    185 
    186 
    187             return HttpResponse(json.dumps(ser.errors))

    知识点分解,如下:

    rest-framework序列化之ModelSerializer

     1 class BookSerializer(serializers.ModelSerializer):
     2     class Meta:
     3         #第一步:先拿到所有字段
     4         model = models.Book
     5         #__all__要去所有字段
     6         fields = '__all__'
     7         # 指定显示要取的字段 (注意指定和去除不能同时用)
     8         # fields=('id','title')
     9         # 去除某个或某几个字段不显示
    10         # exclude=('id','publish')
    11         
    12         #下面这个方法不建议使用(因为不是字段都是要展示给客户看的,还是要使用下面那个方法,可以指定显示哪些字段)
    13         # depth = 1 #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层
    14 
    15     # 重新tiltle字段,进行重命名
    16     # xx = serializers.CharField(source='title')
    17 
    18     #第二步:查看书对应的所有作者,(再重写authors字段,让其所以作者信息,而不只是显示序列号)
    19     authors=serializers.SerializerMethodField()
    20     def get_authors(self,obj):             #obj是一个book对象
    21         ret_authors = obj.authors.all()
    22         # print(ret_authors,type(ret_authors))
    23 
    24         ser=AuthorsSerializer(ret_authors,many=True)
    25         return ser.data
    26 
    27     #同理,查看书对应的的出版社
    28     publish=serializers.SerializerMethodField()
    29     def get_publish(self,obj):
    30         ret_publish= obj.publish
    31         print(ret_publish,type(ret_publish))   #Publish object
    32         ser = PublishSerializer(ret_publish,many=False)
    33         print(ser.data)
    34         return ser.data
  • 相关阅读:
    动态采样
    Java Mail无法解析带分号的收件人列表的问题
    git 使用详解(5) get log 查看提交历史
    git 使用详解(6) 撤消操作
    修改 android的 开机 音乐
    修改 android的 开机 音乐
    关于ubuntu的aptget 包
    ubuntu 10.04 常用 设置
    Android4.0.3 修改 启动 动画
    git 使用详解(5) get log 查看提交历史
  • 原文地址:https://www.cnblogs.com/yangzhizong/p/9788723.html
Copyright © 2020-2023  润新知