如何在Django模型字段中按条件过滤ForeignKey的可选值
解决方案
方法1:模型层全局限制(最推荐)
直接在Service模型的name外键字段添加limit_choices_to参数,该配置会全局生效,无论是Admin后台还是自定义的ModelForm都会自动过滤仅展示is_worker=True的用户:
class Service(models.Model): # 仅修改外键定义行,添加limit_choices_to参数 name = models.ForeignKey(CustomUser, on_delete=models.CASCADE, limit_choices_to={'is_worker': True}) service = models.CharField(choices=SERVICE_CHOICES,max_length=100) def __str__(self): return f'{self.service} - {self.name}'
方法2:自定义Form层面限制
如果只需要在特定表单生效,不需要全局限制,可以重写ModelForm的对应字段queryset:
from django import forms from .models import Service, CustomUser class ServiceForm(forms.ModelForm): class Meta: model = Service fields = '__all__' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 过滤name字段的可选用户 self.fields['name'].queryset = CustomUser.objects.filter(is_worker=True)
之后在视图或者Admin类中指定使用这个Form即可。
方法3:Admin后台单独限制
如果仅需要在Django Admin后台的表单过滤,不需要影响其他场景,可以修改Service对应的Admin类:
from django.contrib import admin from .models import Service, CustomUser @admin.register(Service) class ServiceAdmin(admin.ModelAdmin): def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "name": kwargs["queryset"] = CustomUser.objects.filter(is_worker=True) return super().formfield_for_foreignkey(db_field, request, **kwargs)
内容的提问来源于stack exchange,提问作者user14653534
相关产品推荐
相关产品推荐

