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请求,响应内容')