zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    保持URL不变和数字验证
    centOS ftp key?
    本地环境测试二级域名
    linux 解决You don't have permission to access 问题
    php smarty section loop
    php header Cannot modify header information headers already sent by ... 解决办法
    linux部分命令
    Linux 里面的文件操作权限说明
    用IT网络和安全专业人士视角来裁剪云的定义
    SQL Server 2008 R2炫酷报表"智"作有方
  • 原文地址:https://www.cnblogs.com/yangzhizong/p/9788723.html
Copyright © 2011-2022 走看看