浏览目录
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": "u82f9u679cu51fau7248u793e", "email": "123@qq.com", "id": 1}, # {"name": "u6843u5b50u51fau7248u793e", "email": "456@qq.com", "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": "u82f9u679cu51fau7248u793e", "email": "123@qq.com"}, # {"id": 2, "name": "u6843u5b50u51fau7248u793e", "email": "456@qq.com"}] # 以上方式优化 # 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": "u82f9u679cu51fau7248u793e", "email": "123@qq.com"}}, # {"model": "app01.publish", "pk": 2, "fields": {"name": "u6843u5b50u51fau7248u793e", "email": "456@qq.com"}}]
我们来看一下如何用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":"123@qq.com"},{"name":"桃子出版社","email":"456@qq.com"}]
注意:如果是对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对象不能进行序列化。