Виджет FilteredSelectMultiple с полем django-taggit в админке django

Я пытаюсь добавить Tags к своим экземплярам модели, используя пакет django-taggit's. Для этого я добавил поле tags в свою модель, как оно определено в определении django-taggit's.

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

Я хочу добавить эту модель в панель администратора django и хочу использовать виджет 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): форма = MyModelForm

все работает нормально. Теги сохраняются после сохранения экземпляра. но проблема в том, что когда я открываю страницу обновления. В части «Выбранные теги» виджета поля нет ранее выбранных тегов. Он пуст, и все варианты доступны в опции «Доступные теги».

Я пытался предоставить исходные данные также для change_form администратора модели, но у меня ничего не работает.

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

self.object — это объект, который я получил методом get_object() класса ModelAdmin.

Дайте мне решение.


person Sajid Ahmad    schedule 08.12.2015    source источник


Ответы (1)


Кажется, проблема в том, что функция prepare_value в ModelMultipleChoiceField просматривает поле .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())
person Ray Pendergraph    schedule 10.12.2015
comment
Проблема в том, что связанные теги хранятся в модели taggit.TaggedItem пакета taggit. Если я заменю набор запросов на queryset = TaggedItem.objects.all(), тогда он покажет сохраненные теги, но проблема в том, что мы можем сохранить новые теги, потому что он возвращает экземпляры модели TaggedItem вместо модели тегов. - person Sajid Ahmad; 11.12.2015