Django继承ForeignKeyRawIdWidget实现自定义外键组件显示缩略图报错求解
问题核心原因
你的错误根源是ImageFormField继承了IntegerField,该字段只会返回整型ID值,而外键字段在保存时要求接收关联的模型实例,两者类型不匹配导致报错。
解决方案
直接替换你的原有实现为下方代码即可,核心调整了表单字段的继承类型,适配外键字段对实例类型的要求:
from django import forms from django.contrib.admin.widgets import ForeignKeyRawIdWidget from django.db import models from django.utils.safestring import mark_safe from .models import Image # 替换为你项目中Image模型的实际导入路径 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_obj = Image.objects.get(id=value) thumb = image_obj.version_url('thumb') image = f''' <div style="margin-top: 5px !important;"> <a href="{image_obj.file.url}"> <img style='border: solid 1px #ccc;' src="{thumb}"/> </a> </div>''' return mark_safe(html + image) # 改为继承ModelChoiceField,原生支持返回模型实例 class ImageFormField(forms.ModelChoiceField): def __init__(self, remote_field, *args, **kwargs): # 固定Image模型的查询集 kwargs['queryset'] = Image.objects.all() super().__init__(*args, **kwargs) self.widget = ImageForeignKeyWidget(remote_field, admin.site) class ImageModelField(models.ForeignKey): def __init__(self, *args, **kwargs): # 固定关联到Image模型,使用时无需额外指定 kwargs['to'] = 'your_app_label.Image' # 替换为你项目中Image模型的app_label.模型名格式 super().__init__(*args, **kwargs) def formfield(self, **kwargs): defaults = { 'form_class': ImageFormField, 'remote_field': self.remote_field, } defaults.update(kwargs) return super().formfield(**defaults)
使用说明
在需要关联Image模型的模型类中直接定义字段即可,示例:
class Event(models.Model): # 其他字段省略 image = ImageModelField(on_delete=models.CASCADE)
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

