rest-framework組件 之 序列化
阿新 • • 發佈:2018-05-29
link 優化 操作 self. req elf clas erro django f
瀏覽目錄
-
簡單使用
-
ModelSerializer
-
提交post請求
-
重寫save的create方法
-
單條數據的get和put請求
-
超鏈接API
restful協議
一切皆是資源,操作只是請求方式。
rest-framework
針對數據:json數據。
創建一個序列化類
簡單使用
開發我們的Web API的第一件事是為我們的Web API提供一種將代碼片段實例序列化和反序列化為諸如json
之類的表示形式的方式。我們可以通過聲明與Django forms非常相似的序列化器(serializers)來實現。
models
from django.db import models # Create your models here. 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
views
from django.views import View from .models import * class PublishView(View): def get(self,request): # 序列化方式一 # publish_list=list(Publish.objects.all().values("id","name","email")) #queryset不能進行序列化,強轉為list。 # return HttpResponse(json.dumps(publish_list)) #轉化為json字符串 # 結果:[{"name": "\u82f9\u679c\u51fa\u7248\u793e", "email": "[email protected]", "id": 1}, # {"name": "\u6843\u5b50\u51fa\u7248\u793e", "email": "[email protected]", "id": 2}] # 序列化方式二 # publish_list=Publish.objects.all() # temp=[] # for obj in publish_list: # temp.append({ # "id":obj.pk, # "name":obj.name, # "email":obj.email # }) # return HttpResponse(json.dumps(temp)) # 結果:[{"id": 1, "name": "\u82f9\u679c\u51fa\u7248\u793e", "email": "[email protected]"}, # {"id": 2, "name": "\u6843\u5b50\u51fa\u7248\u793e", "email": "[email protected]"}] # 以上方式優化 # from django.forms.models import model_to_dict # publish_list = Publish.objects.all() # temp = [] # for obj in publish_list: # temp.append(model_to_dict(obj)) # 序列化方式三 from django.core import serializers #django的序列化組件 publish_list = Publish.objects.all() ret=serializers.serialize("json",publish_list) return HttpResponse(ret) # 結果: # [{"model": "app01.publish", "pk": 1, "fields": {"name": "\u82f9\u679c\u51fa\u7248\u793e", "email": "[email protected]"}}, # {"model": "app01.publish", "pk": 2, "fields": {"name": "\u6843\u5b50\u51fa\u7248\u793e", "email": "[email protected]"}}]
我們來看一下如何用rest-framework進行序列化。
from django.core import serializers from .models import * from rest_framework.response import Response from rest_framework import serializers from rest_framework.views import APIView # 為queryset,model對象做序列化 # 實例化一個類 class PublishSerializers(serializers.Serializer): # 需要序列化的字段 name=serializers.CharField() email=serializers.CharField() class PublishView(APIView): def get(self,request): # 方式四:restframework publish_list = Publish.objects.all() ps = PublishSerializers(publish_list, many=True) #實例化一個對象 return Response(ps.data) # 結果:[{"name":"蘋果出版社","email":"[email protected]"},{"name":"桃子出版社","email":"[email protected]"}]
註意:如果是對queryset做序列化,就要加many=True.如果是對model對象做序列化,就是many=False.默認為false,可以不用寫。
實例化的時候要是數據是一個 queryset 我們要加 many = True ret = PublishSerializers(publish_list, many=True) ret.data ------------------------------------拿到的是一個OrderDict。
實例化的時候要是數據是一個model對象,many默認是一個False(可以不寫) ret = PublishSerializers(obj) ret.data ------------------------------------拿到的是一個字典
ModelSerializer
class BookSerializers(serializers.ModelSerializer): class Meta: model=Book fields="__all__" depth=1
提交post請求
def post(self,request,*args,**kwargs): bs=BookSerializers(data=request.data,many=False) if bs.is_valid(): # print(bs.validated_data) bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
重寫save的create方法
class BookSerializers(serializers.ModelSerializer): class Meta: model=Book fields="__all__" # exclude = [‘authors‘,] # depth=1 def create(self, validated_data): authors = validated_data.pop(‘authors‘) obj = Book.objects.create(**validated_data) obj.authors.add(*authors) return obj
單條數據的get和put請求
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)
超鏈接API
class BookSerializers(serializers.ModelSerializer): publish= serializers.HyperlinkedIdentityField( view_name=‘publish_detail‘, lookup_field="publish_id", lookup_url_kwarg="pk") class Meta: model=Book fields="__all__" #depth=1
urls
urlpatterns = [ url(r‘^books/$‘, views.BookViewSet.as_view(),name="book_list"), url(r‘^books/(?P<pk>\d+)$‘, views.BookDetailViewSet.as_view(),name="book_detail"), url(r‘^publishers/$‘, views.PublishViewSet.as_view(),name="publish_list"), url(r‘^publishers/(?P<pk>\d+)$‘, views.PublishDetailViewSet.as_view(),name="publish_detail"), ]
總結:
1、queryset對象不能進行序列化。
rest-framework組件 之 序列化