Django пользовательский виджет администратора, подклассифицирующий ForeignKeyRawIdWidget

Я пытаюсь создать пользовательский виджет администратора, который будет использоваться в нескольких различных моделях для отображения пользовательского ForeignKey в модели Image. Целью является отображение миниатюры рядом с полем ввода ForeignKey. Я следовал статье в блоге здесь, но столкнулся с ошибкой:

ValueError at /admin/events/event/2697/change/
Cannot assign "11": "Event.image" must be a "Image" instance.

Похоже, что метод save_form_data в django.forms.models ожидает экземпляр модели Image, а не id, но я не уверен, как передать это через поле моей пользовательской модели или поле формы. Вот код:

class ImageForeignKeyWidget(ForeignKeyRawIdWidget):
    def render(self, name, value, attrs=None, renderer=None, image=''):
        context = self.get_context(name, value, attrs)
        html = self._render(self.template_name, context, renderer)
        if value:
            image = Image.objects.get(id=value)
            thumb = image.version_url('thumb')
            image = f'''
                <div style="margin-top: 5px !important;">
                <a href="{image.file.url}">
                <img style='border: solid 1px #ccc;' src="{thumb}"/>
                </a>
                </div>'''
        return mark_safe(html + image)

    def _render(self, template_name, context, renderer=None):
        if renderer is None:
            renderer = get_default_renderer()
        return mark_safe(renderer.render(template_name, context))


class ImageFormField(fields.IntegerField):
    def __init__(self, model=None, *args, **kwargs):
        super(ImageFormField, self).__init__(*args, **kwargs)
        self.widget = ImageForeignKeyWidget(model._meta.get_field('image').remote_field, admin.site)


class ImageModelField(models.ForeignKey):
    def formfield(self, **kwargs):
        defaults = {
            'form_class': ImageFormField,
            'model': self.model
            }
        defaults.update(kwargs)
        return models.Field.formfield(self, **defaults)

Есть ли где-то другой метод, который нужно переопределить, чтобы передать экземпляр?

Решением было использование поля ModelChoiceField и определение набора запросов:

class ImageFormField(forms.ModelChoiceField):
    def init(self, model=None, *args, **kwargs):
        super(ImageFormField, self).init(queryset=None, *args, **kwargs)
        self.widget = ImageForeignKeyWidget(model._meta.get_field('image').remote_field, admin.site)
        self.queryset = Image.objects.all()
Вернуться на верх