django restframework框架五 序列化

@(python之路)[django restframework框架五 序列化]
django restframework框架五 序列化

简介

 当我们做前后端分离得时候,我们需要把后端的时间传递给前端,这是就需要Json格式。当然也不否认有其它得格式,例如:xml。但是现在较为普遍得是Json。

序列化组件

我们首先建表,然后通过查询模拟发送数据给前端。
models.py

class Sa(models.Model):
    name = models.CharField(max_length=32)

class Host(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField(default=80)

    host_types = (
        (1,'web'),
        (2,'存储'),
    )
    htype = models.IntegerField(choices=host_types,default=1)

    sa = models.ForeignKey('Sa')
    departs = models.ManyToManyField('Depart')

class Depart(models.Model):
    title = models.CharField(max_length=32)

views.py

from rest_framework import serializers
from  rest_framework.response import Response



class HostSerializer(serializers.Serializer):
    hostname = serializers.CharField()
    port = serializers.IntegerField()
    sa_id = serializers.CharField(source='sa.id')
    sa_name = serializers.CharField(source='sa.name')
    htype_id = serializers.CharField(source='htype')
    htype_title = serializers.CharField(source='get_htype_display')

    
    # 这里执行SerializerMethodField,他就会调用get_%s并执行。根据源码分析。
    departs = serializers.SerializerMethodField()

    def get_departs(self,obj):         # obj就是当前数据行的对象
        return [{'id':row.id,'title':row.title} for row in obj.departs.all()]


class HostView(APIView):
    authentication_classes = []

    def get(self,request,*args,**kwargs):

        ret = {'code':2001}
        try:
            queryset = models.Host.objects.all()
            ser = HostSerializer(instance=queryset,many=True)    # many只有一个对象用False,如果是queryset多个对象就要many=True
            ret['data'] = ser.data
        except Exception as e:
            ret['code'] = 2002
            ret['msg'] = '获取数据失败'
        return Response(ret)

部分截图

第二版本

models.py

class Sa(models.Model):
    name = models.CharField(max_length=32)

class Host(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField(default=80)

    host_types = (
        (1,'web'),
        (2,'存储'),
    )
    htype = models.IntegerField(choices=host_types,default=1)

    sa = models.ForeignKey('Sa')
    departs = models.ManyToManyField('Depart')

class Depart(models.Model):
    title = models.CharField(max_length=32)

views.py

class NewSerializer(serializers.ModelSerializer):
    htype_title = serializers.CharField(source="get_htype_display")
    departs = serializers.SerializerMethodField()
    class Meta:
        model = models.Host
        # fields = '__all__'
        fields = ['hostname','port','htype','htype_title','sa','departs',"departs"]
        depth = 1
    def get_departs(self,obj):
        return [ {"id":row.id,"title":row.title} for row in obj.departs.all()]

class HostView(APIView):
    authentication_classes = []

    def get(self,request,*args,**kwargs):

        ret = {'code':2001}
        try:
            queryset = models.Host.objects.all()
            ser = NewSerializer(instance=queryset,many=True)
            ret['data'] = ser.data
        except Exception as e:
            ret['code'] = 2002
            ret['msg'] = '获取数据失败'
        return Response(ret)

序列化与认证

 序列化用于对用户请求数据进行验证和数据进行序列化。
自定义字段

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from .. import models


class PasswordValidator(object):
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        if value != self.base:
            message = 'This field must be %s.' % self.base
            raise serializers.ValidationError(message)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass


class UserSerializer(serializers.Serializer):
    ut_title = serializers.CharField(source='ut.title')
    user = serializers.CharField(min_length=6)
    pwd = serializers.CharField(error_messages={'required': '密码不能为空'}, validators=[PasswordValidator('666')])


class TestView(APIView):
    def get(self, request, *args, **kwargs):

        # 序列化,将数据库查询字段序列化为字典
        data_list = models.UserInfo.objects.all()
        ser = UserSerializer(instance=data_list, many=True)
        # 或
        # obj = models.UserInfo.objects.all().first()
        # ser = UserSerializer(instance=obj, many=False)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        # 验证,对请求发来的数据进行验证
        ser = UserSerializer(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
        else:
            print(ser.errors)

        return Response('POST请求,响应内容')

views.py

基于Model自动生成字段

urls.py

from django.conf.urls import url, include
from web.views.s6_serializers import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
]

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from .. import models


class PasswordValidator(object):
    def __init__(self, base):
        self.base = str(base)

    def __call__(self, value):
        if value != self.base:
            message = 'This field must be %s.' % self.base
            raise serializers.ValidationError(message)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass

class ModelUserSerializer(serializers.ModelSerializer):

    user = serializers.CharField(max_length=32)

    class Meta:
        model = models.UserInfo
        fields = "__all__"
        # fields = ['user', 'pwd', 'ut']
        depth = 2
        extra_kwargs = {'user': {'min_length': 6}, 'pwd': {'validators': [PasswordValidator(666), ]}}
        # read_only_fields = ['user']


class TestView(APIView):
    def get(self, request, *args, **kwargs):

        # 序列化,将数据库查询字段序列化为字典
        data_list = models.UserInfo.objects.all()
        ser = ModelUserSerializer(instance=data_list, many=True)
        # 或
        # obj = models.UserInfo.objects.all().first()
        # ser = UserSerializer(instance=obj, many=False)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        # 验证,对请求发来的数据进行验证
        print(request.data)
        ser = ModelUserSerializer(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
        else:
            print(ser.errors)

        return Response('POST请求,响应内容')


生成URL

urls.py

from django.conf.urls import url, include
from web.views.s6_serializers import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
    url(r'detail/(?P<pk>\d+)/', TestView.as_view(), name='detail'),
]

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from .. import models


class PasswordValidator(object):
    def __init__(self, base):
        self.base = str(base)

    def __call__(self, value):
        if value != self.base:
            message = 'This field must be %s.' % self.base
            raise serializers.ValidationError(message)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass


class ModelUserSerializer(serializers.ModelSerializer):
    ut = serializers.HyperlinkedIdentityField(view_name='detail')
    class Meta:
        model = models.UserInfo
        fields = "__all__"

        extra_kwargs = {
            'user': {'min_length': 6},
            'pwd': {'validators': [PasswordValidator(666),]},
        }



class TestView(APIView):
    def get(self, request, *args, **kwargs):

        # 序列化,将数据库查询字段序列化为字典
        data_list = models.UserInfo.objects.all()
        ser = ModelUserSerializer(instance=data_list, many=True, context={'request': request})
        # 或
        # obj = models.UserInfo.objects.all().first()
        # ser = UserSerializer(instance=obj, many=False)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        # 验证,对请求发来的数据进行验证
        print(request.data)
        ser = ModelUserSerializer(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
        else:
            print(ser.errors)

        return Response('POST请求,响应内容')

自动生成URL

urls.py

from django.conf.urls import url, include
from web.views.s6_serializers import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
    url(r'detail/(?P<pk>\d+)/', TestView.as_view(), name='xxxx'),
]

views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from .. import models


class PasswordValidator(object):
    def __init__(self, base):
        self.base = str(base)

    def __call__(self, value):
        if value != self.base:
            message = 'This field must be %s.' % self.base
            raise serializers.ValidationError(message)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass


class ModelUserSerializer(serializers.HyperlinkedModelSerializer):
    ll = serializers.HyperlinkedIdentityField(view_name='xxxx')
    tt = serializers.CharField(required=False)

    class Meta:
        model = models.UserInfo
        fields = "__all__"
        list_serializer_class = serializers.ListSerializer

        extra_kwargs = {
            'user': {'min_length': 6},
            'pwd': {'validators': [PasswordValidator(666), ]},
            'url': {'view_name': 'xxxx'},
            'ut': {'view_name': 'xxxx'},
        }


class TestView(APIView):
    def get(self, request, *args, **kwargs):
        # # 序列化,将数据库查询字段序列化为字典
        data_list = models.UserInfo.objects.all()
        ser = ModelUserSerializer(instance=data_list, many=True, context={'request': request})
        # # 如果Many=True
        # # 或
        # # obj = models.UserInfo.objects.all().first()
        # # ser = UserSerializer(instance=obj, many=False)
        return Response(ser.data)

    def post(self, request, *args, **kwargs):
        # 验证,对请求发来的数据进行验证
        print(request.data)
        ser = ModelUserSerializer(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
        else:
            print(ser.errors)

        return Response('POST请求,响应内容')
posted @ 2019-03-15 16:10  zz小公子  阅读(145)  评论(0编辑  收藏  举报