快速入手-基于DRF的过滤、分页、查询配置(十五)

1、过滤需要安装插件

pip install django-filter

2、注册

INSTALLED_APPS = [

"django.contrib.admin",

"django.contrib.auth",

"django.contrib.contenttypes",

"django.contrib.sessions",

"django.contrib.messages",

"django.contrib.staticfiles",

"rest_framework",

"corsheaders",

"app_drf01.apps.AppDrf01Config",

"api.apps.ApiConfig",

"rest_framework_simplejwt",

"rest_framework_simplejwt.token_blacklist",

"django-filters",

]

REST_FRAMEWORK = {

"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",

"PAGE_SIZE": 2,

"DEFAULT_AUTHENTICATION_CLASSES": (

"rest_framework_simplejwt.authentication.JWTAuthentication",

),

"DEFAULT_THROTTLE_CLASSES": [

"rest_framework.throttling.AnonRateThrottle", # 未认证用户

"rest_framework.throttling.UserRateThrottle", # 已认证用户

],

"DEFAULT_THROTTLE_RATES": { # 频率配置

"anon": "200/day", # 匿名用户每分钟最多访问 200 次

"user": "500/day", # 认证用户每分钟最多访问 500 次

},

#全局配置

"DEAFULT_FILTER_BACKENDS": ["django_filters.rest_framework.DjangoFilterBackend"],

}

完整代码

python 复制代码
from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-ws(9g7m^dty#ouzqdii*s^((+a33v@qn654gm0+b)_97)#sx-e"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rest_framework",
    "corsheaders",
    "app_drf01.apps.AppDrf01Config",
    "api.apps.ApiConfig",
    "rest_framework_simplejwt",
    "rest_framework_simplejwt.token_blacklist",
    "django_filters",
]

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
    "PAGE_SIZE": 2,
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ),
    # "DEFAULT_THROTTLE_CLASSES": [
    #     "rest_framework.throttling.AnonRateThrottle",  # 未认证用户
    #     "rest_framework.throttling.UserRateThrottle",  # 已认证用户
    # ],
    "DEFAULT_THROTTLE_RATES": {  # 频率配置
        "anon": "200/day",  # 匿名用户每分钟最多访问 200 次
        "user": "500/day",  # 认证用户每分钟最多访问 500 次
    },
    # "DEAFULT_FILTER_BACKENDS": ["django_filters.rest_framework.DjangoFilterBackend"],
}


MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "maker_drf.urls"
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

WSGI_APPLICATION = "maker_drf.wsgi.application"
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "python_demo",  # 数据库名称
        "USER": "root",  # 数据库用户名
        "PASSWORD": "1234567890",  # 数据库密码
        "HOST": "127.0.0.1",  # 数据库主机地址
        "PORT": "13306",  # 数据库端口
    }
}

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]


# 设置默认语言为中文
LANGUAGE_CODE = "zh-hans"  # 简体中文

# 设置默认时区
TIME_ZONE = "Asia/Shanghai"  # 上海时区

USE_I18N = True

USE_TZ = True

STATIC_URL = "static/"

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# 媒体文件的存储路径
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

# 媒体文件的访问 URL
MEDIA_URL = "/media/"

from datetime import timedelta

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),  # Access Token 的有效期
    "REFRESH_TOKEN_LIFETIME": timedelta(days=7),  # Refresh Token 的有效期
    "ROTATE_REFRESH_TOKENS": True,  # 刷新时是否生成新的 Refresh Token
    "BLACKLIST_AFTER_ROTATION": True,  # 是否在刷新后废弃旧的 Refresh Token
    "ALGORITHM": "HS256",  # 使用的加密算法
    "SIGNING_KEY": SECRET_KEY,  # 设置签名密钥
    "VERIFYING_KEY": None,  # 如果使用公钥算法,可以配置验证密钥
}


CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_HEADERS = [
    "accept",
    "accept-encoding",
    "authorization",
    "content-type",
    "dnt",
    "origin",
    "user-agent",
    "x-csrftoken",
    "x-requested-with",
]
CORS_ALLOW_METHODS = [
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
]

3、在对应的视图函数中添加(局部生效配置)

指定位置配置过滤

#filter_backends = [filters.DjangoFilterBackend] 指定视图中类部分生效,提前需要注释掉上边标红的全局配置,开启以下注释即可

filter_backends = [filters.DjangoFilterBackend]

filterset_fields = ["name", "gid", "id"] # 允许通过这些字段进行过滤

