Добавление тегов: виджет пользовательской формы Django для поля модели ManyToMany

В настоящее время я создаю свое собственное приложение Tagging для Django.

Вот модели:

class Tag(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    tags = models.ManyToManyField(Tag)

Я создал форму для моей модели Book и виджет для Tag входы:

class BookForm(ModelForm):
    class Meta:
        model = Book
        fields = ('title', 'tags')
        widgets = {
            'tags': TagWidget
        }

class TagWidget(Widget):
    """
    Widget for Tag input fields.
    """
    def render(self, name, value, attrs=None):
        final_attrs = self.build_attrs(attrs, name=name)
        final_attrs['class'] = 'tag-input'
        options = []

        # TODO the following tags should be assigned from the model directly
        options.append('tag1');
        options.append('tag2');

        list_element = u'<ul%s>' % flatatt(final_attrs)
        return mark_safe(list_element + '\n<li>' + (u'</li>\n<li>'.join(options)) + '</li>\n</ul>')

Вопросы

  1. Как я могу добавить существующие теги в массив опций (options.append(...))?
  2. Кроме того, как я могу улучшить создание HTML-кода (см. Последнюю строку mark_safe)? Я хотел бы поместить весь HTML-код в другом месте (желательно в моей папке шаблонов).

1 ответ

Решение
  1. Вы можете передать дополнительные данные в конструктор виджета. Что-то вроде

    class TagWidget(Widget):
        def __init__(self, initial_tags, *args, **kwargs)
            self.initial_tags = initial_tags
            super(TagWidget, self).__init__(*args, **kwargs)
    
    # ...
    
    widgets = {
        'tags': TagWidget(initial_tags=('one', 'two', 'three'))
    }
    

    Тогда данные будут доступны в self.initial_tags,

  2. Вы можете использовать функцию render_to_string.

Другие вопросы по тегам