快速实例

Quickstart

序列化

开篇介绍:

     ----  一切皆是资源,操作只是请求方式

     ----book表增删改查
/books/ books
/books/add/ addbook
/books/(\d+)/change/ changebook
/books/(\d+)/delete/ delbook ----book表增删改查
/books/ -----get books ----- 返回当前所有数据
/books/ -----post books ----- 返回提交数据 /books/(\d+)-----get bookdetail ----- 返回当前查看的单条数据
/books/(\d+)-----put bookdetail ----- 返回更新数据
/books/(\d+)-----delete bookdetail ----- 返回空 class Books(View):
def get(self,request):
pass # 查看所有书籍 def post(self,request):
pass # 添加书籍 class BooksDetail(View):
def get(self,request,id):
pass # 查看具体书籍 def put(self,request,id):
pass # 更新某本书籍 def delete(self,request,id):
pass # 删除某本书籍

创建一个序列化类

简单使用

开发我们的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",on_delete=models.CASCADE)
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.shortcuts import render,HttpResponse
import json
from django.views import View
from .models import *
from app01.serialize import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers #这是rest_framework的序列化组件 #为queryset(需要加many=True),model对象做序列化
class PublishSerializers(serializers.Serializer):
name =serializers.CharField()
email=serializers.CharField() class PublishView(APIView): def get(self,request):
#取数据
print(request.GET)
publish_list = Publish.objects.all() #序列化
#方式一:
#publish_list=list(Publish.objects.all().values("name","email")) #方式二:
# 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
# publish_list = Publish.objects.all()
# ret=serializers.serialize("json",publish_list) #方式四(restframework序列化)
ps=PublishSerializers(publish_list,many=True)
return HttpResponse(ps.data)

一对多和多对多字段的序列化:

class BookSerializers(serializers.Serializer):
title = serializers.CharField(max_length=32)
price = serializers.IntegerField()
pub_date = serializers.DateField() publish = serializers.CharField(source="publish.email") # 一对多字段使用source字段处理 # 多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
authors = serializers.SerializerMethodField() def get_authors(self, obj):
temp = []
for obj in obj.authors.all():
temp.append(obj.name)
return temp

序列化的过程:

'''
序列化BookSerializers(book_list,many=True)过程:
temp=[]
for obj in book_list:
temp.append({
"title":obj.title,
"price":obj.price,
"pub_date":obj.pub_date,
#"publish":str(publish),
"publish":obj.publish.name,
"authors":get_authors(obj) })
'''

ModelSerializer(类似于ModelForm):

class PublishModelSerializers(serializers.ModelSerializer):
class Meta:
model = Publish
fields = "__all__"

提交post请求:

    def post(self,request):
#原生request支持的操作
# print(request.POST)
# print(request.body)
# print(type(request))
from django.core.handlers.wsgi import WSGIRequest #新的request支持的操作
print("request_data",request.data) #request_data {'name': 'jesi', 'email': '666@qq.com'}
print("request_data_type",type(request.data)) #request_data_type <class 'dict'> return HttpResponse("POST")

get和post:

class BookView(APIView):
def get(self,request):
book_list=Book.objects.all()
# bs=BookSerializers(book_list,many=True)
bs2=BookModelSerializers(book_list,many=True,context={'request': request})
# return Response(bs.data)
return Response(bs2.data) def post(self,request):
#post请求的数据
bs=BookModelSerializers(data=request.data)
     #post请求过来的数据如果通过了校验就创建一条数据,如果没有返回错误信息。
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors)

重写save中的create方法:

# ModelSerializers
class BookModelSerializers(serializers.ModelSerializer):
class Meta:
model = Book
fields = "__all__"
# publish = serializers.CharField(source="publish.pk") # 一对多字段使用source字段处理

  

    # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
def create(self, validated_data):
print(validated_data)
book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
book.authors.add(*validated_data["authors"])
return book

整体:

class BookModelSerializers(serializers.ModelSerializer):
class Meta:
model = Book
fields = "__all__" publish = serializers.CharField(source="publish.pk") # 一对多字段使用source字段处理 #
# #多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
# authors=serializers.SerializerMethodField()
# def get_authors(self,obj):
# temp=[]
# for obj in obj.authors.all():
# temp.append(obj.name)
# return temp # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
def create(self, validated_data):
print(validated_data)
book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
book.authors.add(*validated_data["authors"])
return book

