如何基于is_active布尔字段限制对Django API的访问?
实现方案
以下是Django生态下几种常用的全局过滤实现方式,可根据你的技术栈选择:
方案1:自定义模型管理器(全场景通用)
这是最底层的全局过滤方案,对所有调用模型查询的逻辑生效:
- 给作者模型新增自定义管理器,默认过滤
is_active=True的记录
from django.db import models class ActiveAuthorManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(is_active=True) class Author(models.Model): is_active = models.BooleanField(default=False) # 其他原有字段... # 保留默认管理器,供后台、超级用户等特殊场景查询非活跃作者使用 all_objects = models.Manager() # 替换默认管理器为带活跃过滤的版本 objects = ActiveAuthorManager()
- 配置完成后,所有调用
Author.objects.xxx的查询都会自动带上is_active=True的过滤条件,无需修改现有API的查询逻辑。
方案2:DRF全局过滤类(API场景专属)
如果你用的是Django REST Framework开发接口,可以通过自定义全局过滤类实现API层的统一限制,不会影响非API场景的模型查询:
- 新增自定义过滤类
from rest_framework.filters import BaseFilterBackend from .models import Author class IsActiveAuthorFilter(BaseFilterBackend): def filter_queryset(self, request, queryset, view): # 仅对作者模型的查询做过滤,不影响其他模型 if queryset.model == Author: # 可选:超级用户跳过过滤,满足后台管理需求 # if request.user.is_superuser: # return queryset return queryset.filter(is_active=True) return queryset
- 在项目settings中注册为全局默认过滤类
REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': [ '你的应用路径.filters.IsActiveAuthorFilter', # 保留原有其他全局过滤类 ] }
配置后所有DRF视图的作者模型查询都会自动过滤非活跃作者,包括列表查询和单个对象查询场景。
方案3:视图Mixin复用逻辑
如果只需要部分接口做限制,不想全局生效,可以写一个通用Mixin类,需要的视图继承即可:
from django.shortcuts import get_object_or_404 class ActiveAuthorQueryMixin: def get_object(self): queryset = self.filter_queryset(self.get_queryset()) obj = get_object_or_404(queryset, uuid=self.kwargs["id"], is_active=True) self.check_object_permissions(self.request, obj) return obj
需要用限制的视图直接继承该Mixin即可:
from rest_framework import generics from .models import Author from .serializers import AuthorSerializer class AuthorDetailView(ActiveAuthorQueryMixin, generics.RetrieveAPIView): queryset = Author.objects.all() serializer_class = AuthorSerializer # 无需重复编写过滤逻辑
内容的提问来源于stack exchange,提问作者Ashwin Mahesh
相关产品推荐
相关产品推荐

