序列化
基本代碼結構
modles.py
1 from django.db import models 2 # Create your models here. 3 4 # Create your models here. 5 class UserGroup(models.Model): 6 title=models.CharField(max_length=32) 7 8 class UserInfo(models.Model): 9 user_type_choices=((1,'普通用戶'), 10 (2,"VIP"), 11 (3,"SVIP")) 12 user_type=models.IntegerField(choices=user_type_choices) 13 group= models.ForeignKey('UserGroup',on_delete=models.CASCADE,null=True) 14 roles=models.ManyToManyField('Role') 15 username=models.CharField(max_length=32,unique=True) 16 password=models.CharField(max_length=32) 17 18 class UserToken(models.Model): 19 user=models.OneToOneField(to='UserInfo',on_delete=models.CASCADE) 20 token=models.CharField(max_length=64) 21 22 class Role(models.Model): 23 title=models.CharField(max_length=32)
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
class UserinfoSerializer(ModelSerializer):
# user_type = serializers.CharField(source='get_user_type_display')
# role = serializers.SerializerMethodField()
#生成url
group=serializers.HyperlinkedIdentityField(view_name='gu',lookup_url_kwarg='xxx',lookup_field='group_id')
class Meta:
model=models.UserInfo
fields='__all__'
# fields=['id','username','user_type','role']
depth=1
# def get_role(self, row):
# roles=row.roles.all()
# dict=[]
# for item in roles:
# dict.append({'ID':item.id,"title":item.title})
# return dict
class TestView(APIView):
def get(self,request,*args,**kwargs):
#方法一
# roles=models.Role.objects.all().values('id','title')
# roles=list(roles)
# ret=json.dumps(roles,ensure_ascii=False)
#方法二
# roles=models.Role.objects.all()
# ser=RoleSerializer(instance=roles,many=True)
# ret = json.dumps(ser.data, ensure_ascii=False)
uesr=models.UserInfo.objects.all()
#生成url時,必須添加context參數
ser=UserinfoSerializer(instance=uesr,many=True,context={'request': request})
ret = json.dumps(ser.data, ensure_ascii=False)
return HttpResponse(ret)
源碼分析
1.實例化Serializer對象時,many參數的作用?
我們從實例化入手,大家知道在實例化時,首先執行的是__new__方法,然后返回對應的對象實例,所以我們一步步深入,在BaseSerializer類中找到了__new__方法。

根據判斷many參數的值,來確定我們需要返回的對象實例。
2.Serializer對象是如何序列化數據的?

從data方法入手,進入data方法,返回self._data,接着我們從最外層尋找to_repersertation方法。

3.如何反向生成url?
字段類型(HyperlinkedIdentityField)就是字段生成url,在上圖中,進行第一次to_represention方法是返回的是一個對象。

在HyperlinkedIdentityField類的to_represention最后調用的是django內置的生成url的方法reverse。
請求數據校驗
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
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')])
def validate_user (self,value):
print(value)
raise exceptions.ValidationError('拒絕你了!!!!')
class TestView(APIView):
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請求,響應內容')
源碼分析
1.實例化過程
將data賦值給initial_data

2.如果實現數據校驗?
ser.is_valid()方法的返回值肯定是個bool值,進一步進入內部,看如何實現校驗。


