Отображение разделенного запятыми списка элементов ManyToMany в поле Charfield в ModelForm - PullRequest
2 голосов
/ 10 февраля 2011

У меня есть модель, содержащая поле ManyToMany для таблицы «Теги».Поскольку эта таблица может быть огромной, я не хочу отображать выборку в форме, а список тегов, разделенных запятой, предоставляемый полем символов (я полагаю).

При сохранении я бы разделилсписок через запятую, а затем добавить их по одному (используя get_or_create).Я уже сделал это.

Но когда я хочу изменить данные, вместо списка тегов у меня появляется список идентификаторов.

Как отобразить список разделенных запятыми тегов?Должен ли я создать новое конкретное поле для этого?или уже что-то делает то, что я ищу?

Спасибо за помощь!

1 Ответ

3 голосов
/ 10 февраля 2011

Вы захотите создать собственный виджет (я не знаю о встроенном виджете, который будет делать именно то, что вы хотите).Наиболее полезными примерами, вероятно, будут виджеты, которые поставляются с 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
...