Django表单限制用户仅选择自身标签的实现问题
解决表单标签仅显示当前用户选项的问题
问题原因
你之前尝试给DateInputForm传递limit_choices_to参数报错,是因为limit_choices_to是模型字段的静态参数,不能直接传给ModelForm的构造函数,BaseModelForm本身不支持这个参数。
解决方案
有两种简洁的实现方式,选一种即可:
方式1:在表单中动态过滤(推荐,表单逻辑内聚)
修改你的DateInputForm,在初始化时接收当前用户并过滤标签选项:
class DateInputForm(ModelForm): def __init__(self, *args, **kwargs): # 从参数中取出当前用户,注意要在调用super之前弹出 user = kwargs.pop('user') super().__init__(*args, **kwargs) # 过滤tags字段的可选值,仅保留当前用户的标签 self.fields['tags'].queryset = Tag.objects.filter(user=user) class Meta: model = Task fields = ['user', 'title', 'description', 'date_to_do', 'complete', 'tags'] widgets = { 'date_to_do': forms.DateTimeInput(format='%Y-%m-%dT%H:%M', attrs={'type': 'datetime-local', 'class': 'timepicker'}), }
然后在视图中重写get_form_kwargs方法,把当前用户传给表单:
class TaskUpdate(LoginRequiredMixin, UpdateView): model = Task template_name = "tasks/task_form.html" form_class = DateInputForm def get_form_kwargs(self): kwargs = super().get_form_kwargs() # 将当前登录用户传入表单 kwargs['user'] = self.request.user return kwargs
方式2:在视图中动态过滤(无需修改表单)
如果不想改动表单,直接在视图的get_form方法中修改标签的查询集:
class TaskUpdate(LoginRequiredMixin, UpdateView): model = Task template_name = "tasks/task_form.html" form_class = DateInputForm def get_form(self, form_class=None): form = super().get_form(form_class) # 仅显示当前用户的标签 form.fields['tags'].queryset = Tag.objects.filter(user=self.request.user) return form
补充说明
如果你的Task模型中tags字段是ForeignKey或ManyToManyField,静态的limit_choices_to只能写固定条件(比如limit_choices_to={'tag_name__contains': 'test'}),无法引用请求上下文里的request.user,所以必须用上述动态过滤的方式实现。
内容的提问来源于stack exchange,提问作者Wamz
相关产品推荐
相关产品推荐

