Django Admin中如何设置ManyToManyField的limit_choices_to匹配request.user?
Django Admin 限制多对多字段可选范围
问题分析
你在模型中直接使用limit_choices_to={"profile__school": "request.user.profile.school"}是无效的——模型定义阶段无法获取当前请求的request对象,这个参数仅支持静态条件或无法直接访问request的可调用对象。正确的处理方式是在ModelAdmin类中动态修改字段的查询集。
实现方案
在你的NewsAdmin类中重写formfield_for_manytomany方法,针对users字段过滤可选的User对象:
from django.contrib import admin from .models import News from django.contrib.auth.models import User class NewsAdmin(admin.ModelAdmin): def formfield_for_manytomany(self, db_field, request, **kwargs): # 仅对users字段做过滤处理 if db_field.name == 'users': # 获取当前登录管理员的学校信息 current_school = request.user.profile.school # 过滤出与管理员同校的User对象 kwargs['queryset'] = User.objects.filter(profile__school=current_school) return super().formfield_for_manytomany(db_field, request, **kwargs) admin.site.register(News, NewsAdmin)
补充说明
- 若需兼容管理员无
profile或school为空的场景,可添加判断逻辑避免异常:if hasattr(request.user, 'profile') and request.user.profile.school: current_school = request.user.profile.school kwargs['queryset'] = User.objects.filter(profile__school=current_school) else: # 根据需求返回空查询集或全部用户 kwargs['queryset'] = User.objects.none() - 该方法会同时作用于News的添加页和修改页,确保两处的可选范围一致。
内容的提问来源于stack exchange,提问作者Alessandro Curseri
相关产品推荐
相关产品推荐

