Django序列化与DRF序列化的对比 | DRF

方式一:

list()函数配合ORM中values()实现的序列化;

复制代码

>>> from cloud.models import *
>>> user_list = list(UserInfo.objects.filter(id__lte=4).values())
>>> user_list
[{'user_id': 1, 'state': '1', 'tell': '021-61521590', 'id': 1, 'type': '1', 'forgetpassword': None, 'phone': '15325099160', 'pnode_id': None, 'company': 'xxxx', 'userGUID': '0d0b5761-b3ad-11e6-a321-b888e3f1fb60', 'fullname': 'xxxx'}, {'user_id': 2, 'state': '1', 'tell': '110', 'id': 2, 'type': '1', 'forgetpassword': None, 'phone': '11111111111', 'pnode_id': None, 'company': 'xxxxx', 'userGUID': '2d90ec8f-b6e4-11e6-88e4-b888e3f1fb60', 'fullname': 'xxxxx'}, {'user_id': 3, 'state': '0', 'tell': '1', 'id': 3, 'type': '2', 'forgetpassword': None, 'phone': '11111111111', 'pnode_id': 2, 'company': '1', 'userGUID': '6e3fea21-b6e4-11e6-abe8-b888e3f1fb60', 'fullname': 'xxxx'}, {'user_id': 4, 'state': '1', 'tell': '123', 'id': 4, 'type': '1', 'forgetpassword': None, 'phone': '11111111111', 'pnode_id': None, 'company': '123456', 'userGUID': '0cda1fcf-bc61-11e6-9beb-005056a37549', 'fullname': 'wenxy'}]

复制代码

 

方式二:

将对象中的字段信息一个个取出来,赋值到字典中,再添加到列表中;

 

方式三:

model_to_dict()

复制代码

>>> from django.forms.models import model_to_dict
>>> users = UserInfo.objects.filter(id__lte=2)
>>> data = []
>>> for user in users:
...     data.append(model_to_dict(user))
...
>>> data
[{'state': '1', 'client_host': [], 'type': '1', 'user': 1, 'phone': '15325099160', 'group': [], 'tell': '021-61521590', 'userGUID': '0d0b5761-b3ad-11e6-a321-b888e3f1fb60', 'pnode': None, 'id': 1, 'forgetpassword': None, 'company': 'xxxxx', 'fullname': 'xxxxx'}, {'state': '1', 'client_host': [], 'type': '1', 'user': 2, 'phone': '11111111111', 'group': [3], 'tell': '110', 'userGUID': '2d90ec8f-b6e4-11e6-88e4-b888e3f1fb60', 'pnode': None, 'id': 2, 'forgetpassword': None, 'company': 'xxxxx', 'fullname': 'xxxxxx'}]

复制代码

 

 

方式四:

django中的serializers;

复制代码

>>> from cloud.models import *
>>> from django.core import serializers
>>> jobs = Joblist.objects.filter(id__lte=1)
>>> data = serializers.serialize("json", jobs)
>>> data
'[{"model": "cloud.joblist", "pk": 1, "fields": {"jobid": 796, "appid": 4, "jobinitfrom": "Schedule", "clientname": "test1", "idataagent": "Windows File System", "instance": "DefaultInstanceName", "backupset": "defaultBackupSet", "subclient": "DDBBackup", "data_sp": "SP-7DAYS", "backuplevelInt": 1, "backuplevel": "Full", "incrlevel": 0, "jobstatusInt": 1, "jobstatus": "Success", "jobfailedreason": "", "transferTime": 105, "startdateunixsec": 1489104014, "enddateunixsec": 1489104152, "startdate": "2017-03-10T00:00:14Z", "enddate": "2017-03-10T00:02:32Z", "durationunixsec": 125, "duration": "2 m 5 s", "numstreams": 1, "numbytesuncomp": 344713940, "numbytescomp": 90163679, "numobjects": 208, "isAged": 1, "isAgedStr": "Yes", "xmlJobOptions": null, "retentionDays": "7", "systemStateBackup": 0, "inPrimaryCopy": 1, "failedobjects": 0, "totalBackupSize": 91095646, "encrypted": "No", "diskcapacity": 91112542, "result": ""}}]'

复制代码

 

方式五:

django rest framework提供的序列化操作;

 

复制代码

# Restful协议
"""
一切皆是资源,操作只是请求方式:
    GET
    POST
    PUT
    DELETE
针对数据:
    JSON
"""


class Example(View):
    """
    所有数据的操作
    """
    def get(self, request):
        pass

    def post(self, request):
        pass


class ExampleDetail(View):
    """
    指定数据操作
    """
    def get(self, rquest, id):
        pass

    def put(self, request, id):
        pass

    def post(self, request, id):
        pass
    
    def delete(self, request, id):
        pass

复制代码

 


复制代码

"""
一.序列化
"""

# models.py
from django.db import models


class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish")
    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


# urls.py
urlpatterns = [
    (url("/publish/", views.PublishView.as_view())),  # view(request) ==> APIView>dispatch()
]


# views.py
# django rest framework中的request对象与原生django的request对象不同:
#   1.已经做好了反序列化操作,将json转换成dict,表单数据转化成Queryset;
#   2.原生的request对象就是request._request;
from .models import *
from django.shortcuts import HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response

from rest_framework import serializers


