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