Django - rest - framework - 上
一、快速实例
http://www.django-rest-framework.org/tutorial/quickstart/#quickstart
http://www.cnblogs.com/yuanchenqi/articles/8719520.html
简介:
restframework(Django) app
pip install django
pip install djangorestframework
(前后端分离 后端返回 json 数据)
----针对数据:json
---- 一切皆是资源,操作只是请求方式
----book表增删改查
/books/ books
/books/add/ addbook
/books/(\d+)/change/ changebook
/books/(\d+)/delete/ delbook
----book表增删改查 url里面不能出现动词!!
/books/ -----get books ----- 返回当前所有数据
/books/ -----post books ----- 返回提交数据
/books/(\d+)-----get bookdetail ----- 返回当前查看的单条数据
/books/(\d+)-----put bookdetail ----- 返回更新数据
/books/(\d+)-----delete bookdetail ----- 返回空
应用:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/', views.Book.as_view()), url(r'^bookdetail/(\d+)', views.BookDetail.as_view()), ] --------------------------------------------------------------- from django.shortcuts import render,redirect,HttpResponse # Create your views here. from django.views import View class Book(View): def get(self,request): return HttpResponse("get all...") # 查看所有书籍 def post(self,request): return HttpResponse("post all...") # 添加书籍 class BookDetail(View): def get(self,request,pk): return HttpResponse("get ..."+ pk) # 查看某本书籍 def put(self,request,pk): return HttpResponse("put ..." + pk) # 查看某本书籍 def post(self,request,pk): return HttpResponse("post ..." + pk) # 添加某本书籍 def delete(self,request,pk): return HttpResponse("delete ..." + pk) # 删除某本书籍
二、序列化
url(r"^publishes/", views.PublishView.as_view())
方式一 list()
class PublishView(View): def get(self,request): # 方式一: publish_list = list(Publish.objects.all().values("name","email")) # {'name': '苹果出版社', 'email': '123@qq.com'}{'name': '橘子出版社', 'email': '456@qq.com'} return HttpResponse(publish_list)
方式二 model_to_dict(obj)
class PublishView(View): def get(self,request): # 方式二: from django.forms.models import model_to_dict publish_list = Publish.objects.all() temp = [] for obj in publish_list: # temp.append({ # "name":obj.name, # "email":obj.email # }) temp.append(model_to_dict(obj)) print(temp, type(temp)) # [{'name': '苹果出版社', 'email': '123@qq.com'}, {'name': '橘子出版社', 'email': '456@qq.com'}] <class 'list'> # [{'id': 1, 'name': '苹果出版社', 'email': '123@qq.com'}, {'id': 2, 'name': '橘子出版社', 'email': '456@qq.com'}] <class 'list'> return HttpResponse(temp)
方式三 serializers.serialize("json",publish_list)
class PublishView(View): def get(self,request): # 方式三 from django.core import serializers publish_list = Publish.objects.all() ret = serializers.serialize("json",publish_list) """ [ { "model": "app01.publish", "pk": 1, "fields": { "name": "苹果出版社", "email": "123@qq.com" } }, { "model": "app01.publish", "pk": 2, "fields": { "name": "橘子出版社", "email": "456@qq.com" } } ] """ return HttpResponse(ret)
方式四(推荐)(rest_framework serializers)
序列化一个queryset: PublishSerializers(publish_list, many=True)
序列化一个对象: PublishSerializers(model_obj)
from rest_framework import serializers class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.EmailField() class PublishView(View): def get(self,request): # 方式四(推荐) publish_list = Publish.objects.all() ret = PublishSerializers(publish_list, many=True) # queryset # print(ret.data) # print(type(ret.data)) # [OrderedDict([('name', '苹果出版社'), ('email', '123@qq.com')]), # OrderedDict([('name', '橘子出版社'), ('email', '456@qq.com')])] # <class 'rest_framework.utils.serializer_helpers.ReturnList'> """ >>>dict([("name","橘子出版社"),("email","456@qq.com")]) {'name': '橘子出版社', 'email': '456@qq.com'} """ return HttpResponse(ret.data)
三、rest_framework (APIView)
models.py
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") 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
取数据
get:
request._request ( 原request )
request.GET == request._request.GET
post:
request.data ( 得到 json 数据,也可得到 urlencode 数据)
都是 rest_framework APIView 的功劳,
如果使用 View , request.post( 只能得到 urlencode 的数据,不能得到 json 数据,只能从 request.body 中取)
from django.shortcuts import render,redirect,HttpResponse from django.views import View from .models import * from rest_framework.views import APIView, Response from rest_framework import serializers class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.EmailField() class PublishView(APIView): def get(self,request): # 取数据 APIView publish_obj = Publish.objects.all() ret = PublishSerializers(publish_obj,many=True) print(ret.data) # [OrderedDict([('name', '苹果出版社'), ('email', '123@qq.com')]), # OrderedDict([('name', '橘子出版社'), ('email', '456@qq.com')])] print(request.GET) # <QueryDict: {'a': ['1'], 'b': ['2']}> print("data",request.data) # # 只处理 post print(request._request.GET) # <QueryDict: {'a': ['1'], 'b': ['2']}> return HttpResponse(ret.data) # return Response(ret.data) def post(self,request): # 取数据 View (原生request支持得操作) # print("post",request.POST) # <QueryDict: {'a': ['1'], 'b': ['2']}> # print("body",request.body) # b'a=1&b=2' # 发的是json数据 View (不处理json数据,只解析urlencode) (原生request支持得操作) # print("post", request.POST) # <QueryDict: {}> # print("body", request.body) # b'{"name":"yuan","age":12}' # print(type(request)) # <class 'django.core.handlers.wsgi.WSGIRequest'> # from django.core.handlers.wsgi import WSGIRequest # APIView (新得request支持得操作) print(type(request)) # <class 'rest_framework.request.Request'> from rest_framework.request import Request print(request._request) # <WSGIRequest: POST '/publishes/'> print("data",request.data) # {'name': 'yuan', 'age': 12} print("type",type(request.data)) # <class 'dict'> return HttpResponse('POST')
四、rest_framework (Response)
""" 响应器
针对 不同得访问者 浏览器 postman 做不同得处理
只有浏览器,用户 会给一个页面!!
几种请求方式
get post
get put delete
"""
Response:
配置之后:浏览器才可访问; rest_framework 是django的一个app!
可发 get / post 请求 !!
postman: 可模拟浏览器发送
get post put delete ...
from .models import * from rest_framework.views import APIView, Response from rest_framework import serializers class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.EmailField() class PublishView(APIView): def get(self,request): publish_obj = Publish.objects.all() # model_obj = Publish.objects.all().first() ret = PublishSerializers(publish_obj,many=True) # queryset # ret = PublishSerializers(model_obj) # obj return Response(ret.data) def post(self,request): print("data",request.data) # {'name': 'yuan', 'age': 12} return Response(request.data)
五、rest_framework (serializers.Serializer)
一对多:
publish = serializers.CharField() # str(obj) publish = serializers.CharField(source='publish.email')
多对多:
# authors = serializers.CharField(source="authors.all") authors = serializers.SerializerMethodField() def get_authors(self,book_obj): temp = [] for obj in book_obj.authors.all(): temp.append(obj.name) return temp
from .models import * from rest_framework.views import APIView, Response from rest_framework import serializers class BookSerializers(serializers.Serializer): title = serializers.CharField(max_length=32) price = serializers.IntegerField() pub_date = serializers.DateField() publish = serializers.CharField(source='publish.email') # authors = serializers.CharField(source="authors.all") authors = serializers.SerializerMethodField() def get_authors(self,book_obj): temp = [] for obj in book_obj.authors.all(): temp.append(obj.name) return temp class BookView(APIView): def get(self, request): book_list = Book.objects.all() ret = BookSerializers(book_list,many=True) return Response(ret.data) def post(self, request): pass """ 序列化的过程: BookSerializers(book_list,many=True) temp = [] for obj in book_list: "title":obj.title, "price":obj.price, "pub_date":obj.pub_date, "publish":str(obj.publish), #"authors":obj.authors.all, "authors":get_authors(obj) """ class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.EmailField() class PublishView(APIView): def get(self,request): publish_obj = Publish.objects.all() # model_obj = Publish.objects.all().first() ret = PublishSerializers(publish_obj,many=True) # ret = PublishSerializers(model_obj) return Response(ret.data) def post(self,request): print("data",request.data) # {'name': 'yuan', 'age': 12} return Response(request.data) ----------------------------------------- from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r"^publishes/", views.PublishView.as_view()), url(r"^books/", views.BookView.as_view()) ]
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
六、rest_framework (serializers.ModelSerializer)
fields = "__all__"
当然了,可定制一对多,多对多:
publish = serializers.CharField(source="publish.email")
authors = serializers.SerializerMethodField()
... ...
get
class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # publish = serializers.CharField() # str(obj) publish = serializers.CharField(source="publish.email") # authors = serializers.CharField(source="authors.all") authors = serializers.SerializerMethodField() def get_authors(self, book_obj): temp = [] for obj in book_obj.authors.all(): temp.append(obj.name) return temp class BookView(APIView): def get(self, request): book_list = Book.objects.all() ret = BookModelSerializers(book_list,many=True) return Response(ret.data)
post
bms = BookModelSerializers(data = request.data)
bms.is_valid(): # 可校验
bms.save() # create操作
bms.validated_date # 验证后得数据
bms.errors # 错误信息
def create(self, validated_data): pass # 重写create操作
# post 发送得数据 {"title":"金瓶mei","price":88,"pub_date":"2018-12-12","publish":2,"authors":[1,2]}
from .models import * from rest_framework.views import APIView, Response from rest_framework import serializers # class BookSerializers(serializers.Serializer): # title = serializers.CharField(max_length=32) # price = serializers.IntegerField() # pub_date = serializers.DateField() # publish = serializers.CharField(source='publish.email') # # authors = serializers.CharField(source="authors.all") # # authors = serializers.SerializerMethodField() # def get_authors(self,book_obj): # temp = [] # for obj in book_obj.authors.all(): # temp.append(obj.name) # return temp class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # publish = serializers.CharField() # publish = serializers.CharField(source="publish.email",read_only=True) # authors = serializers.CharField(source="authors.all") # authors = serializers.SerializerMethodField() # def get_authors(self, book_obj): # temp = [] # for obj in book_obj.authors.all(): # temp.append(obj.name) # return temp # def create(self, validated_data): # print("validated_data--->",validated_data) # book = Book.objects.create(title=validated_data['title'],price=validated_data["price"], # pub_date=validated_data["pub_date"],publish=validated_data["publish"]) # book.authors.add(*validated_data["authors"]) # # return book class BookView(APIView): def get(self, request): book_list = Book.objects.all() ret = BookModelSerializers(book_list,many=True) return Response(ret.data) def post(self, request): # post请求数据 bms = BookModelSerializers(data=request.data) if bms.is_valid(): bms.save() # create() 可以重写create 当然也可以不写 # print("data:-->",bms.validated_data) # OrderedDict([('title', '金瓶mei11'), ('price', 88), # ('pub_date', datetime.date(2018, 12, 12)), # ('publish', <Publish: Publish object>), # ('authors', [<Author: alex>, <Author: egon>])]) return Response(bms.data) else: return Response(bms.errors)
简洁方法:
authors = validated_data.pop("authors")
obj = Book.objects.create(**validated_data)
obj.authors.add(*authors)
from .models import * from rest_framework.views import APIView, Response from rest_framework import serializers class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" def create(self, validated_data): authors = validated_data.pop("authors") print(authors) # [<Author: alex>, <Author: egon>] obj = Book.objects.create(**validated_data) obj.authors.add(*authors) return obj class BookView(APIView): def get(self, request): book_list = Book.objects.all() ret = BookModelSerializers(book_list,many=True) return Response(ret.data) def post(self, request): bms = BookModelSerializers(data=request.data,many=False) if bms.is_valid(): bms.save() return Response(bms.data) else: return Response(bms.errors)
七、单条数据(get put delete)
get
bms = BookModelSerializers(book)
put
bms = BookModelSerializers(book,data=request.data)
delete
Book.objects.filter(pk=book_id).delete()
url(r'^books/(\d+)/$',views.BookDetailView.as_view()) --------------------------------------------------- class BookDetailView(APIView): def get(self,request,book_id): book = Book.objects.filter(pk=book_id).first() # 序列化 bms = BookModelSerializers(book) return Response(bms.data) def put(self,request,book_id): book = Book.objects.filter(pk=book_id).first() bms = BookModelSerializers(book,data=request.data) if bms.is_valid(): bms.save() return Response(bms.data) else: return Response(bms.errors) def delete(self,reqeust,book_id): Book.objects.filter(pk=book_id).delete() return Response() ------------------------------------------------- class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # def create(self, validated_data): # authors = validated_data.pop("authors") # obj = Book.objects.create(**validated_data) # obj.authors.add(*authors) # return obj
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^publishes/', views.PublishView.as_view()), url(r"^books/$", views.BookView.as_view()), url(r'^books/(\d+)/$',views.BookDetailView.as_view()) ]
from rest_framework.views import APIView, Response from app01.serializers import * class PublishView(APIView): def get(self, request): publish_list = Publish.objects.all() ret = PublishSerializers(publish_list, many=True) return Response(ret.data) def post(self, request): ps = PublishSerializers(data=request.data) if ps.is_valid(): ps.save() return Response(ps.data) else: return Response(ps.errors) class BookView(APIView): def get(self, request): book_list = Book.objects.all() ret = BookModelSerializers(book_list, many=True) return Response(ret.data) def post(self, request): bms = BookModelSerializers(data=request.data, many=False) if bms.is_valid(): bms.save() return Response(bms.data) else: return Response(bms.errors) class BookDetailView(APIView): def get(self,request,book_id): book = Book.objects.filter(pk=book_id).first() # 序列化 bms = BookModelSerializers(book) return Response(bms.data) def put(self,request,book_id): book = Book.objects.filter(pk=book_id).first() bms = BookModelSerializers(book,data=request.data) if bms.is_valid(): bms.save() return Response(bms.data) else: return Response(bms.errors) def delete(self,reqeust,book_id): Book.objects.filter(pk=book_id).delete() return Response()
# -*- coding:utf-8 -*- from .models import * from rest_framework import serializers class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.CharField() def create(self, validated_data): obj = Publish.objects.create(**validated_data) return obj class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" def create(self, validated_data): authors = validated_data.pop("authors") obj = Book.objects.create(**validated_data) obj.authors.add(*authors) return obj
八、HyperlinkedIdentityField
配置:
url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detail_publish"),
ret = BookModelSerializers(book_list, many=True,context={"request":request})
# 显示超链接
publish = serializers.HyperlinkedIdentityField(
view_name="detail_publish", # 别名 含正则表达式
lookup_field="publish_id",
lookup_url_kwarg="pk",
)
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^publishes/$', views.PublishView.as_view(),name="publish"), url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detail_publish"), url(r"^books/$", views.BookView.as_view(),name="books"), url(r'^books/(?P<pk>\d+)/$',views.BookDetailView.as_view(),name="detail_book") ]
from rest_framework.views import APIView, Response from app01.serializers import * class PublishView(APIView): def get(self, request): publish_list = Publish.objects.all() ret = PublishModelSerializers(publish_list, many=True) return Response(ret.data) def post(self, request): ps = PublishModelSerializers(data=request.data) if ps.is_valid(): ps.save() return Response(ps.data) else: return Response(ps.errors) class PublishDetailView(APIView): def get(self,request,pk): publish = Publish.objects.filter(pk=pk).first() ps = PublishModelSerializers(publish) return Response(ps.data) def put(self,request,pk): publish = Publish.objects.filter(pk=pk).first() ps = PublishModelSerializers(publish,data=request.data) if ps.is_valid(): ps.save() return Response(ps.data) else: return Response(ps.errors) def delete(self,request,pk): Publish.objects.filter(pk=pk).delete() return Response() class BookView(APIView): def get(self, request): book_list = Book.objects.all() ret = BookModelSerializers(book_list, many=True,context={"request":request}) return Response(ret.data) def post(self, request): bms = BookModelSerializers(data=request.data, many=False,context={"request":request}) if bms.is_valid(): bms.save() return Response(bms.data) else: return Response(bms.errors) class BookDetailView(APIView): def get(self,request,pk): book = Book.objects.filter(pk=pk).first() # 序列化 bms = BookModelSerializers(book,context={"request":request}) return Response(bms.data) def put(self,request,pk): book = Book.objects.filter(pk=pk).first() bms = BookModelSerializers(book,data=request.data,context={"request":request}) if bms.is_valid(): bms.save() return Response(bms.data) else: return Response(bms.errors) def delete(self,reqeust,pk): Book.objects.filter(pk=pk).delete() return Response()
# -*- coding:utf-8 -*- from .models import * from rest_framework import serializers class PublishModelSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # 显示超链接 publish = serializers.HyperlinkedIdentityField( view_name="detail_publish", # 别名 含正则表达式 lookup_field="publish_id", lookup_url_kwarg="pk", ) # publish = serializers.CharField(source="publish.pk") # publish = serializers.CharField() # authors = serializers.CharField(source="authors.all") # 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
restful协议 ---- 一切皆是资源,操作只是请求方式 ----book表增删改查 /books/ books /books/add/ addbook /books/(\d+)/change/ changebook /books/(\d+)/delete/ delbook ----book表增删改查 url里面不能出现动词!! /books/ -----get books ----- 返回当前所有数据 /books/ -----post books ----- 返回提交数据 /books/(\d+)-----get bookdetail ----- 返回当前查看的单条数据 /books/(\d+)-----put bookdetail ----- 返回更新数据 /books/(\d+)-----delete bookdetail ----- 返回空 http://www.cnblogs.com/yuanchenqi/articles/8719520.html http://www.django-rest-framework.org/tutorial/quickstart/#quickstart 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 # 删除某本书籍 http://www.django-rest-framework.org/tutorial/quickstart/#quickstart restframework(Django) app pip install django pip install djangorestframework ----针对数据:json (1)Django的原生request: 浏览器 ------------- 服务器 "GET url?a=1&b=2 http/1.1\r\user_agent:Google\r\ncontentType:urlencoded\r\n\r\n" "POST url http/1.1\r\user_agent:Google\r\ncontentType:urlencoded\r\n\r\na=1&b=2" request.body: a=1&b=2 request.POST: if contentType:urlencoded: a=1&b=2----->{"a":1,"b":2} (2)restframework 下的APIView: (3) class PublishSerializers(serializers.Serializer): name=serializers.CharField() email=serializers.CharField() PublishSerializers(queryset,many=true) PublishSerializers(model_obj) --------------------------- 总结: 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() restframework 1 APIView 2 序列组件 3 视图、 4 组件(认证权限频率) 5 数据解析器 6 分页和Response