单条数据的get和put请求:

直接通过序列化的实例对象做一个校验,对传入的ID值对应的书籍进行增删改查。

class BookDetailView(APIView):
def get(self,request,id):
#单条数据查看
book=Book.objects.filter(pk=id).first()
bs=BookModelSerializers(book,context={'request': request})
return Response(bs.data) def put(self,request,id):
#更新单条数据
book=Book.objects.filter(pk=id).first() bs = BookModelSerializers(book,request.data)
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors) def delete(self,request,id):
Book.objects.filter(pk=id).delete()
return Response()

超链接API:Hyperlinked

class BookModelSerializers(serializers.ModelSerializer):
class Meta:
model = Book
fields = "__all__"
publish=serializers.HyperlinkedIdentityField(
view_name="publishdetail",
lookup_field="publish_id",
lookup_url_kwarg="id", )

urls部分:

urlpatterns = [
path('admin/', admin.site.urls),
url(r'publishes/$', views.PublishView.as_view(),name="publish"),
url(r'publishes/(?P<id>\d+)/$', views.PublishDetailView.as_view(),name="publishdetail"),
url(r'books/$', views.BookView.as_view(),name="books"),
url(r'books/(\d+)/$', views.BookDetailView.as_view(),name="bookdetail"),
]

这里有一个点需要注意一下:

class BookView(APIView):
def get(self,request):
book_list=Book.objects.all()
# bs=BookSerializers(book_list,many=True)
bs2=BookModelSerializers(book_list,many=True,context={'request': request})
# return Response(bs.data)
return Response(bs2.data) class BookDetailView(APIView):
def get(self,request,id):
#单条数据查看
book=Book.objects.filter(pk=id).first()
bs=BookModelSerializers(book,context={'request': request})
return Response(bs.data)

最后总结:

总结:
1 reuqest类----源码 2 restframework 下的APIView--源码 url(r'^books/$', views.BookView.as_view(),name="books")# View下的view books/一旦被访问: view(request) ------APIView: dispatch() 3 def dispatch(): 构建request对象
self.request=Request(request)
self.request._request
self.request.GET # get
self.request.data # POST PUT 分发----if get请求:
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) # self.get(request, *args, **kwargs) return response 4 序列化类
# from django.core import serializers
# ret=serializers.serialize("json",publish_list) restframework下的序列类 BookModelSerializers
将queryset或者model对象序列成一json数据
bs=BookModelSerializers(book_list,many=True,context={'request': request})
bs=BookModelSerializers(book,context={'request': request}) 还可以做校验数据,json-------》queryset/model-->记录 bs=BookModelSerializers(data=request.data)
if bs.is_valid():
print(bs.validated_data)
bs.save() # 重写create方法
5 操作数据: 以Book表为例
class BookView(APIView):
# 查看所有书籍
def get(self,request):
book_list=Book.objects.all()
bs=BookModelSerializers(book_list,many=True,context={'request': request})
return Response(bs.data) # 添加一本书籍
def post(self,request):
# post请求的数据
bs=BookModelSerializers(data=request.data)
if bs.is_valid():
print(bs.validated_data)
bs.save()# create方法
return Response(bs.data)
else:
return Response(bs.errors) class BookDetailView(APIView):
# 查看一本书籍
def get(self,request,id): book=Book.objects.filter(pk=id).first()
bs=BookModelSerializers(book,context={'request': request})
return Response(bs.data)
# 更新一本书籍
def put(self,request,id):
book=Book.objects.filter(pk=id).first()
bs=BookModelSerializers(book,data=request.data)
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors)
# 删除某一本书籍
def delete(self,request,id):
Book.objects.filter(pk=id).delete() return Response()

代码:

views.py

