2

テーブル「タグ」への ManyToMany フィールドを含むモデルがあります。このテーブルは巨大になる可能性があるため、フォームに選択を表示したくはありませんが、charfield によって提供されるタグのカンマ区切りのリストを表示したいと思います (私はそう思います)。

保存時に、リストをコンマで分割し、(get_or_create を使用して) 1 つずつ追加します。私はすでにそれをしました。

しかし、データを変更したい場合は、タグのリストではなく、ID のリストを使用します。

カンマ区切りのタグのリストを表示するにはどうすればよいですか? そのために新しい特定のフィールドを作成する必要がありますか? それとも、私が探していることをする何かがすでにありますか?

ご協力いただきありがとうございます!

4

2 に答える 2

3

カスタム ウィジェットを作成することをお勧めします (希望どおりの機能を備えた組み込みウィジェットは知りません)。最も有用な例は、おそらく 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
于 2011-02-10T17:47:48.220 に答える
0

上記のコードは、より最適な方法でクエリを使用できます。

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))
于 2019-08-06T11:07:16.943 に答える