models部分python
from django.db import models # Create your models here. class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateField(null=True) xx=models.IntegerField(choices=((0,'文學類'),(1,'情感類')),default=1,null=True) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True) authors=models.ManyToManyField(to='Author') def __str__(self): return self.name def test(self): return 'xxx' class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name
在app01下新建一個py文件,這裏命名爲app01serilaizergit
app01serializer部分django
from app01 import models from rest_framework import serializers class AuthorSerializer(serializers.Serializer): name=serializers.CharField() age=serializers.CharField() class BookSerializer(serializers.Serializer): #指定source='name' ,表示序列化模型表中的name字段,重名命爲name5(name和source='name'指定的name不能重名) name5=serializers.CharField(source='name') # #write_only 序列化的時候,該字段不顯示 # #read_only 反序列化的時候,該字段不傳 price=serializers.CharField(write_only=True) # #若是要取 出版社的city source='publish.city' publish=serializers.CharField(source='publish.name') # #source不但能夠指定一個字段,還能夠指定一個方法 book_type = serializers.CharField(source='get_xx_display',read_only=True) # #序列化出版社的詳情,指定SerializerMethodField以後,能夠對應一個方法,返回什麼內容,publish_detail就是什麼內容 publish_detail=serializers.SerializerMethodField(read_only=True) #對應的方法固定寫法get_字段名 def get_publish_detail(self,obj): # print(type(obj)) return {'name':obj.publish.name,'city':obj.publish.city} #拓展性差 #返回全部做者信息 authors=serializers.SerializerMethodField(read_only=True) def get_authors(self,obj): # return [ {'name':author.name,'age':author.age} for author in obj.authors.all()] authorser=AuthorSerializer(obj.authors.all(),many=True) #拓展性強 return authorser.data def create(self, validated_data): ret=models.Book.objects.create(**validated_data) return ret
views部分json
from app01.app01serializer import BookSerializer class Books(APIView): def get(self,request): response={'code':100,'msg':'查詢成功'} books=models.Book.objects.all() #若是序列化多條,many=True(也就是queryset對象,就須要寫) #若是序列化一條(能夠不寫),instance是要序列化的對象 bookser=BookSerializer(instance=books,many=True) # print(type(bookser.data)) # bookser.data response['data']=bookser.data return Response(response)
models部分不變app
views部分源碼分析
def post(self,request): #實例化產生一個序列化類的對象,data是要反序列化的字典 # print(request.data) bookser=BookSerializer(data=request.data) if bookser.is_valid(): #清洗經過的數據,能夠加限制好比最大長度之類的 ret=bookser.create(bookser.validated_data) #重寫create方法,更新的話用update return Response()
app01serializers部分post
from rest_framework import serializers from rest_framework import exceptions from app01 import models class BookSerializer(serializers.ModelSerializer): class Meta: model=models.Book # fields=('nid','name') #不能跟fields同時使用 # exclude=['name',] fields=('__all__') #深度是1,官方建議不要超過10,我的建議不要超過3 # depth=1 # xx=serializers.CharField(source='get_xx_display') #在外面重寫字段(取中文) # authors=serializers.SerializerMethodField() # def get_authors(self,obj): # ret=AuthorSerializer(instance=obj.authors.all(),many=True) # return ret.data # name=serializers.CharField() #反序列化的校驗(局部校驗,全局校驗) def validate_name(self,value): print(value) raise exceptions.ValidationError('不能以sb開頭') # if value.startswith('sb'): # raise ValidationError('不能以sb開頭') # return value def validate(self,attrs): print(attrs) # if attrs.get('price')!=attrs.get('xx'): # raise exceptions.ValidationError('name和price相等,不正常') return attrs
views部分rest
def get(self,request): response={'code':100,'msg':'查詢成功'} books=models.Book.objects.all() #瞭解 # ret = serializers.serialize("json", books) #若是序列化多條,many=True(也就是queryset對象,就須要寫) #若是序列化一條(能夠不寫),instance是要序列化的對象 bookser=BookSerializer(instance=books,many=True) # print(type(bookser.data)) # bookser.data response['data']=bookser.data return Response(response)
反序列化code
views部分對象
#使用繼承了ModelSerializers序列化類的對象,反序列化 def post(self,request): #實例化產生一個序列化類的對象,data是要反序列化的字典 bookser=BookSerializer(data=request.data) # bookser.data if bookser.is_valid(raise_exception=True): #清洗經過的數據 bookser.save() else: print(bookser.errors['name'][0]) return Response()
validate_字段名(self,value) 若是校驗失敗,拋出validationError(拋出的異常信息須要去bookser.errors中取) 若是校驗經過直接return value validate(self,attrs) attrs全部校驗經過的數據,是個字典 若是校驗失敗,拋出validationError 若是校驗經過直接return attrs
序列化組件,先調用__new__方法,若是many=True,生成ListSerializer對象,若是爲False,生成Serializer對象 序列化對象.data方法--調用父類data方法---調用對象本身的to_representation(自定義的序列化類無此方法,去父類找) Aerializer類裏有to_representation方法,for循環執行attribute = field.get_attribute(instance) 再去Field類裏去找get_attribute方法,self.source_attrs就是被切分的source,而後執行get_attribute方法,source_attrs 當參數傳過去,判斷是方法就加括號執行,是屬性就把值取出來