在 ModelForm 的 Charfield 中显示以逗号分隔的 ManyToMany 项目列表

发布于 2024-10-17 00:16:38 字数 272 浏览 5 评论 0原文

我有一个模型,其中包含表“Tags”的 ManyToMany 字段。由于这个表可能很大,我不想在表单中显示选择,而是显示由 charfield 提供的逗号分隔的标签列表(我想)。

在保存时,我会用逗号分割列表,然后将它们一一添加(使用 get_or_create )。我已经这么做了。

但是当我想要更改数据时,我没有标签列表,而是 ID 列表。

如何显示逗号分隔标签的列表?我是否必须为此创建一个新的特定字段?或者是否已经有一些东西可以满足我的需求?

感谢您的帮助!

I have a model containing a ManyToMany field to a table "Tags". Since this table could be huge, I don't want to display a select in the form, but a coma separated list of tags, provided by a charfield (I suppose).

On the saving, I would split the list by their comma and then add them one by one (using get_or_create). I already did that.

But when I want to change data, instead of having a list of tags, I have a list of IDs.

How can I display a list of comma separated tags? Do I have to create a new specific Field for that ? or is there already something that do what I'm looking for?

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久而酒知 2024-10-24 00:16:39

上面的代码可以以更优化的方式使用查询,例如

类 CommaTags(Widget):
    def render(自身、名称、值、attrs=None):
        值 = Tag.objects.filter(pk__in=each) \
            .exclude(name__exact='') \
            .values_list("名称") \
            。加入(”, ”)

        如果值:
            Final_attrs['值'] = force_unicode(值)

        return mark_safe(u'<输入%s />' % flatatt(final_attrs))

The code above could use queries in a more optimal way, something like

class CommaTags(Widget):
    def render(self, name, value, attrs=None):
        value = Tag.objects.filter(pk__in=each) \
            .exclude(name__exact='') \
            .values_list("name") \
            .join(", ")

        if value:
            final_attrs['value'] = force_unicode(value)

        return mark_safe(u'<input%s />' % flatatt(final_attrs))
っ〆星空下的拥抱 2024-10-24 00:16:38

您需要创建一个自定义小部件(我不知道有哪个内置小部件可以完全满足您的要求)。最有用的例子可能是 Django 附带的小部件(在 forms/widgets.py 中)。您还可以在此处查看创建自定义小部件的示例

我做了一些摆弄,在调整内置 Input 小部件后,这就是我想出的结果;我做了一些测试,它对我有用:

class CommaTags(Widget):
    def render(self, name, value, attrs=None):
        final_attrs = self.build_attrs(attrs, type='text', name=name)
        objects = []
        for each in value:
            try:
                object = Tag.objects.get(pk=each)
            except:
                continue
            objects.append(object)

        values = []
        for each in objects:
            values.append(str(each))
        value = ', '.join(values)
        if value: # only add 'value' if it's nonempty
            final_attrs['value'] = force_unicode(value)
        return mark_safe(u'<input%s />' % flatatt(final_attrs))

请注意,在这个示例中,小部件被硬编码为使用假设的 Tag 模型,并且它只是使用 str() 方法每个对象的内容将显示在逗号分隔的列表中。您可能需要更改这些以适合您的使用。另外,我直接将其放在 forms/widgets.py 中,因此如果您将其放在其他地方(就像您可能应该做的那样),您将需要导入一些我使用的东西。

创建完成后,您可以将其指定为表单中 ModelMultipleChoiceField 的小部件,如下所示:

from django import forms

class TagForm(forms.ModelForm):
    tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all(),
                                          widget=CommaTags)
    class Meta:
        model = Tag

You'll want to create a custom widget (I'm not aware of a built-in widget that will do exactly what you want). The most useful examples would probably be the widgets that come with Django (in forms/widgets.py). You can also see an example of creating a custom widget here.

I did a little fiddling, and after adapting the built-in Input widget this is what I came up with; I did some testing and it works for me:

class CommaTags(Widget):
    def render(self, name, value, attrs=None):
        final_attrs = self.build_attrs(attrs, type='text', name=name)
        objects = []
        for each in value:
            try:
                object = Tag.objects.get(pk=each)
            except:
                continue
            objects.append(object)

        values = []
        for each in objects:
            values.append(str(each))
        value = ', '.join(values)
        if value: # only add 'value' if it's nonempty
            final_attrs['value'] = force_unicode(value)
        return mark_safe(u'<input%s />' % flatatt(final_attrs))

Note that in this example, the widget is hardcoded to use a hypothetical Tag model, and it's just using the str() method of each object as what will show up in the comma-separated list. You'll probably want to change these to fit your use. Also, I had this directly in forms/widgets.py, so if you put it somewhere else (like you probably should), you'll need to import a few of the things I used.

Once you have that created, you can specify it as the widget for your ModelMultipleChoiceField in your form, like so:

from django import forms

class TagForm(forms.ModelForm):
    tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all(),
                                          widget=CommaTags)
    class Meta:
        model = Tag
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文