注意:在apifox测试每个字段的值必须要完全匹配才可以,否则数据找不到。

完整代码如下所示

python 复制代码
from django.shortcuts import render, HttpResponse
from rest_framework.response import Response
from rest_framework.decorators import action

from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import (
    ListModelMixin,
    CreateModelMixin,
    RetrieveModelMixin,
    UpdateModelMixin,
    DestroyModelMixin,
)
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers

from rest_framework.authentication import (
    BasicAuthentication,
    SessionAuthentication,
)
from rest_framework.permissions import (
    IsAuthenticated,
    AllowAny,
    IsAuthenticatedOrReadOnly,
)


from .models import *
from api.serializer import *
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
from django_filters import rest_framework as filters


# 这种写法实现所有的增删改查,不能够单独进行操作
# class Linkapi(ModelViewSet):
# 不仅可以实现所有的增删改查,而且可以单独也可以全部包含增删改查
class Linkapi(
    GenericViewSet,
    ListModelMixin,
    CreateModelMixin,
    RetrieveModelMixin,
    UpdateModelMixin,
    DestroyModelMixin,
):

    queryset = Link.objects.all()
    serializer_class = LinkSerializer
    # authentication_classes = [SessionAuthentication]
    # IsAuthenticated 授权登录后可以访问
    # IsAuthenticatedOrReadOnly  只允许查询
    permission_classes = [IsAuthenticatedOrReadOnly]
    # 限流局部配置UserRateThrottle   AnonRateThrottle
    throttle_classes = [UserRateThrottle, AnonRateThrottle]
    # 自定义分页
    pagination_class = MyPage
    # 指定位置配置过滤
    filter_backends = [filters.DjangoFilterBackend]
    filterset_fields = ["name", "gid", "id"]  # 允许通过这些字段进行过滤

    # 在原有的二级路由中自定义添加三级路由路径
    # 访问路径/api/linkapi/{pk}/login/
    @action(
        methods=["get", "POST"],
        detail=True,
        url_path="login",
    )
    def login(self, request, pk):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    # detail为false表示路径名格式应该为/api/linkapi/get_new_5/
    @action(
        methods=[
            "get",
        ],
        detail=False,
    )
    def get_new_2(self, request):
        obj = Link.objects.all().filter()[:2]
        serializer = self.get_serializer(instance=obj, many=True)
        return Response(serializer.data)

4、基于apifox测试

http://127.0.0.1:8000/api/linkapi/ 添加params相关参数(gid,name,id),另外size是之前分页的参数

后端日志记录:

01/Apr/2025 09:13:51\] "GET /api/linkapi/?size=10\&gid=2\&id=29\&name=%E6%B5%8B%E8%AF%952222eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQzNDY5NDY4LCJpYXQiOjE3NDM0NjkxNjgsImp0aSI6IjhlOTlhMjI2YjYyYjQyOWM4NzY3NjMxMTEzOWE3ZTE3IiwidXNlcl9pZCI6MX0.aH99SmrKbrae4pZmt6SCwkl95uJYbS3cUnIphpSKMHk HTTP/1.1" 200 471 5、代码下载 链接: https://pan.baidu.com/s/15COVJcs5XHZYzX5be6DaJQ?pwd=5p6e 提取码: 5p6e

相关推荐
<<10 小时前
基于Django的权限管理平台
后端·python·django
Jamesvalley10 小时前
【修复】Django收到请求报Json解析错误
django·json
凌叁儿16 小时前
从零开始搭建Django博客①--正式开始前的准备工作
python·django·sqlite
镰圈量化1 天前
Django 实现服务器主动给客户端发送消息的几种常见方式及其区别
服务器·django·sqlite
凌叁儿1 天前
从零开始搭建Django博客③--前端界面实现
前端·python·django
终身学习基地2 天前
第一篇:Django简介
后端·python·django
橘猫云计算机设计2 天前
django软件开发招聘数据分析与可视化系统设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
hadoop·spring boot·python·数据挖掘·数据分析·django·毕业设计
程序员秘密基地3 天前
基于pycharm,python,django,pytorch,mysql,深度学习,模型训练,在线植物,花卉分类系统
pytorch·python·深度学习·神经网络·django
尹劭东3 天前
Django 入门实战:从环境搭建到构建你的第一个 Web 应用
后端·python·django
QD.Joker3 天前
Django ORM 定义模型
数据库·django