我需要 ModelMultipleChoiceField 的 "raw id" 小部件

I need a "raw id" widget for a ModelMultipleChoiceField

我的一个模型有一个 ManyToMany 字段。 我在表单中使用 ModelMultipleChoiceField 和默认小部件(SelectMultiple 小部件)。

问题: 该字段大约有 50k 个选项,加载需要很长时间。

我想将小部件更改为 CharField 并输入以逗号分隔的每个 PK(如管理员 raw_id_field)。

问题: 最好的方法是什么?有人已经为此做了一个小部件吗? 我应该创建自己的 Widget 还是 Field?

谢谢!

你试过了吗ManyToManyRawIdWidget

https://github.com/django/django/blob/master/django/contrib/admin/widgets.py#L205

Disclaimer: Haven't tried it myself, came across it while digging through the source code for something else.

如果您不需要在单独的 window 中选择项目,例如在管理中,那么编写这样的小部件非常简单。使用以下小部件,您将能够输入以逗号分隔的 pks 列表:

from django import forms
from django.utils.encoding import force_text

class ModelMultiRawInput(forms.TextInput):
    def render(self, name, value, attrs=None):
        if value:
            value = ','.join([force_text(v) for v in value])
        else:
            value = ''
        return super(ModelMultiRawInput, self).render(name, value, attrs)

    def value_from_datadict(self, data, files, name):
        value = data.get(name)
        if value:
            return value.split(',')

您通常会像这样使用此小部件:

class MyForm(forms.Form):
    users = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=ModelMultiRawInput)