认证权限频率
-auto_now_add=True
-auto_now=True
-写一个登录接口---》保存用户登录状态
-session:request.SESSION['name']='lqz'
-签发阶段:做三件事:
1 生成一个随机字符串
2 django-session表中插入记录
3 把随机字符串以cookie形式返回给前端(存在浏览器的cookie中)
-认证阶段:前端自动携带cookie到后端:sessionid:随机字符串
-django.contrib.sessions.middleware.SessionMiddleware
-自己写的,本质原理也是session的认证机制
-session是存储在服务端的键值对
-认证类:接口需要登录后才能访问
-1 写一个类,继承BaseAuthentication
-2 重写authenticate
-3 在方法中做认证---》取出前端传入的随机字符串--》去表中查出当前用户
-4 返回两个值 user,token
-5 后续的request.user就能拿到当前登录用户
-6 使用:局部,全局
-1 写一个类,继承BasePermission
-2 重写has_permission
-3 在方法中做权限控制---》满足权限返回true,不满足返回false
-4 使用:局部,全局
-request.META.get('REMOTE_ADDR') 客户端ip地址
'''
'DEFAULT_THROTTLE_RATES': {
'drf_day08': '3/m', # 一分钟访问三次
},
'''
-配置类属性
filter_backends = [OrderingFilter]
ordering_fields=['id','user_type']
session的认证机制图解
保存用户登录的状态:使用session, request.SESSION['name']='lin'
1.生成一个随机字符串
2.把数据存到django-session表中
3.把随机字符串以cookie的形式返回给前端
以上三件事是django的中间件做的
django.contrib.sessions.middleware.SessionMiddleware
1 过滤
pip install django==3.2.12
pip install django-filter
-使用方式:三种
-方式一:内置的
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['name', 'price']
-方式二:第三方
filter_backends = [DjangoFilterBackend]
filterset_fields=['name','price']
-方式三:自定义--完全自己控制
filter_backends = [MyFilter]
代码演练
from rest_framework.filters import BaseFilterBackend
from django.db.models import Q
class MyFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
search_param = request.query_params.get('name')
price = request.query_params.get('price')
if search_param and price:
queryset = queryset.filter(name__contains=search_param,price=price)
return queryset
1.1 继承APIView写过滤和排序
class BookView(ViewSetMixin, APIView):
def list(self, request, *args, **kwargs):
print('asfdasdf')
name = request.query_params.get('name')
book_list = Book.objects.all().filter(name__contains=name)
ser = BookSerializer(instance=book_list, many=True)
return Response(ser.data)
1.2 继承GenericAPIView写过滤类,可以写多个
-写多个,他们是从左往右,依次执行
-大原则,配置多个过滤类的时候,第一个放尽量多个过滤掉数据
-配置多个:执行原理
-先执行第一个过滤类的:filter_queryset返回qs对象
-再执行第二个过滤类的filter_queryset,传入上一个返回的qs,过滤完返回qs对象
2 分页
只针对于 查询所有接口
-分页展现形式:
web:下一页,下一页
小程序,app:上拉加载更多
1.方式一:基本分页 PageNumberPagination
根据客户端请求自动对结果集进行分页,并返回包含分页信息的响应。
客户端可以通过查询参数来控制分页,例如 ?page=2 表示请求第二页的数据。
2.方式二:基本分页 LimitOffsetPagination
客户端可以通过添加 ?limit 和 offset 查询参数来控制分页。
是一种简单但有用的分页机制,适用于需要根据客户端需求精确控制分页结果的情况。
3.方式三:基本分页 CursorPagination
通过游标来获取分页数据。客户端可以使用 ?cursor 查询参数来控制游标位置,
以获取下一页或上一页的数据。它是一个强大的分页机制,适用于需要处理大量数据的 API,
特别是需要排序和过滤数据的情况。使用游标而不是页码来获取数据可以显著提高性能。
page.py
from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination, CursorPagination
class CommonPageNumberPagination(PageNumberPagination):
page_size = 3
page_query_param = 'page'
page_size_query_param = 'size'
max_page_size = 5
class CommonLimitOffsetPagination(LimitOffsetPagination):
default_limit = 2
limit_query_param = 'limit'
offset_query_param = 'offset'
max_limit = 5
class CommonCursorPagination(CursorPagination):
cursor_query_param = 'cursor'
page_size = 2
ordering = 'id'
视图类:继承GenericAPIView
from .page import CommonPageNumberPagination,CommonLimitOffsetPagination,CommonCursorPagination
class BookView(ViewSetMixin, ListAPIView):
authentication_classes=[]
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class =CommonCursorPagination
继承APIView也要实现
class BookView(ViewSetMixin, APIView):
authentication_classes=[]
def list(self,request,*args,**kwargs):
book_list=Book.objects.all()
pagination =CommonPageNumberPagination()
page=pagination.paginate_queryset(book_list,request)
ser=BookSerializer(instance=page,many=True)
return Response(ser.data)
3 异常处理
-认证类,认证不通过,抛异常,前端看到没有问题,只是返回了提示信息---》处理了drf的异常
1 写一个函数
def common_exception(exc, context):
res = exception_handler(exc, context)
if not res:
return Response({'code': 999, 'msg': '非drf错误,错误信息是:%s' % str(exc)})
else:
return Response({'code': 888, 'msg': 'drf错误,错误信息是:' + res.data.get('detail')})
2 配置文件配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.exceptions.common_exception',
}
4 DateField和DateTimeField
DateField、DateTimeField
auto_now_add=True
auto_now=True
`DateField` 和 `DateTimeField` 是 Django 中用于处理日期和日期时间的两个字段类型。
1. **DateField**:`DateField` 用于存储日期(年、月、日),不包括时间部分。通常用于需要记录事件、生日、日期等只关心日期部分的数据。在数据库中,它通常映射到日期字段,如 MySQL 中的 `DATE` 类型或 PostgreSQL 中的 `date` 类型。
例如,在 Django 模型中定义一个 `DateField`:
from django.db import models
class Event(models.Model):
event_date = models.DateField()
2. **DateTimeField**:`DateTimeField` 用于存储日期和时间,包括年、月、日、时、分、秒和毫秒。
它用于需要记录精确的时间戳或日期时间的数据。在数据库中,它通常映射到日期时间字段,
如 MySQL 中的 `DATETIME` 类型或 PostgreSQL 中的 `timestamp` 类型。
例如,在 Django 模型中定义一个 `DateTimeField`:
from django.db import models
class LogEntry(models.Model):
entry_datetime = models.DateTimeField()
在使用这两个字段类型时,您可以在 Django 模型中定义各种日期和日期时间属性,以满足您的需求。
这些字段允许您在应用程序中轻松存储和检索日期和日期时间数据。
5 auto_now_add和auto_now
在 Django 模型中,`auto_now_add` 和 `auto_now` 是两个用于自动管理日期和时间的属性,
通常用于 `DateTimeField` 字段。
1. **auto_now_add**:当一个对象被创建时,`auto_now_add` 属性会自动将该字段的值设置
为对象的创建时间。它只会在对象创建时设置一次,之后不会再修改。
这个属性通常用于记录对象的创建时间。
例如,以下代码将在对象创建时自动记录创建时间:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
2. **auto_now**:无论对象何时被保存,`auto_now` 属性都会自动将该字段的值设置为当前时间。
每次对象被保存时,这个字段的值都会被更新为当前时间。它通常用于记录对象的最后修改时间。
例如,以下代码将在对象每次被保存时自动更新修改时间:
from django.db import models
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
last_modified = models.DateTimeField(auto_now=True)
总之,`auto_now_add` 用于记录对象的创建时间,而 `auto_now` 用于记录对象的最后修改时间。
这两个属性使得在模型中管理日期时间字段变得非常方便,无需手动处理这些时间戳。