from django.shortcuts import render,HttpResponse
import json
from django.views import View
from .models import *
from app01.serialize import *
from rest_framework.views import APIView
from rest_framework.response import Response class PublishView(APIView): def get(self,request):
#取数据
print(request.GET)
publish_list = Publish.objects.all() #序列化
#方式一:
#publish_list=list(Publish.objects.all().values("name","email")) #方式二:
# 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
# publish_list = Publish.objects.all()
# ret=serializers.serialize("json",publish_list) #方式四(restframework序列化)
ps=PublishSerializers(publish_list,many=True)
return HttpResponse(ps.data) def post(self,request):
#原生request支持的操作
# print(request.POST)
# print(request.body)
# print(type(request))
from django.core.handlers.wsgi import WSGIRequest #新的request支持的操作
print("request_data",request.data) #request_data {'name': 'jesi', 'email': '666@qq.com'}
print("request_data_type",type(request.data)) #request_data_type <class 'dict'> return HttpResponse("POST") class PublishDetailView(APIView):
def get(self,request,id):
#单条数据查看
publish=Publish.objects.filter(pk=id).first()
ps=PublishModelSerializers(publish)
return Response(ps.data) def put(self,request,id):
#更新单条数据
publish=Publish.objects.filter(pk=id).first() ps = PublishModelSerializers(publish,request.data)
if ps.is_valid():
ps.save()
return Response(ps.data)
else:
return Response(ps.errors) def delete(self,request,id):
Publish.objects.filter(pk=id).delete()
return Response() class BookView(APIView):
def get(self,request):
book_list=Book.objects.all()
# bs=BookSerializers(book_list,many=True)
bs2=BookModelSerializers(book_list,many=True,context={'request': request})
# return Response(bs.data)
return Response(bs2.data) def post(self,request):
#post请求的数据
bs=BookModelSerializers(data=request.data)
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors) class BookDetailView(APIView):
def get(self,request,id):
#单条数据查看
book=Book.objects.filter(pk=id).first()
bs=BookModelSerializers(book,context={'request': request})
return Response(bs.data) def put(self,request,id):
#更新单条数据
book=Book.objects.filter(pk=id).first() bs = BookModelSerializers(book,request.data)
if bs.is_valid():
bs.save()
return Response(bs.data)
else:
return Response(bs.errors) def delete(self,request,id):
Book.objects.filter(pk=id).delete()
return Response()

serialize.py

# Author:Jesi
# Time : 2018/10/5 11:29
from app01.models import *
from rest_framework import serializers #这是rest_framework的序列化组件
#为queryset(需要加many=True),model对象做序列化
class PublishSerializers(serializers.Serializer):
name =serializers.CharField()
email=serializers.CharField() # Serializers
class BookSerializers(serializers.Serializer):
title = serializers.CharField(max_length=32)
price = serializers.IntegerField()
pub_date = serializers.DateField() publish = serializers.CharField(source="publish.email") # 一对多字段使用source字段处理 # 多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
authors = serializers.SerializerMethodField() def get_authors(self, obj):
temp = []
for obj in obj.authors.all():
temp.append(obj.name)
return temp '''
序列化BookSerializers(book_list,many=True)过程:
temp=[]
for obj in book_list:
temp.append({
"title":obj.title,
"price":obj.price,
"pub_date":obj.pub_date,
#"publish":str(publish),
"publish":obj.publish.name,
"authors":get_authors(obj) })
''' class PublishModelSerializers(serializers.ModelSerializer):
class Meta:
model = Publish
fields = "__all__" # ModelSerializers
class BookModelSerializers(serializers.ModelSerializer):
class Meta:
model = Book
fields = "__all__"
publish=serializers.HyperlinkedIdentityField(
view_name="publishdetail",
lookup_field="publish_id",
lookup_url_kwarg="id", ) # publish = serializers.CharField(source="publish.pk") # 一对多字段使用source字段处理 #
# #多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
# authors=serializers.SerializerMethodField()
# def get_authors(self,obj):
# temp=[]
# for obj in obj.authors.all():
# temp.append(obj.name)
# return temp # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
def create(self, validated_data):
print(validated_data)
book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
book.authors.add(*validated_data["authors"])
return book

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
url(r'publishes/$', views.PublishView.as_view(),name="publish"),
url(r'publishes/(?P<id>\d+)/$', views.PublishDetailView.as_view(),name="publishdetail"),
url(r'books/$', views.BookView.as_view(),name="books"),
url(r'books/(\d+)/$', views.BookDetailView.as_view(),name="bookdetail"),
]

