Django - rest - framework - 下
一、视图三部曲
https://www.cnblogs.com/wupeiqi/articles/7805382.html
使用混合(mixins)
之前得视图部分
# urls.py 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") ] ------------------------------------------------------ # views.py 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() ---------------------------------------------------
# serializers.py # -*- 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__"
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
models.py
1. mixin类编写视图
from rest_framework import mixins, generics
mixins.ListModelMixin, mixins.CreateModelMixin,
mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin,
generics.GenericAPIView
url(r'^authors/$',views.AuthorView.as_view(),name="author"),
url(r'^authors/(?P<pk>\d+)',views.AuthorDetailView.as_view(),name="detail_author"), ----------------------------------------- ######################### mixin类编写视图 ############################## from rest_framework import mixins, generics class AuthorView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs) class AuthorDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs) ------------------------------------------------ class AuthorModelSerializers(serializers.ModelSerializer):
class Meta:
model = Author
fields = "__all__"
2. 使用通用的基于类的视图
from rest_framework import generics
generics.ListCreateAPIView
generics.RetrieveUpdateDestroyAPIView
通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py
模块。
######################### 使用通用得基于类得视图 ############################## from rest_framework import generics class AuthorView(generics.ListCreateAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
3. viewsets.ModelViewSet
views.AuthorModelView.as_view({"get": "list", "post": "create"})
views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})
from rest_framework import viewsets
viewsets.ModelViewSet
url(r'^authors/$', views.AuthorModelView.as_view({"get": "list", "post": "create"}), name="author"),
url(r'^authors/(?P<pk>\d+)',
views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}), name="detail_author"), --------------------------------------------------- ######################### viewsets.ModelViewSet ############################## from rest_framework import viewsets class AuthorModelView(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers # 可重写,覆盖!
# def list(self,request,*args,**kwargs):pass
效果:
get post get put delete 都可访问!
http://www.cnblogs.com/yuanchenqi/articles/8719520.html
视图三部曲
5中方法: 查(全部) 查(单条) 增 删 改
逻辑封装起来了 ----------------------------------- class AuthorModelView(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers (1):url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}), name='author'),
(2):url(r'^authors/$', ViewSetMixin.as_view({"get":"list","post":"create"}), name='author'),
(3):url(r'^authors/$', ViewsetMixin.View, name='author'), 一旦用户 get 方式 访问 authors:
ViewsetMixin.View():
for method, action in actions.items(): # {"get":"list","post":"create"}
handler = getattr(self, action) # self.list self.create
setattr(self, method, handler) # self.get = self.list self.post = self.create # getattr(self,"get") # self.list
# getattr(self,"post") # self.create return self.dispatch() APIView.dispatch():
if request.method.lower() in self.http_method_names:
handler = getattr(self,request.method.lower())
response = handler(request,*args,**kwargs) # self.list() return response (ViewSetMixin)
小总结 - 笔记
二、认证组件
生成随机字符串
import hashlib, time def get_random_str(user):
""" 生成随机 字符串 """
ctime = str(time.time()) md5 = hashlib.md5(bytes(user,encoding='utf-8'))
md5.update(bytes(ctime,encoding="utf-8")) return md5.hexdigest()
update_or_create
# update_or_create
Token.objects.update_or_create(user=user,defaults={"token":random_str})
返回json
# import json
# from django.shortcuts import HttpResponse
# return HttpResponse(json.dumps(res,ensure_ascii=False)) # from django.http import JsonResponse
# return JsonResponse(res) return Response(res)
登录,生成随机token
url(r'^login/$', views.LoginView.as_view(), name="login") --------------------------------------------- import hashlib, time def get_random_str(user):
""" 生成随机 字符串 """
ctime = str(time.time()) md5 = hashlib.md5(bytes(user,encoding='utf-8'))
md5.update(bytes(ctime,encoding="utf-8")) return md5.hexdigest() class LoginView(APIView):
def post(self,request):
name = request.data.get("name")
pwd = request.data.get("pwd") user = User.objects.filter(name=name,pwd=pwd).first()
res = {"state_code":1000,"msg":None}
if user:
random_str = get_random_str(user.name)
# update_or_create
Token.objects.update_or_create(user=user,defaults={"token":random_str})
res["token"] = random_str
else:
res["state_code"] = 1001 # 错误状态码
res["msg"] = "用户名或密码错误" # import json
# from django.shortcuts import HttpResponse
# return HttpResponse(json.dumps(res,ensure_ascii=False)) # from django.http import JsonResponse
# return JsonResponse(res) return Response(res) -------------------------------------------------------- # models.py class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32) class Token(models.Model):
user = models.OneToOneField("User")
token = models.CharField(max_length=128) def __str__(self):
return self.token
效果图:
登录验证 - 局部
authentication_classes = [TokenAuth]
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
def authenticate(self,request):
... ...
if not token_obj:
raise exceptions.AuthenticationFailed("验证失败")
return (token_obj.user.name, token_obj)
from rest_framework import exceptions # class TokenAuth(object):
# def authenticate(self,request):
# token = request.GET.get("token")
# token_obj = Token.objects.filter(token=token).first()
# if not token_obj:
# raise exceptions.AuthenticationFailed("验证失败")
#
# return (token_obj.user.name, token_obj)
#
# def authenticate_header(self,request):
# pass from rest_framework.authentication import BaseAuthentication class TokenAuth(BaseAuthentication):
def authenticate(self,request):
token = request.GET.get("token")
token_obj = Token.objects.filter(token=token).first()
if not token_obj:
raise exceptions.AuthenticationFailed("验证失败") return (token_obj.user.name, token_obj) class BookView(APIView):
authentication_classes = [TokenAuth] 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)
登录验证 - 全局
settings 配置
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth']
# settings.py REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth']
} -------------------------------------------
# app01.utils from .models import *
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication class TokenAuth(BaseAuthentication):
def authenticate(self,request):
token = request.GET.get("token")
token_obj = Token.objects.filter(token=token).first()
if not token_obj:
raise exceptions.AuthenticationFailed("验证失败") return (token_obj.user.name, token_obj) --------------------------------------------
# views.py 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 AuthorModelView(viewsets.ModelViewSet):
authentication_classes = [] # 加上这个,前提是全局有认证;加上这个,就走自己得,不认证了,自己没有,才走全局配置得! queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
效果图:
三、权限组件
权限 - 局部
permission_classes = [SVIPPermission]
has_permission(self,request,view):pass # 固定得写法,根据源码来写得!
authentication_classes = [] # 登录页面 不需要验证,在全局配置得前提下
class AuthorModelView(viewsets.ModelViewSet):
authentication_classes = [TokenAuth]
permission_classes = [SVIPPermission] queryset = Author.objects.all()
serializer_class = AuthorModelSerializers ----------------------------------------------
# app01.utils.SVIPPermission
class SVIPPermission(object):
message = "只有超级用户才能访问"
def has_permission(self,request,view):
username = request.user
user_type = User.objects.filter(name=username).first().user_type
if user_type == 3:
return True
else:
return False ---------------------------------------------- class LoginView(APIView):
authentication_classes = []
... ...
权限 - 全局
settings配置:
'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission']
# settings.py REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],
'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission']
}
效果图:
四、频率组件
局部视图throttle
class BookView(APIView):
# authentication_classes = [TokenAuth]
# permission_classes = [SVIPPermission]
throttle_classes = [VisitRateThrottle] 。。。 。。。 ----------------------------------------------- from rest_framework.throttling import BaseThrottle VISIT_RECORD={}
class VisitThrottle(BaseThrottle): def __init__(self):
self.history=None def allow_request(self,request,view):
remote_addr = request.META.get('REMOTE_ADDR')
print(remote_addr)
import time
ctime=time.time() if remote_addr not in VISIT_RECORD:
VISIT_RECORD[remote_addr]=[ctime,]
return True history=VISIT_RECORD.get(remote_addr)
self.history=history while history and history[-1]<ctime-60:
history.pop() if len(history)<3:
history.insert(0,ctime)
return True
else:
return False def wait(self):
import time
ctime=time.time()
return 60-(ctime-self.history[-1])
全局视图throttle
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],
'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission'],
'DEFAULT_THROTTLE_CLASSES': ['app01.utils.VisitThrottle'],
}
内置throttle类
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],
'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission'],
'DEFAULT_THROTTLE_CLASSES': ['app01.utils.VisitThrottle'],
"DEFAULT_THROTTLE_RATES": {
"visit_rate": "1/m",
}
} ------------------------------------ from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle): scope="visit_rate"
def get_cache_key(self, request, view): return self.get_ident(request)
http://www.cnblogs.com/yuanchenqi/articles/8719520.html
五、解析器
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
"""
默认得是 JSONParser FormParser MultiPartParser
""" class BookView(APIView): parser_classes = [JSONParser,FormParser] ...
request类
django的request类和rest-framework的request类的源码解析
局部视图
from rest_framework.parsers import JSONParser,FormParser
class PublishViewSet(generics.ListCreateAPIView):
parser_classes = [FormParser,JSONParser]
queryset = Publish.objects.all()
serializer_class = PublshSerializers
def post(self, request, *args, **kwargs):
print("request.data",request.data)
return self.create(request, *args, **kwargs)
全局视图
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
"DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],
"DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",],
"DEFAULT_THROTTLE_RATES":{
"visit_rate":"5/m",
},
"DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',]
}
六、url路由控制
url(r'',include(routers.urls)),
from rest_framework import routers
routers = routers.DefaultRouter()
routers.register("authors",views.AuthorModelView)
# urls.py from django.conf.urls import url,include
from django.contrib import admin from app01 import views from rest_framework import routers
routers = routers.DefaultRouter()
routers.register("authors",views.AuthorModelView) 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"), # url(r'^authors/$',views.AuthorView.as_view(),name="author"),
# url(r'^authors/(?P<pk>\d+)',views.AuthorDetailView.as_view(),name="detail_author"), # url(r'^authors/$', views.AuthorModelView.as_view({"get": "list", "post": "create"}), name="author"),
# url(r'^authors/(?P<pk>\d+)',
# views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}), name="detail_author"), url(r'',include(routers.urls)), url(r'^login/$', views.LoginView.as_view(), name="login") ] ------------------------------------------ # views.py from rest_framework import viewsets class AuthorModelView(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
效果图
七、分页
pnp = MyPageNumberPagination()
books_page = pnp.paginate_queryset(book_list,request,self)
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination class MyPageNumberPagination(PageNumberPagination):
page_size = 2
page_query_param = "page"
page_size_query_param = "size"
max_page_size = 2 # 限制 size 得大小 不能超过多少!! class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = 1 --------------------------- class BookView(APIView):def get(self, request): book_list = Book.objects.all() pnp = MyPageNumberPagination()
# pnp = MyLimitOffsetPagination() books_page = pnp.paginate_queryset(book_list,request,self) # ret = BookModelSerializers(book_list, many=True, context={"request": request})
ret = BookModelSerializers(books_page, many=True) # return Response(ret.data)
return pnp.get_paginated_response(ret.data)
from rest_framework import viewsets class AuthorModelView(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers pagination_class = MyPageNumberPagination
效果图
day99 1 CBV 2 APIView
class BookView(APIView):pass
url(r'^books/$', views.BookView.as_view(),name="books"),
url(r'^books/$', View类下的view,name="books"),
一旦访问books/: view(request)======APIView类下的dispatch()====请求方式对应的示例方法() 3 def dispatch():
#一 初始化操作
# (1) 构建新的request:
self.request=self.initial_request()
# self.request._request
# self.request.GET
# self.request.data
# (2) 执行组件
# 认证,权限,频率
# 认证:request.user
self.initial(request, *args, **kwargs)
==== # 认证组件
self.perform_authentication(request)
==== request.user
=====
for authenticator in self.authenticators: # [TokenAuth(),]
try:
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple
return # 权限组件
self.check_permissions(request)
===========
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
) # 频率组件
self.check_throttles(request) =============
for throttle in self.get_throttles(): # [VisitRateThrottle(),]
if not throttle.allow_request(request, self):
self.throttled(request, throttle.wait()) # 受限制 # 分发
if request.method.lower() in self.http_method_names:
handler = getattr(self,request.method.lower(),
self.http_method_not_allowed) response = handler(request, *args, **kwargs) return response 4 序列化组件 class PublishSerializers(serializers.Serializer):
name = serializers.CharField()
email = serializers.CharField() class PublishModelSerializers(serializers.ModelSerializer):
class Meta:
model=Publish
fields="__all__" # queryset或者model对象-------------》json数据
ps=PublishSerializers(queryset,many=True)
ps.data # [{},{},{}] ps=PublishSerializers(model_obj,many=False)
ps.data # {} # json数据-------》记录
# 添加操作
ps=PublishSerializers(data=request.data)
if ps.is_valid():
ps.save() # create # 更新操作 ps=PublishSerializers(model_obj,data=request.data)
if ps.is_valid():
ps.save() # update 5 视图组件
# 版本1:
# 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() # 版本2:mixIn from rest_framework import mixins
from rest_framework import generics class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers def get(self,request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self,request, *args, **kwargs):
return self.create(request, *args, **kwargs) class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers def get(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs) def delete(self,request,*args, **kwargs):
return self.destroy(request,*args, **kwargs) def put(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs) # 版本3:基于通用类
from rest_framework import mixins
from rest_framework import generics class AuthorView(generics.ListCreateAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers # 版本4
class AuthorModelView(viewsets.ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put" 流程:
url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
url(r'^authors/$', ViewSetMixin.as_view({"get":"list","post":"create"}),name="author"),
url(r'^authors/$', ViewSetMixin类下的view),
一旦访问 /authors/:
ViewSetMixin
def view():
for method, action in actions.items(): # {"get":"list","post":"create"}
handler = getattr(self, action) # self.list self.create
setattr(self, method, handler) self.dispatch(request, *args, **kwargs) APIView类下的self.dispatch
# 分发
if request.method.lower() in self.http_method_names:
handler = getattr(self,request.method.lower(),
self.http_method_not_allowed) response = handler(request, *args, **kwargs) # self.list() return response 6 认证权限频率 组件 request.META:
{'ALLUSERSPROFILE': 'C:\\ProgramData',
'APPDATA': 'C:\\Users\\Administrator\\AppData\\Roaming',
'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files',
'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files',
'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files',
'COMPUTERNAME': 'PC201712041709',
'COMSPEC': 'C:\\Windows\\system32\\cmd.exe',
'DJANGO_SETTINGS_MODULE': 'restdemo.settings',
'FP_NO_HOST_CHECK': 'NO', 'HOMEDRIVE': 'C:',
'HOMEPATH': '\\Users\\Administrator',
'LOCALAPPDATA': 'C:\\Users\\Administrator\\AppData\\Local',
'LOGONSERVER': '\\\\PC201712041709',
'NUMBER_OF_PROCESSORS': '', 'OS': 'Windows_NT',
'PATH': 'C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\Scripts;C:\\Python27;E:\\MySQL Server 5.6\\bin;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\Scripts\\;C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\;C:\\Users\\Administrator\\AppData\\Local\\atom\\bin',
'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC',
'PROCESSOR_ARCHITECTURE': 'AMD64',
'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 60 Stepping 3, GenuineIntel',
'PROCESSOR_LEVEL': '', 'PROCESSOR_REVISION': '3c03',
'PROGRAMDATA': 'C:\\ProgramData',
'PROGRAMFILES': 'C:\\Program Files',
'PROGRAMFILES(X86)': 'C:\\Program Files (x86)',
'PROGRAMW6432': 'C:\\Program Files',
'PSMODULEPATH': 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\',
'PUBLIC': 'C:\\Users\\Public', 'PYCHARM_HOSTED': '', 'PYTHONIOENCODING': 'UTF-8',
'PYTHONPATH': 'C:\\Users\\Administrator\\PycharmProjects\\s9\\restdemo', 'PYTHONUNBUFFERED': '',
'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\Windows',
'TEMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp',
'USERDOMAIN': 'PC201712041709',
'USERNAME': 'Administrator',
'USERPROFILE': 'C:\\Users\\Administrator',
'WINDIR': 'C:\\Windows', 'WINDOWS_TRACING_FLAGS': '',
'WINDOWS_TRACING_LOGFILE': 'C:\\BVTBin\\Tests\\installpackage\\csilogfile.log',
'RUN_MAIN': 'true', 'SERVER_NAME': 'PC201712041709',
'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '',
'REMOTE_HOST': '',
'CONTENT_LENGTH': '',
'SCRIPT_NAME': '',
'SERVER_PROTOCOL': 'HTTP/1.1',
'SERVER_SOFTWARE': 'WSGIServer/0.2',
'REQUEST_METHOD': 'GET',
'PATH_INFO': '/authors/',
'QUERY_STRING': 'token=8204b8e3ac40bf59ae480d17c146b51a',
'REMOTE_ADDR': '127.0.0.1',
'CONTENT_TYPE': 'text/plain',
'HTTP_HOST': '127.0.0.1:8000',
'HTTP_CONNECTION': 'keep-alive',
'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
'HTTP_UPGRADE_INSECURE_REQUESTS': '',
'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HTTP_COOKIE': 'csrftoken=jtus3l4GJEc9TFXWYCWxkBIZprcOv7C1vFMIyOHs7Zkxt015FwVZ2KEEeDV6LOyN', 'wsgi.input': <_io.BufferedReader name=832>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>} 7 解析器-----数据解析器
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
parser_classes = [JSONParser,FormParser] 8 路由控制
针对:
url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"), class AuthorModelView(viewsets.ModelViewSet): queryset = Author.objects.all()
serializer_class = AuthorModelSerializers url(r'^books/$', views.BookModelView.as_view({"get":"list","post":"create"}),name="author"),
url(r'^books/(?P<pk>\d+)/$', views.BookModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailbook"), class AuthorModelView(viewsets.ModelViewSet): queryset = Author.objects.all()
serializer_class = AuthorModelSerializers 9 分页 10 响应器 Response
总结 - 笔记
REST_FRAMEWORK = {
# 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.TokenAuth'],
# 'DEFAULT_PERMISSION_CLASSES': ['app01.utils.SVIPPermission'],
# 'DEFAULT_THROTTLE_CLASSES': ['app01.utils.VisitThrottle'],
# "DEFAULT_THROTTLE_RATES": {
# "visit_rate": "1/m",
# }
# "PAGE_SIZE":2
}
settings.py
from django.conf.urls import url,include
from django.contrib import admin from app01 import views from rest_framework import routers
routers = routers.DefaultRouter()
routers.register("authors",views.AuthorModelView) 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"), # url(r'^authors/$',views.AuthorView.as_view(),name="author"),
# url(r'^authors/(?P<pk>\d+)',views.AuthorDetailView.as_view(),name="detail_author"), # url(r'^authors/$', views.AuthorModelView.as_view({"get": "list", "post": "create"}), name="author"),
# url(r'^authors/(?P<pk>\d+)',
# views.AuthorModelView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}), name="detail_author"), url(r'',include(routers.urls)), url(r'^login/$', views.LoginView.as_view(), name="login") ]
urls.py
from .models import *
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication class TokenAuth(BaseAuthentication):
def authenticate(self,request):
token = request.GET.get("token")
token_obj = Token.objects.filter(token=token).first()
if not token_obj:
raise exceptions.AuthenticationFailed("验证失败") return (token_obj.user.name, token_obj) class SVIPPermission(object):
message = "只有超级用户才能访问"
def has_permission(self,request,view):
username = request.user
user_type = User.objects.filter(name=username).first().user_type
if user_type == 3:
return True
else:
return False # from rest_framework.throttling import BaseThrottle
#
# VISIT_RECORD={}
# class VisitThrottle(BaseThrottle):
#
# def __init__(self):
# self.history=None
#
# def allow_request(self,request,view):
# remote_addr = request.META.get('REMOTE_ADDR')
# print(remote_addr)
# import time
# ctime=time.time()
#
# if remote_addr not in VISIT_RECORD:
# VISIT_RECORD[remote_addr]=[ctime,]
# return True
#
# history=VISIT_RECORD.get(remote_addr)
# self.history=history
#
# while history and history[-1]<ctime-60:
# history.pop()
#
# if len(history)<3:
# history.insert(0,ctime)
# return True
# else:
# return False
#
# def wait(self):
# import time
# ctime=time.time()
# return 60-(ctime-self.history[-1]) from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle): scope="visit_rate"
def get_cache_key(self, request, view): return self.get_ident(request)
utils.py
from django.shortcuts import render, HttpResponse from django.views import View
from .models import *
import json
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response # 为queryset,model 对象 做序列化得
# class PublishSerializers(serializers.Serializer):
# name = serializers.CharField()
# email = serializers.CharField() 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='detailpublish', # 别名 含正则表达式
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 class AuthorModelSerializers(serializers.ModelSerializer):
class Meta:
model = Author
fields = "__all__"
serializer.py
from django.db import models # Create your models here. class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32) type_choices = ((1,"普通用户"),(2,"VIP"),(3,"SVIP"))
user_type = models.IntegerField(choices=type_choices,default=1) class Token(models.Model):
user = models.OneToOneField("User")
token = models.CharField(max_length=128) def __str__(self):
return self.token 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
models.py
from django.shortcuts import render,HttpResponse # Create your views here. from django.views import View
from .models import *
import json
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response from app01.serializer 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() from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser
"""
默认得是 JSONParser FormParser MultiPartParser
"""
# Book
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
class MyPageNumberPagination(PageNumberPagination):
page_size = 1
page_query_param = "page"
page_size_query_param = "size"
max_page_size = 2 # 限制 size 得大小 不能超过多少!!
# # http://127.0.0.1:8000/books/?page=2&size=2 class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = 1
# limit_query_param =
# http://127.0.0.1:8000/books/?limit=2&offset=2 # 偏移 class BookView(APIView):
# authentication_classes = [TokenAuth] parser_classes = [JSONParser,FormParser] def get(self,request): print("user:--->", request.user)
print(request.auth) book_list = Book.objects.all() # 分页 page_size 配置 setting 全局得 单独怎么设置? 写个类
# from rest_framework.pagination import PageNumberPagination # pnp = PageNumberPagination()
# pnp = MyPageNumberPagination()
pnp = MyLimitOffsetPagination() books_page = pnp.paginate_queryset(book_list,request,self) # bs = BookModelSerializers(book_list,many=True,context={'request': request})
bs = BookModelSerializers(books_page,many=True,context={'request': request}) # return HttpResponse(bs.data)
return Response(bs.data) def post(self,request): print('data:--->', request.data,type(request.data)) # post 请求的数据
bs = BookModelSerializers(data=request.data,context={'request': request})
if bs.is_valid():
bs.save() # create 方法
print(bs.validated_data)
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)
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() # Author
# 逻辑复用
# 三种方法 ######################### mixin类编写视图 ############################## # from rest_framework import mixins, generics
#
# class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
# queryset = Author.objects.all()
# serializer_class = AuthorModelSerializers
#
# def get(self,request,*args,**kwargs):
# return self.list(request,*args,**kwargs)
#
# def post(self,request,*args,**kwargs):
# return self.create(self, request, *args, **kwargs)
#
#
# class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
# queryset = Author.objects.all()
# serializer_class = AuthorModelSerializers
#
# def get(self,request,pk,*args,**kwargs):
# return self.retrieve(request,pk,*args,**kwargs)
#
# def delete(self,request,*args,**kwargs):
# return self.destroy(request,*args,**kwargs)
#
# def put(self,request,*args,**kwargs):
# return self.update(request,*args,**kwargs) ######################### 使用得通用得基于类得视图 ############################## # from rest_framework import mixins, generics
#
# class AuthorView(generics.ListCreateAPIView):
# queryset = Author.objects.all()
# serializer_class = AuthorModelSerializers
#
#
# class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
# queryset = Author.objects.all()
# serializer_class = AuthorModelSerializers ######################### viewsets.ModelViewSet ##############################
# url 需要是一趟线 走一个视图类
# url 中 利用参数 来指定 什么方式 用什么方法 执行
from .utils import TokenAuth,SVIPPermission
from rest_framework import viewsets class VisitRateThrottle(object):
def allow_request(self,request,view):
# 要求访问站点得频率不能超过每分钟20次
if 1:
# 每次来 存下来 比对一下,间隔多久 超过一分钟
# IP, 请求首行(request.method request.path)
# 请求头(request.meta) 请求体(request.body)
print("meta:----->",request.META)
print(request.META.get("REMOTE_ADDR")) # 客户端得ip 这里面 你要保存什么 ip 时间 记录下来;
# 频率 限制 实现 功能!!! return True
else:
return False from rest_framework.response import Response class AuthorModelView(viewsets.ModelViewSet): # authentication_classes = [TokenAuth,]
# permission_classes = [SVIPPermission,] 取配全局八
# throttle_classes = [VisitRateThrottle] queryset = Author.objects.all()
serializer_class = AuthorModelSerializers pagination_class = MyPageNumberPagination # 完美! ok # 类得继承 , 表示形式 需求 展示 数据 ,覆盖方法 单独写 类得继承 可重写 覆盖
#
# def list(self,request,*args,**kwargs):
# pass # ------------------------------------------------------ def get_random_str(user):
import hashlib,time
ctime=str(time.time()) md5=hashlib.md5(bytes(user,encoding="utf8"))
md5.update(bytes(ctime,encoding="utf8")) return md5.hexdigest() class LoginView(APIView):
authentication_classes = []
def post(self,request):
name = request.data.get("name")
pwd = request.data.get("pwd")
user = User.objects.filter(name=name,pwd=pwd).first()
res = {"state_code":1000,"msg":None}
if user:
random_str = get_random_str(user.name)
token = Token.objects.update_or_create(user=user,defaults={"token":random_str})
res['token'] = random_str
else:
res["status_code"] = 1001 # 错误状态码
res['msg'] = "用户名或密码错误" import json
return Response(json.dumps(res,ensure_ascii=False))
views.py
八、渲染器、版本
配置:
1.添加配置
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer','rest_framework.renderers.BrowsableAPIRenderer'],
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version', # 参数
'DEFAULT_VERSION': 'v1', # 默认版本
}
2.设置路由:
luffycity/urls.py
from django.conf.urls import url,include
from django.contrib import admin urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^api/(?P<version>\w+)/', include('api.urls')),
]
api/urls.py
from django.conf.urls import url
from api.views import course urlpatterns = [
url(r'^course/$', course.CourseView.as_view()),
]
3.获取版本
request.version 获取版本
Django - rest - framework - 下的更多相关文章
- 6- vue django restful framework 打造生鲜超市 -完成商品列表页(下)
Vue+Django REST framework实战 搭建一个前后端分离的生鲜超市网站 Django rtf 完成 商品列表页下 drf中的request和response drf对于django的 ...
- 使用django rest framework
django 刚接触,想做一些restful api , google了一下,发现有现成的框架.Django REST framework. 对使用做下记录: 安装 从http://django-re ...
- django rest framework 入门
django rest framework 入门1-序列化 Serialization 分类: Python 2013-01-22 22:24 11528人阅读 评论(0) 收藏 举报 djangop ...
- django rest framework
Django-Rest-Framework 教程: 4. 验证和权限 作者: Desmond Chen, 发布日期: 2014-06-01, 修改日期: 2014-06-02 到目前为止, 我们的AP ...
- Django REST Framework学习——Android使用REST方法访问Diango
本文更应该叫做Android如何模拟浏览器访问Django服务器后台. 环境为: Android通过HttpClient访问服务器,从Django中获取json数据,解析显示在UI界面上. 问题为: ...
- 用Django Rest Framework和AngularJS开始你的项目
Reference: http://blog.csdn.net/seele52/article/details/14105445 译序:虽然本文号称是"hello world式的教程&quo ...
- Django REST FrameWork中文教程2:请求和响应
从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...
- Django REST framework+Vue 打造生鲜超市(三)
四.xadmin后台管理 4.1.xadmin添加富文本插件 (1)xadmin/plugins文件夹下新建文件ueditor.py 代码如下: # xadmin/plugins/ueditor.py ...
- Django REST framework+Vue 打造生鲜超市(四)
五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...
随机推荐
- js学习之--Bootstrap Modals(模态框)
http://www.runoob.com/bootstrap/bootstrap-v2-modal-plugin.html http://outofmemory.cn/bootstrap/tutor ...
- 转载: erlang连接mysql
转自:http://blog.csdn.net/flyinmind/article/details/7740540 项目中用到erlang,同时也用到mysql.惯例,google. 但是,按照网上说 ...
- 解决error: Your local changes to the following files would be overwritten by merge
在项目里我们一般都会把自己第一次提交的配置文件忽略本地跟踪 1 [Sun@webserver2 demo]$ git update-index --assume-unchanged <filen ...
- oracle查询一个用户下的所有表
select table_name from all_tables where owner_name=upper('scott'); 用户名一定要大写//
- why pure virtual function has definition 为什么可以在基类中实现纯虚函数
看了会音频,无意搜到一个frameworks/base/include/utils/Flattenable.h : virtual ~Flattenable() = 0; 所以查了下“纯虚函数定义实现 ...
- C/C++ 头文件以及库的搜索路径
关键点: 1. #include <...> 不会搜索当前目录 2. 使用 -I 参数指定的头文件路径仅次于 搜索当前路径. 3. gcc -E -v 可以输出头文件路径搜索过程 C++编 ...
- oracle_存储过程_有参数_获取部门装置层级树
create or replace procedure P_UTIL_TREE(P_APPL_NAME in VARCHAR2, P_HIERARCHY_TYP in VARCHAR2, TREETY ...
- Linux环境下$开头的相关变量的含义
$0 这个程式的执行名字$n 这个程式的第n个参数值,n=1..9$* 这个程式的所有参数,此选项参数可超过9个.$# 这个程式的参数个数$$ 这个程式的PID(脚本运行的当前进程ID号)$! 执行上 ...
- RIDE指定log和report的输出目录
在命令行中,输入 pybot --help就可以看到他支持的所以命令和相关的介绍 我们可以看到outputdir这个命令,就是来知道report和log的输出目录的 如果你是在命令行中,那么直接后面跟 ...
- C语言分支结构之if else语句
前面我们看到的代码都是顺序执行的,也就是先执行第一条语句,然后是第二条.第三条……一直到最后一条语句,这称为顺序结构. 但是对于很多情况,顺序结构的代码是远远不够的,比如一个程序限制了只能成年人使用, ...