当前位置: 首页 > news >正文

快速入手-基于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"],

}

完整代码

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测试每个字段的值必须要完全匹配才可以,否则数据找不到。

完整代码如下所示

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

相关文章:

  • 2025年渗透测试面试题总结-某 携程旅游-基础安全工程师(题目+回答)
  • 41、当你在 index.html 中引用了一个公共文件(比如 common.js),修改这个文件后,用户访问页面时仍然看到旧内容,因为浏览器缓存了旧版本
  • 人工智能-LangGraph+ChatUI+DeepSeek API搭建本地智能助手
  • 搭建开源笔记平台:outline
  • 如何在 Unity3D 导入 Spine 动画
  • 【NLP】15. NLP推理方法详解 --- 动态规划:序列标注,语法解析,共同指代
  • JavaScript 库:全面解析与推荐
  • 13-SpringBoot3入门-整合MyBatis-Plus
  • 【Docker镜像】Python项目之使用Dockerfile构建镜像(一)
  • 如何用Postman实现自动化测试?
  • 【Jira 查询与 JQL 使用详解】
  • 【数据结构】导航
  • Ubuntu 24.04.2 LTS 系统安装python,创建虚拟环境
  • 解决 CMS Old GC 频繁触发线上问题技术方案
  • 本地部署vanna ai+通过http请求调用vanna
  • 虚幻5入门
  • Docker学习--本地镜像管理相关命令--docker save 命令
  • 【Easylive】TokenUserInfoDto中@JsonIgnoreProperties和 Serializable 接口作用
  • git 按行切割 csv文件
  • MCP协议的Streamable HTTP:革新数据传输的未来
  • 乡村快递取件“跑腿费”屡禁不止?云南元江县公布举报电话
  • 央行:增加支农支小再贷款额度3000亿元
  • 山东滕州市醉驾交通事故肇事人员已被刑拘
  • 原四川省农村信用社联合社党委副书记、监事长杨家卷被查
  • 新华社:赵心童世锦赛夺冠,中国书写斯诺克运动新历史
  • 10家A股农商行去年年报:瑞丰银行营收增速领跑,常熟银行等4家净利增速超11%