rest-framework序列化的更多相关文章

  1. Django REST Framework序列化器

    Django序列化和json模块的序列化 从数据库中取出数据后,虽然不能直接将queryset和model对象以及datetime类型序列化,但都可以将其转化成可以序列化的类型,再序列化. 功能需求都 ...

  2. rest framework 序列化之depth遇到用户表外键的尴尬情况

    rest framework 序列化之depth遇到用户表外键的尴尬情况 问题:ModelSerializer序列化使用depth=1直接扩表把用户表所有信息查询出来的情况 class xxxSeri ...

  3. [Django REST framework - 序列化组件、source、钩子函数]

    [Django REST framework - 序列化组件.source.钩子函数] 序列化器-Serializer 什么是rest_framework序列化? 在写前后端不分离的项目时: 我们有f ...

  4. Django REST framework序列化

    一.简介 Django REST framework是基于Django实现的一个RESTful风格API框架,能够帮助我们快速开发RESTful风格的API. 官网:https://www.djang ...

  5. Django Rest framework序列化流程

    目录 一 什么是序列化 二 Django REST framework配置流程之Serializer 三 Django REST framework配置流程之ModelSerializer 一 什么是 ...

  6. 02 Django REST Framework 序列化

    01-创建序列化类 # 方式一: publish_list = models.Publish.objects.all() # 导入序列化组件 from django.core import seria ...

  7. rest framework 序列化

    serializers 序列化组件 可以实现很轻松的互相转换,最常用的组件 ,用量最大的组件 源码位置 rest_framework.serializers 源码中需要用到的    rest_fram ...

  8. python学习-- Django REST framework 序列化数据操作

    一.为什么要返回json数据? 一般来说前端要用到从后台返回的数据来渲染页面的时候,这时候后台就需要向前端返回json类型的数据,简单直观便于理解 ,就类似于 {"xxx":{[& ...

  9. Django REST Framework 序列化和校验 知识点

    DRF序列化 Django ORM对象 --> JSON格式的数据 序列化 JSON格式的数据 --> Django ORM数据 反序列化 需要两个工具: from rest_framew ...

  10. django rest framework 序列化组件总结

    序列化组件总结 一. 序列化组件本质上为了实现前后端分离,而进行json序列化的一个组件形式,极大方便了解析数据的作用 二. 所有序列化是基于APIView 解析器实现的,通过内部的多继承关系方便实现 ...

随机推荐

  1. 为爱好舞蹈的人们做的软件,细究数据结构,操作系统,磁盘原理,用java/c/c++写一个开源 MP3助手

    1.可以给歌曲间插播空白音乐 2.拖拽式调整 3.先排序,后一键写入顺序文件. 国外的开源软件 MP3 播放排序  http://www.murraymoffatt.com/software-prob ...

  2. Qt的事件

    Qt的事件机制 事件过滤器: 可以让一个对象侦听拦截另外一个对象的事件. 实现原理: 在所有Qt对象的基类:QObject中有一个 类型为:QObjectList 名字为:eventFilters 的 ...

  3. May 28. 2018 Week 22nd Monday

    Do one thing at a time, and do well. 一次只做一件事,并且要做到最好. Why is it that about 25% to 50% of people have ...

  4. Ubuntu 12.04上安装MySQL并运行

    Ubuntu 12.04上安装MySQL并运行 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 安装MySQL数据库 sudo apt-get upda ...

  5. 关于Three.js基本几何形状

    一.有关球体SphereGeometry构造函数参数说明 SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLeng ...

  6. Java 7 for Absolute Beginners/Java 7基础教程--读后感

    1. 很适合部分初学者,因为书中对于JAVA许多特性都有涉猎,而且也是浅尝即止.如果读者没有受过专业的编程训练,那么在阅读此书时不会畏惧.因为书中没有充斥着大量的计算机理论知识,虽然作者依然覆盖了JA ...

  7. 用js显示系统当前日期

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. 在 Linux 中自动配置 IPv6 地址

    在 Linux 中自动配置 IPv6 地址 在本文中,我们将学习如何为 ULA 自动配置 IP 地址. 何时使用唯一本地地址 唯一本地地址unique local addresses(ULA)使用 f ...

  9. 关于HashMap的一些深入探索与理解

    在java中.大家差点儿是离不开对集合的使用的,像Map系列,List系列.Set系列.可是非常多人没有了解过或者研究过这些集合类究竟能够用在什么地方,而且有什么注意的地方.因此本文分Map系列和Li ...

  10. 使用c#封装海康SDK出现无法加载 DLL“..\bin\HCNetSDK.dll”: 找不到指定的模块

    最近在研究网络摄像头的二次开发,测试了一款海康威视的网络摄像头,程序调试的时候,出现如题的报错. 调试随机自带的demo时,程序运行正常,但当把该程序引入到我自己的程序中时,就开始报错.根据开发软件包 ...