class BookSerializers(serializers.Serializer):
    """
    可以将serializers单独创建文件,再引入视图
    """
    # 1.常规字段
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    pub_date = serializers.DateField()
    publish = serializers.CharField(source="publish.name")  # 外键 str(obj.publish)-->obj.publish.name
    # 2.一对多外键字段
    # publish = serializers.CharField()  # 如果不传入source参数,默认使用publish的__str__(self)方法下的字段;

    # 3.多对多外键字段
    # authors = serializers.CharField(source="authors.all")  # 查出来的是Queryset,不好使;
    authors = serializers.SerializerMethodField()  # SerializerMethodField为多对多服务的字段;
    def get_authors(self,obj):    # --> get_authors(obj)
        temp = []
        for author in obj.authors.all():
            temp.append(author.name)
        return temp


class BookViewSet(APIView):
    def get(self, request, *args, **kwargs):
        book_list=Book.objects.all()
        bs=BookSerializers(book_list, many=True)  # many=True 表示序列化的是一个QuerySet;其还可以序列化 model对象

        # return HttpResponse(bs.data)
        return Response(bs.data)  # 构造新的结构与页面  ?format=json获取真实json数据;

复制代码

 


复制代码

"""
ModelSerializers
"""
class BookModelSerializers(serializers.ModelSerializer):
    """
    自动转化成Serializers,外键是值的列表,如果自己添加外键,就显示自定义的
    """
    class Meta:
        model=Book
        fields="__all__"
        depth=1

    # 如果自己添加外键,就显示自定义的
    publish = serializers.CharField(source="publish.name")  # 外键 str(obj.publish)-->obj.publish.name
    authors = serializers.SerializerMethodField()  # SerializerMethodField为多对多服务的字段;
    def get_authors(self,obj):    # --> get_authors(obj)
        temp = []
        for author in obj.authors.all():
            temp.append(author.name)
        return temp

    def create(self, validated_data):
        """
        针对自定义而重构的create()方法
        """
        authors = validated_data.pop('authors')
        obj = Book.objects.create(**validated_data)
        obj.authors.add(*authors)
        return obj
 

class BookViewSet(APIView):
    def get(self, request, *args, **kwargs):
        """
        返回当前所有数据
        """
        book_list=Book.objects.all()
        bs=BookModelSerializers(book_list, many=True)

        # return HttpResponse(bs.data)
        return Response(bs.data)  # 构造新的结构与页面  ?format=json获取真实json数据;

  def post(self,request,*args,**kwargs):
        """
        返回提交数据
        """
        bs=BookModelSerializers(data=request.data, many=False)  
        if bs.is_valid():  # 如果是按照规定CharField()等格式来的,验证数据后保存至数据库
            # print(bs.validated_data)  # 验证成功数据
            bs.save()  
            """
            注:这里的save()方法是调用BookModelSerializers类中的,其中self.create()方法不支持source="publish.name"参数的使用,会报错;

            """
            return Response(bs.data)
        else:
            return HttpResponse(bs.errors)  # 验证错误信息

复制代码

 


复制代码

"""
单条数据的操作
"""

# urls.py
urlpatterns = [
    (url("/books/(\d+)", views.BookDetailView.as_view())),  # view(request) ==> APIView>dispatch()
]

# views.py
class BookDetailViewSet(APIView):
    def get(self,request,pk):
        """
        获取单条数据
        """
        book_obj=Book.objects.filter(pk=pk).first()
        bs=BookSerializers(book_obj)
        return Response(bs.data)

    def put(self,request,pk):
        """
        更新操作
        """
        book_obj=Book.objects.filter(pk=pk).first()
        bs=BookSerializers(book_obj,data=request.data)
        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:
            return HttpResponse(bs.errors)

复制代码

 


 

复制代码

"""
超链接:点击外键跳转具体表数据;
"""
# serializers.py
class BookModelSerializers(serializers.ModelSerializer):
    # 自定义外键字段
    publish= serializers.HyperlinkedIdentityField(
                    view_name='publish_detail',  # url中的别名
                    lookup_field="publish_id",  # 指定当前对象字段
                    lookup_url_kwarg="pk")  # 传入参数别名
    class Meta:
        model=Book
        fields="__all__"
        #depth=1

# urls.py
urlpatterns = [
    (url("/publish/(?P\d+)", views.BookDetailView.as_view(), name="publish_detail")),  # view(request) ==> APIView>dispatch()
]

# views.py
class BookViewSet(APIView):
    """
    注意:在使用HyperlinkedIdentityField字段时,BookModelSerializers序列化时需要添加参数:context={"request": request}
    """
    def get(self, request, *args, **kwargs):
        """
        返回当前所有数据
        """
        book_list=Book.objects.all()
        bs=BookModelSerializers(book_list, many=True, context={"request": request})

        return Response(bs.data)  # 构造新的结构与页面  ?format=json获取真实json数据;

  def post(self,request,*args,**kwargs):
        """
        返回提交数据
        """
        bs=BookModelSerializers(data=request.data, many=False, context={"request": request})  
        if bs.is_valid():  # 如果是按照规定CharField()等格式来的,验证数据后保存至数据库
            # print(bs.validated_data)  # 验证成功数据
            bs.save()  
            return Response(bs.data)
        else:
            return HttpResponse(bs.errors)  # 验证错误信息

复制代码

 

 

记录自己的学习历程!

出处:http://www.cnblogs.com/pymkl/articles/9308616.html

参考:https://blog.csdn.net/aransam/article/details/80929460

https://blog.csdn.net/u012993796/article/details/80767102

https://blog.csdn.net/Ch_zhenhua/article/details/81198226

你可能感兴趣的:(python,django)