添加标签:用于ManyToMany模型字段的Django自定义表单小部件

时间:2012-05-12 10:30:17

标签: python django model widget 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 个答案:

答案 0 :(得分:3)

  1. 您可以在widget的构造函数中传递其他数据。像

    这样的东西
    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. 中访问数据
  3. 您可以使用render_to_string功能。