在django admin中使用django-taggit字段的FilteredSelectMultiple小部件

时间:2015-12-08 10:25:37

标签: python django django-admin django-taggit

我正在尝试使用Tags包将django-taggit's添加到我的模型实例中。为此,我在我的模型中添加了tags字段,因为它在django-taggit's定义中定义。

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    tags = TaggableManager()

我想将此模型添加到django-admin面板,并希望使用FilteredSelectMultiple小部件添加标记。为此我创建了一个模型表单并更改了它的字段小部件。

class MyModelForm(forms.ModelForm):
    tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.none())
    def __init__(self, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)
        self.fields['tags'].widget = FilteredSelectMultiple('Tags', False)
        self.fields['tags'].queryset = Tag.objects.all()

class Meta:
    model = MyModel
    exclude = []

类MyModelAdmin(admin.ModelAdmin):     form = MyModelForm

一切都运转良好。保存实例后正在保存标签。但问题是,当我打开更新页面时。 “选择的标签”中没有先前选择的标签。字段小部件的一部分。它是空的,所有选项都在'可用标签'选项。

我也尝试为模型管理员的change_form提供初始数据,但对我来说没有任何作用。

def get_changeform_initial_data(self, request):
    return {'tags': self.object.tags.all()}

self.objectget_object()类的ModelAdmin方法获得的对象。

给我一​​个解决方案。

1 个答案:

答案 0 :(得分:0)

似乎问题是ModelMultipleChoiceField中的 prepare_value 函数查看对象上的 .pk 字段,该字段提供的值不正确,因此不会呈现(或渲染)错误的选择)。您应该看一下 .tag_id 字段。

这对我有用,但如果有更正确或更优雅的方式会感兴趣:

class TagMultipleChoiceField(forms.ModelMultipleChoiceField):
    def prepare_value(self, value):
        if hasattr(value, 'tag_id'):
            return value.tag_id
        elif hasattr(value, '__iter__') and not isinstance(value, six.text_type) and not hasattr(value, '_meta'):
            return [self.prepare_value(v) for v in value]
        else:
            return super(TagMultipleChoiceField, self).prepare_value(value)

class AdminCourseForm(forms.ModelForm):
    class Meta:
        model = Course
        exclude = ()

    tags = TagMultipleChoiceField(queryset=MyTag.objects.all())