rest-framework框架基本组件

一、快速实例

Quickstart

http://www.cnblogs.com/yuanchenqi/articles/8719520.html

二、序列化

1、准备模型和路由

from django.db import models
# Create your models here.


class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.IntegerField()
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE)
    authors = models.ManyToManyField("Author")

    def __str__(self):
        return self.title


class Publish(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    def __str__(self):
        return self.name
models.py

  urls.py:

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('publishes/', views.PublishView.as_view())
]

2、序列化方式一:将QuerySet对象转化为数组套字典

from django.shortcuts import render, HttpResponse
from django.views import View
from .models import Publish
import json

class PublishView(View):
    def get(self, request):
        # QuerySet对象不能进行json序列化
        # 方式1:values(*field):调用者是queryset对象,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
        #       再使用list()方法强转为列表,组成列表里面放字典的数据结构
        publish_list = list(Publish.objects.all().values("name", "email"))

        return HttpResponse(json.dumps(publish_list))

    def post(self, request):
        pass

  注意:

(1)values(*field):

  调用者是queryset对象,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列:

  <QuerySet [{'name': '橘子出版社', 'email': '[email protected]'}, {'name': '苹果出版社', 'email': '[email protected]'}]>

(2)list():

  将序列强行转化为数组:

  [{'name': '橘子出版社', 'email': '[email protected]'}, {'name': '苹果出版社', 'email': '[email protected]'}]

(3)json.dumps():

  json.dumps 用于将 Python 对象编码成 JSON 字符串。以下是python 原始类型向 json 类型的转化对照表:

  

3、序列化方式二:model_to_dict(obj)

(1)循环QuerySet构建可序列化数据结构

from django.views import View
from .models import Publish
import json

class PublishView(View):
    def get(self, request):
        # QuerySet对象不能进行json序列化
        # 方式2:
        publish_list = Publish.objects.all()
        temp = []
        for obj in publish_list:
            temp.append({
                "name": obj.name,
                "name": obj.email
            })
        print(temp)  # [{'name': '[email protected]'}, {'name': '[email protected]'}]

        return HttpResponse(json.dumps(temp))

    def post(self, request):
        pass

  这样写的问题是有多少字段就要加多少个字段,而且如果不知道是哪张表或者有哪些字段,就无法构建数据。

扫描二维码关注公众号,回复: 3004210 查看本文章

(2)引入model_to_dict完成改写

   model_to_dict是用于将model对象转换为字典的方法。

from django.views import View
from .models import Publish
import json

class PublishView(View):
    def get(self, request):
        # QuerySet对象不能进行json序列化
        # 方式2:
        from django.forms.models import model_to_dict
        publish_list = Publish.objects.all()
        temp = []
        for obj in publish_list:
            temp.append(model_to_dict(obj))
        print(temp)  # [{'name': '[email protected]'}, {'name': '[email protected]'}]

        return HttpResponse(json.dumps(temp))

(3)测试理解model_to_dict方法

  在pycharm的python console测试:

>>>from django.forms.models import model_to_dict
>>>from app01 import models
>>>print(models)
<module 'app01.models' from '/Users/hqs/PycharmProjects/restDemo/app01/models.py'>
>>>obj = models.Publish.objects.all()
>>>print(obj)
<QuerySet [<Publish: 橘子出版社>, <Publish: 苹果出版社>]>
>>>obj = models.Publish.objects.filter(pk=2).first()
>>>obj  # obj是一个model对象
<Publish: 橘子出版社>

>>>model_to_dict(obj)
{'id': 2, 'name': '橘子出版社', 'email': '[email protected]'}

  由此可见有几个字段就转化为几个键值对的字典。

4、序列化方式三:serializers.serizlize("json",publish_list)

  serializers是django的序列化组件。

from django.views import View
from .models import Publish
import json

class PublishView(View):
    def get(self, request):
        # QuerySet对象不能进行json序列化
        # 方式3:
        from django.core import serializers
        publish_list = Publish.objects.all()
        ret = serializers.serialize("json", publish_list)

        return HttpResponse(json.dumps(ret))

    def post(self, request):
        pass

  注意:

(1)__init__.py中serialize函数原型

def serialize(format, queryset, **options):
    """
    Serialize a queryset (or any iterator that returns database objects) using
    a certain serializer.
    """
    s = get_serializer(format)()
    s.serialize(queryset, **options)
    return s.getvalue()

  传递给 serialize 方法的参数有二:一个序列化目标格式,另外一个是序列化的对象QuerySet. (事实上,第二个参数可以是任何可迭代的Django Model实例,但它很多情况下就是一个QuerySet).

(2)序列化后数据组织形式

"[{\"model\": \"app01.publish\", \"pk\": 2, \"fields\": {\"name\": \"\\u6a58\\u5b50\\u51fa\\u7248\\u793e\", \"email\": \"[email protected]\"}}, {\"model\": \"app01.publish\", \"pk\": 3, \"fields\": {\"name\": \"\\u82f9\\u679c\\u51fa\\u7248\\u793e\", \"email\": \"[email protected]\"}}]"

5、序列化方式四:(推荐)rest_framework  serializers

from django.views import View
from .models import Publish
import json
from rest_framework import serializers

class PublishSerializers(serializers.Serializer):
    """为QuerySet做序列化"""
    name = serializers.CharField()
    email = serializers.CharField()

class PublishView(View):
    def get(self, request):
        # 方式4:
        publish_list = Publish.objects.all()
        ret = PublishSerializers(publish_list, many=True)  # 描述是model对象还是QuerySet  True:queryset
        return HttpResponse(json.dumps(ret))

    def post(self, request):
        pass

  注意:

(1)分析继承了Serializers的子类PublishSerializers

>>>from app01.views import PublishSerializers
>>>publish_list = models.Publish.objects.all()
>>>PublishSerializers(publish_list, many=True)   # 描述是model对象还是QuerySet
PublishSerializers(<QuerySet [<Publish: 橘子出版社>, <Publish: 苹果出版社>]>, many=True):
    name = CharField()
    email = CharField()
>>>ps = PublishSerializers(publish_list, many=True)
>>>ps.data
[OrderedDict([('name', '橘子出版社'), ('email', '[email protected]')]), OrderedDict([('name', '苹果出版社'), ('email', '[email protected]')])]

(2)Serializer是对QuerySet和model对象做序列化的

  在序列化时,第一个参数传递要序列化的对象,第二个参数many是向组件声明到底是model对象还是QuerySet。

  many=True:QuerySet      many=False:model对象

三、rest_framework(APIView)

猜你喜欢

转载自www.cnblogs.com/xiugeng/p/9572089.html