将Django ModelChoiceField查询集限制为所选项
这是我一天苦苦挣扎的......
我有一个消息模型,其中 recipients
是 ManyToManyField
到 User
模型 .
然后有一个用于撰写邮件的表单 . 由于有数千个用户,在表单中的多选小部件中显示选项并不方便,这是默认行为 . 相反,使用FcbkComplete jquery插件,我使收件人字段看起来像用户键入收件人的输入字段,并且它工作 .
但...
虽然在表单页面上不可见,但所有用户列表都会在选择字段中呈现到页面中,这是我不想要的原因 .
我尝试重写ModelChoiceField操作验证和查询集的行为,我使用了MultipleChoice小部件,等等 . 但是没有一个工作并且感觉很自然 .
那么,避免在客户端使用整个选项列表,但仍然能够针对查询集进行验证的(最佳)方法是什么?
回答(4)
如果您不关心建议,并且可以使用该ID,Django Admin会为这些情况提供raw_id_field属性 .
您还可以创建一个小部件,它使用用户名而不是ID并返回有效用户 . 以下内容:
# I haven't tested this code. It's just for illustration purposes
class RawUsernameField(forms.CharField):
def clean(self, value):
try:
return User.objects.get(username=value)
except User.DoesNotExist:
rause forms.ValidationError(u'Invalid Username')
我通过覆盖 forms.ModelMultipleChoiceField
的默认小部件来解决这个问题 . 新窗口小部件仅返回选定的字段,而不是整个选项列表:
class SelectMultipleUserWidget(forms.SelectMultiple):
def render_options(self, choices, selected_choices):
choices = [c for c in self.choices if str(c[0]) in selected_choices]
self.choices = choices
return super(SelectMultipleUserWidget,
self).render_options([], selected_choices)
class ComposeForm(forms.Form):
recipients = forms.ModelMultipleChoiceField(queryset=User.objects.all(),
widget=SelectMultipleUserWidget)
...
2 years ago
你见过django-ajax-selects吗?当我遇到一个类似于你想要解决的问题的时候,我的心理抓包里面的东西......