FBV 和 CBV

CBV 通过函数调用方法
FBV 通过类调用方法
    其本质上都是 CBV
但是 FBV 内部封装了关于 method 的方法,由于基本上都是前端的请求,所有像GET,POST等方法用的频繁,
而CBV将这些方法封装了起来,使得开发时更便捷了许多,所以CBV更适合写接口

######  标准的  ######
2.1 fbv方式请求的过程

用户发送url请求,Django会依次遍历路由映射表中的所有记录,一旦路由映射表其中的一条匹配成功了,
就执行视图函数中对应的函数名,这是fbv的执行流程

2.2 cbv方式请求的过程

当服务端使用cbv模式的时候,用户发给服务端的请求包含url和method,这两个信息都是字符串类型

服务端通过路由映射表匹配成功后会自动去找dispatch方法,然后Django会通过dispatch反射的方式找到类中对应的方法并执行

类中的方法执行完毕之后,会把客户端想要的数据返回给dispatch方法,由dispatch方法把数据返回经客户端

一:下载

pip install djangorestframewrok

二:Views

    # restframework 常用的类
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response

写法1:

--
from rest_framework import serializers
(1)和 models 表中的字段对应 (使用模块:serializers.Serializer)
(2)全部字段直接写(使用模块:serializers.ModelSerializer)
class Meta:
model = models.Book
fields = '__all__'
(3)使用时需要调用 BookModelSerializers(queryset/data,many=True/False)
注:当需要返回一个 queryset 的时候必须加 many=True 这个参数,单条数据则不用
--
----------Url----------
from app01 import views
re_path('book/$',views.BookView.as_view()) ----------View----------
from rest_framework import serializers
class BookModelSerializers(serializers.ModelSerializer):
title = serializers.CharField()
price = serializers.CharField()
publish = serializers.CharField() from rest_framework.views import APIView
from rest_framework.views import Response # 更新操作:
def put(self,request,pk):
shop = models.Shop.objects.filter(pk=pk).first()
bs = ShopSerializers(shop,data=request.data)
if bs.is_valid(): # 判断数据是否有误
print('bs: ',bs)
bs.save() # 相当于调用了 updata方法
return Response(bs.data) # 返回 数据
else:
return Response(bs.errors) # 添加操作:
ps = PublishSerializers(data=request.data)
if ps.is_valid():
ps.save() # create # 查询操作:
class BookView(APIView):
def get(self,request):
book_list = models.Book.objects.all()
serializers = BookModelSerializers(book_list,many=True)
return Response(serializers.data) # 删除操作:
def delete(self,request,pk):
models.Shop.objects.filter(pk=pk).delete()
return Response()

写法2:

--
(a)
(1)mixins 模块中有 List,Create,Put...方法可以直接使用
(2)generics 主要作用还是调用 APIView 中的
-- ----------Url----------
from app01 import views
re_path('book/$',views.BookView.as_view()) ----------View (a)----------
from rest_framework import mixins
from rest_framework import generics
from rest_framework import serializers from rest_framework import serializers
class BookModelSerializers(serializers.ModelSerializer):
title = serializers.CharField()
price = serializers.CharField()
publish = serializers.CharField() class AuthorView(mixins.ListModelMixin,generics.GenericAPIView):
queryset = models.Author.objects.all() # 必须有的参数 :queryset
serializer_class = AuthorModelSerializers # 必须有的参数 :serializer_class def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs) --
(b)
(1)继承 generics.RetrieveUpdateDestroyAPIView
将上面的 mixins generics 全部封装成了一个模块
-- ----------View (b)---------- 比上面简单一点
class UserView(generics.RetrieveUpdateDestroyAPIView):
queryset = models.User.objects.all()
serializer_class = UserModelSerializers

写法三:

