django配置文件
1.根路径:
BASE_DIR = Path(__file__).resolve().parent.parent
2.django加密使用-秘钥
SECRET_KEY = 'django-insecure-ov_#*#-o&svxjrtxe1op*%3wfobg)+)&k%1u$l&4!00k5*9eq$'
3.出现BUG时前端的显示
DEBUG = True 抛异常在浏览器中可以看到 路径不存在也会显示有哪些路径 项目调试阶段使用
DEBUG = False 前端显示的时错误状态码
4.允许项目部署的地址-项目上线服务器地址 当DEBUG = False必须添加 否则报错
ALLOWED_HOSTS = []
5.django中的APP--django大而全是因提供了很多app
INSTALLED_APPS = [
'django.contrib.admin', # 后台管理
'django.contrib.auth', # 权限-6个表
'django.contrib.contenttypes',
'django.contrib.sessions', # session相关
'django.contrib.messages', # 消息框架
'django.contrib.staticfiles',] # 静态文件
6.django中间件-当针对在路由匹配执行视图函数前要做一些操作时可以在中间件中操作
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', # session相关
'django.middleware.common.CommonMiddleware', # 路由匹配时 未/的二次匹配
'django.middleware.csrf.CsrfViewMiddleware', # csrf认证
'django.contrib.auth.middleware.AuthenticationMiddleware', # auth认证
'django.contrib.messages.middleware.MessageMiddleware', # 消息框架
'django.middleware.clickjacking.XFrameOptionsMiddleware',]
7.路由py文件的路径-根据拖动到不同位置会变化(解释器操作的)
ROOT_URLCONF = 'drf08.urls'
8.HTML文件(模板操作)-根据django版本不同需要修改DIRS的格式
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]},]
9.项目上线,uwsgi运行这个application,测试阶段使用manage.py 运行项目
WSGI_APPLICATION = 'drf08.wsgi.application'
10.数据库配置--可配多个数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',}}
11.国际化操作
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
12.静态文件接口前缀--可做动态解析(防止前缀发生改变)
STATIC_URL = '/static/'
13.自增主键-BigAutoField
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
内置的三大认证
1.内置认证
1.基类---BaseAuthentication
继承它需要重写authenticate方法--不然直接抛异常
class UserAuthenticate(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token') # 自己设计的放在那里
user_token = UserToken.objects.filter(token=token).first()
if not user_token:
raise AuthenticationFailed('你未登录请先登录')
return (user_token.user, token)
2.SessionAuthentication---继承BaseAuthentication
当用前端携带cookie过来时 经过session中间件时 如果用户登录就可以拿到当前登录用户
通过反射获取user 将当前用户返回
def authenticate(self, request):
user = getattr(request._request, 'user', None)
if not user or not user.is_active:
return None
self.enforce_csrf(request)
return (user, None)
3.RemoteUserAuthentication---继承BaseAuthentication
当用户登录后
从META(包含所有的HTTP首部)中获取当前用户 返回
def authenticate(self, request):
user = authenticate(request=request, remote_user=request.META.get(self.header))
if user and user.is_active:
return (user, None)
4.TokenAuthentication---继承BaseAuthentication
从META中拿到HTTP_HEADER_ENCODING --进行分割判断---抛出异常
2.内置权限
1.基类---BasePermission 继承它需要重写has_permission方法
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
class UserPermission(BasePermission):
def has_permission(self, request, view):
if request.user.permission.name == '超级用户':
return True
return False
2.AllowAny---继承BasePermission--写了has_permission方法---所有
def has_permission(self, request, view):
return True
3.IsAdminUser---继承BasePermission--写了has_permission方法--转为布尔值
auth的user表中is_staff字段是否为True,对后台管理有没有权限
def has_permission(self, request, view):
return bool(request.user and request.user.is_staff)
4.IsAuthenticated---继承BasePermission--写了has_permission方法
是否登录,登录了才有权限
认证类,如果登录了,返回(当前登录用户,None), 如果没有登录返回 None
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
3.内置频率
1.基类---BaseThrottle---继承它需重写allow_request方法---否则抛异常
def allow_request(self, request, view):
"""
Return `True` if the request should be allowed, `False` otherwise.
"""
raise NotImplementedError('.allow_request() must be overridden')
2.SimpleRateThrottle---继承了BaseThrottle---重写allow_request方法
继承它重写get_cache_key方法---少写代码
def allow_request(self, request, view):
if self.rate is None:
return True
self.key = self.get_cache_key(request, view)
if self.key is None:
return True
self.history = self.cache.get(self.key, [])
self.now = self.timer()
while self.history and self.history[-1] <= self.now - self.duration:
self.history.pop()
if len(self.history) >= self.num_requests:
return self.throttle_failure()
return self.throttle_success()
3.AnonRateThrottle---继承SimpleRateThrottle---重写了get_cache_key方法
def get_cache_key(self, request, view):
if request.user and request.user.is_authenticated:
return None
return self.cache_format % {
'scope': self.scope,
'ident': self.get_ident(request)
}
如果用户认证了---返回限制设置--如果要以ip作为限制
配置文件中配置
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m',
}
4.UserRateThrottle---继承SimpleRateThrottle---重写了get_cache_key方法
def get_cache_key(self, request, view):
if request.user and request.user.is_authenticated:
ident = request.user.pk
else:
ident = self.get_ident(request)
return self.cache_format % {
'scope': self.scope,
'ident': ident
}
如果用户认证了---返回限制设置--如果要以用户id作为限制
配置文件中配置
'DEFAULT_THROTTLE_RATES': {
'user': '3/m',
}
过滤类
1.第三方过滤类---django_filters---DjangoFilterBackend
1.第三方模块下载:pip install django_filters
2.导入from django_filters.rest_framework import DjangoFilterBackend
3.局部配置及筛选条件
filter_backends = [DjangoFilterBackend, ]
filterset_fields = ['name', 'publish']
4.网址:http://127.0.0.1:8000/books/?name=追风筝的人&publish=北方出版社
注:缺点:只能精准查询无法模糊查询
2.自定义过滤类
1.自定义类继承BaseFilterBackend
重写filter_queryset方法
from rest_framework.filters import BaseFilterBackend
class BookFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
name = request.query_params.get('name')
publish = request.query_params.get('publish')
if name and publish:
queryset = queryset.filter(name__icontains=name, publish__icontains=publish)
return queryset
return None
2.局部配置
filter_backends = [BookFilter, ]
3.网址:http://127.0.0.1:8000/books/?name=卖报纸&publish=南方出 and关系模糊查询
全局异常处理
1.在APIView的dispatch方法中进行了全局异常捕获
2.异常捕获执行handle_exception方法
try:
......
except Exception as exc:
response = self.handle_exception(exc)
3.handle_exception方法--只对drf中的异常进行了捕获
def handle_exception(self, exc):
if isinstance(exc, (exceptions.NotAuthenticated,
exceptions.AuthenticationFailed)):
auth_header = self.get_authenticate_header(self.request)
if auth_header:
exc.auth_header = auth_header
else:
exc.status_code = status.HTTP_403_FORBIDDEN
exception_handler = self.get_exception_handler()
context = self.get_exception_handler_context()
response = exception_handler(exc, context)
if response is None:
self.raise_uncaught_exception(exc)
response.exception = True
return response
4.对所有异常进行捕获并返回统一格式
自己一个函数
def book_handle_exception(exc, context):
request = context.get('request')
print(exc)
print(context)
try:
username = request.user.username
except:
username = '您没有登录'
now_time = time.time()
path = request.path
method = request.method
print(f'{username}在{now_time}通过{method}请求访问了{path}出现了{str(exc)}的错误')
response = exception_handler(exc, context)
if response:
return Response({'code': 888, 'msg': 'drf错误, 错误原因:%s' % response.data.get('detail', '未知错误')})
return Response({'code': 999, 'msg': 'drf错误, 错误原因:%s' % exc})
接口文档
1.接口文档内容:
请求地址
请求方式
支持的编码格式
请求参数
返回格式示例
2.写的方式
2.1 直接用word或者md
2.2 使用接口文档平台,在接口文档平台录入--Yapi(百度开源 可以自己搭建)
第三方平台--收费
2.3 项目自动生成:swagger、coreapi
1.下载:pip install coreapi
2. 路由中配置:
from rest_framework.documentation import include_docs_urls
urlpatterns = [
path('docs/', include_docs_urls(title='站点页面标题'))
]
3.在视图类中加注释 在序列化类上写help_text
4.配置文件中配置:
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
作业
1.自定义一个过滤类,实现可以通过图书名或作者模糊匹配--使用django-filter实现模糊匹配
from django_filters.rest_framework import DjangoFilterBackend
class MyFilter(DjangoFilterBackend):
def filter_queryset(self, request, queryset, view):
name = request.query_params.get('name')
publish = request.query_params.get('publish')
if name and publish:
queryset = queryset.filter(Q(name__icontains=name)|Q(publish__icontains=publish))
return queryset
elif name:
queryset = queryset.filter(name__icontains=name)
return queryset
elif publish:
queryset = queryset.filter(publish__icontains=publish)
return queryset
return queryset
2.编写一个全局异常处理,让它生效
# from rest_framework.response import Response
# import time
# from rest_framework.views import exception_handler
#
#
# def book_handle_exception(exc, context):
# request = context.get('request')
# print(exc)
# print(context)
# try:
# username = request.user.username
# except:
# username = '您没有登录'
# now_time = time.time()
# path = request.path
# method = request.method
# print(f'{username}在{now_time}通过{method}请求访问了{path}出现了{str(exc)}的错误')
# response = exception_handler(exc, context)
# if response:
# return Response({'code': 888, 'msg': 'drf错误, 错误原因:%s' % response.data.get('detail', '未知错误')})
# return Response({'code': 999, 'msg': 'drf错误, 错误原因:%s' % exc})
标签:return,self,09,request,django,---,user,drf
From: https://www.cnblogs.com/040714zq/p/16782758.html