--
(1) as_view({参数})
中传的参数是必须的,参数的名称还是固定的,
可根据需求来限定哪个url配定哪个参数
(2) view 中 的变量名也是固定的,不能改变,
当执行到某个父类的方法的时候,就会需要这两个参数
queryset -- queryset
serializer_class
--
----------Url----------
from app01 import views
re_path('book/$', views.Book.as_view({'get': 'list', 'post': 'create'})),
re_path('book/(?P<pk>\d+)/$', views.Book.as_view({'get': 'retrieve', 'put': 'update','delete':'destroy'})), ----------View---------- from rest_framework import viewsets class Book(viewsets.ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializers

四:认证组件

----------  View(局部认证)  ----------
--
(1) BaseAuthentication 模块中 有俩个方法(authenticate , authenticate_header)
注:这俩个方法也是固定名字,两个必须写上,一个都不能少,否则报错 !
模块中这两个方法都是返回空的,但是执行的时候当前函数就将
两个方法覆盖了,也就是少些一个 authenticate_header
(2) 创建一个 返回 随机字符的 token (3) update_or_create -- 如果有就更新,如果没有就创建 -- # 认证 组件
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from app01 import models
class TokenAuth(BaseAuthentication): # 这个方法直接写在一个文件中
def authenticate(self,request):
token = request.GET.get('token') # 获取 token
token_obj = models.Token.objects.filter(token=token).first() # 验证 token 是否匹配
if not token_obj:
raise exceptions.AuthenticationFailed('验证失败')
else:
return token_obj.user.name,token_obj.token # 返回一个 登陆校验判断 的随机字符串
def get_random_str(user):
import hashlib,time
ctime = str(time.time()) # 当前时间字符串 md5 = hashlib.md5(bytes(user,encoding='utf8')) # md5 加密,加盐
md5.update(bytes(ctime,encoding='utf8')) # 将字符串进行拼接 #md5.digest() 二进制
#md5.hexdigest() 十六进制
return md5.hexdigest() # 返回一个 十六进制 的加密随机字符 # 登陆验证
class LoginView(APIView):
authentication_classes = [TokenAuth]
def post(self,request):
name = request.data.get('name') # 获取用户名
pwd = request.data.get('pwd') # 获取密码
user = models.User.objects.filter(name=name,pwd=pwd).first() # 数据库校验
res = {'code':0,'msg':None}
if user:
random_str = get_random_str(user.name)
token = models.Token.objects.update_or_create(user=user,defaults={'token':random_str}) # 在数据库生成 token
res['token'] = random_str
res['code'] = 1
res['msg'] = '验证成功'
else:
res['msg'] = '验证失败'
import json
return Response(json.dumps(res)) ---------- View(全局认证) ---------- (1) settings 中配置 认证组件位置: # 全局认证组件
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",]
} (2) 这样就不用写 authentication_classes = [TokenAuth]
(3) 如果哪个方法不需要认证的话 只需要 authentication_classes = [] 将列表设为空

五:权限组件

# 权限组件
class SvipPermission(object):  # 这个方法直接写在一个文件中
message = "只有超级用户才能访问"
def has_permission(self,request,view):
username = request.user
user_type = models.User.objects.filter(name=username).first().user_type
if user_type == 3:
return True # 返回True 则验证通过
else:
return False # 返回False 则验证不通过 # 只需类下面添加
permission_classes = [SvipPermission] # 权限组件 -- 局部
# 全局认证
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES":['app01.utils.SvipPermission'], # 全局权限组件
}

六:解析器 (用于将解析字符格式)

from rest_framework.parsers import JSONParser,FormParser
parser_classes = [JSONParser, FormParser] # 局部 (用于将解析字符格式)

七:频率组件:

- 自定义:

# 定义一个频率认证类 - 之后在视图配置
import time
from rest_framework.throttling import BaseThrottle class MyThrottle(BaseThrottle):
visited_record = {} def __init__(self):
self.history = None def allow_request(self, request, my_cbv):
# 这个my_cbv是源码中传的我们的视图类,这里我们也要传进去
# print(self.get_ident(request)) # 可以获取本次请求的ip
ip = request.META.get("REMOTE_ADDR")
if ip not in self.visited_record:
self.visited_record[ip] = [] current_time = time.time()
history = self.visited_record[ip]
self.history = history
print(history) while history and current_time - history[-1] > 60: # 把大于60秒的时间都删掉
history.pop() if len(history) > 2: # 第三次访问,列表中只有2个值,也满足条件
return False
history.insert(0, current_time)
return True def wait(self):
"""
用于返回还剩多少时间访问; 本次访问时间:9:50:55
[09:50:30, 09:50:20, 09:50:10] 剩余 60 - (9:50:55 - 09:50:10)秒才能访问
:return:
"""
c_time = time.time()
return 60 - (c_time - self.history[-1]) #### 局部使用 ####
from rest_framework import generics
from rest_framework import mixins
from app01.utils.frequency import MyThrottle
class ListView(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):
throttle_classes = [MyThrottle]
def get(self, request, *args, **kwargs):
return Response('ok') #### 全局使用 ####
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
),
'DEFAULT_THROTTLE_CLASSES': (
'app01.utils.frequency.MyThrottle',
),
}

- 内置

####  定义类  ####
from rest_framework.throttling import SimpleRateThrottle class MyThrottle(SimpleRateThrottle): scope = "visit_rate" # 这个值决定了在配置时使用那个变量描述限制的频率 def get_cache_key(self, request, view): # 这个方法也是必须要有
return self.get_ident(request) #### 只能在全局使用 ####
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'app01.utils.throttle_class.MyThrottle',
),
"DEFAULT_THROTTLE_RATES": {
"visit_rate": "10/m",
# 这个参数就是频率类中定义的那个参数scope, 其中第一个数字10表示10次,后面的m表示一分钟,还有s,一秒, h, 一小时, d, 一天
}
}

八:分页器 -- 用于 restframework 内置的调试页面

# 要使用 restframework 自带的调试数据网页 需要在 settings 中配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'rest_framework',  # 配置 restframework 组件
] # 分页器
from rest_framework.pagination import PageNumberPagination
class BookPageNumberPagination(PageNumberPagination):
page_size = 1 # 每页显示个数
page_query_param = 'page'
page_size_query_param = 'size' # 修改当前页显示个数
#max_page_size = 2 # 每页显示个数限制 class BookView(APIView):
def get(self,request):
book_list = models.Book.objects.all() # 分页器
pnp = BookPageNumberPagination()
book_page = pnp.paginate_queryset(book_list,request,self) bs = BookModelSerializers(book_page,many=True,context={'request': request})
return Response(bs.data)

python - Django - restframework 简单使用 和 组件的更多相关文章

  1. Python django实现简单的邮件系统发送邮件功能

    Python django实现简单的邮件系统发送邮件功能 本文实例讲述了Python django实现简单的邮件系统发送邮件功能. django邮件系统 Django发送邮件官方中文文档 总结如下: ...

  2. Python Django 实现简单注册功能

    Python Django 实现简单注册功能 项目创建略,可参考前期文档介绍. 目录结构如下 编辑views.py from django.shortcuts import render # Crea ...

  3. Python Django 之 简单入门

    一.下载Django并安装 1.下载Django 2.安装 二.新建Django project 1.使用django-admin新建mysite 项目 django-admin startproje ...

  4. python Django rest-framework 序列化步骤

    django-rest-framework,是一套基于Django 的 REST 框架,是一个强大灵活的构建 Web API 的工具包.本文介绍一下 django-rest-framework 的简单 ...

  5. pythonのdjango Form简单应用。

    Form表单有两种应用场景: 1.生成HTML标签. 2.验证输入内容. 如果我们在django程序中使用form时,需要在views中导入form模块 from django import form ...

  6. python Django rest-framework 创建序列化工程步骤

    11创建项目 2创建应用 3stting添加应用(apps)-添加制定数据库-修改显示汉字(zh-hans)-上海时区(Asia/Shanghai) 4主路由添加子路由 5应用里创建子路由 6创建数据 ...

  7. pythonのdjango CSRF简单使用

    一.简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功 ...

  8. Python - Django - Cookie 简单用法

    home.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  9. django restframework 简单总结

    官方文档:http://www.django-rest-framework.org/ model.py class Snippet(models.Model): created = models.Da ...

随机推荐

  1. c++连接打印机(转载)

    Visual C++6.0是开发Windows应用程序的强大工具,但是要通过它实现程序的打印功能,一直是初学者的一个难点,经常有朋友询问如何在VC中实现打印功能,他们往往感到在MFC提供的框架内实现这 ...

  2. 【C++札记】实现C++的string类

    C++有了string类使得操作字符串变得很方便.有关string类,面试过程中也经常问到的就是自己实现一个sring类.下边实现个String类供大家参考: String.h #pragma onc ...

  3. 魔术方法之__call、__callStatic

    1.__call() 作用,当调用不存在的方法时,会调用该方法.实际应用,当程序调用不存在的方法时,意外导致程序终止. .或者当你调用了受保护的或者是私人的方法时,也会自动调用__call方法 结果: ...

  4. Django框架之DRF 基于mixins来封装的视图

    基础视图 示例环境搭建:新建一个Django项目,连接Mysql数据库,配置路由.视图函数.序列化单独创建py文件 # 配置路由 from django.conf.urls import url fr ...

  5. Sql CLR创建一个简单的表值函数

    1.创建面目: 2. 添加函数代码: using System; using System.Data.Sql; using Microsoft.SqlServer.Server; using Syst ...

  6. go 读取BMP文件头二进制读取

    BMP文件头定义: WORD 两个字节 16bit DWORD 四个字节 32bit package main import ( "encoding/binary" "f ...

  7. 贴一个markdown语法,mweb自带的说明

    Markdown 语法和 MWeb 写作使用说明 Markdown 的设计哲学 Markdown 的目標是實現「易讀易寫」.不過最需要強調的便是它的可讀性.一份使用 Markdown 格式撰寫的文件應 ...

  8. js(es6)数组去重

    // 利用set.reduce.filter去重 // Set function getSetArr(arr) { return [...new Set(arr)] } console.log(get ...

  9. [转]关于ORA-00979 不是 GROUP BY 表达式错误的解释

    转自:https://www.cnblogs.com/vigarbuaa/archive/2012/06/25/2561225.html ORA-00979 不是 GROUP BY 表达式”这个错误, ...

  10. PHP/Python---百钱百鸡简单实现及优化

    公鸡5块钱一只,母鸡3块钱一只,小鸡一块钱3只,用100块钱买一百只鸡,问公鸡,母鸡,小鸡各要买多少只? 今天看到这题很简单 ,但是随手写出来后发现不是最优的