如何解决如何在模型中没有表达的 FK 关系的管理更改页面中的字段上实现添加/编辑链接?
我有一个 Django 3.x 网站。有 3 个模型,其中包括 Document
、MetaData
、MetaDataValue
。 MetaDataValue
模型与 MetaData
模型具有外键关系。
在一个简单的世界中,会有一个从 MetaData
到 Document
的外键关系。然后 DocumentAdmin
会将 MetaData
字段显示为下拉列表,并填充相应的 MetaDataValues
。下拉菜单旁边还会有编辑/添加(铅笔/加号)链接,以允许用户编辑/添加该 MetaDataValue
对象的 MetaData
。
但是,该项目的要求之一是在运行时之前不定义哪些或多少 MetaData
对象将与特定的 Document
类型相关联。这些关联是通过另一组模型进行的。因此,Document
管理更改页面在运行时将不同的 MetaData
字段添加到更改管理页面,方法是查看 MetaData
字段与此类 {{ 1}},然后通过 Document
方法将它们添加到字段集。
这种设计的含义是不能编辑/添加值到 get_fieldsets
管理更改页面上的特定 MetaData
字段,因为我认为 Django 丢失了Document
和 Document
模型,因为字段集是在管理员的 MetaData
方法中生成的。
我可以添加代码页来显示 get_fieldsets
字段是如何在运行时生成的,但我认为这不会使描述更加清晰。我查看了为上述“简单世界”示例生成的页面源代码和字段集,但看不到 Django 在哪里确定何时将编辑/更改链接添加到特定外键字段的下拉列表。>
我的问题是,如何将铅笔和加号添加到 MetaData
管理更改页面中显示的这些 MetaData
字段,并让用户选择添加/编辑 {{1 }} 对于那个特定的 Document
对象?我可以创建一些 Ajax 调用并自己完成所有繁重的工作,但我更愿意尽可能多地利用 Django 基础设施,而不是重新发明更多。
谢谢!
解决方法
我找到了使用 RelatedFieldWidgetWrapper
的解决方案。我将这个小部件包装器添加到我所有需要绿色加号(添加)和黄色铅笔(编辑)的选择中。
这里有太多代码要发布,但这里是它的主要内容。我的数据库表 MetaData
包含所有字段的名称,MetaDataValue
包含每个元数据字段的值。元数据用于描述文档(文本、视频、图像),但 MetaData
模型和 Document
模型之间没有 FK 关系。元数据和文档之间的关系包含在另一个表的 JSON 字段中。 MetaData
表还具有用于该元数据字段的 Django 字段类型。还有另一个表用于确定哪些元数据字段适用于哪种文档类型(图像、文本、视频)。对于所有 ModelChoiceFields
,我添加了字段和小部件(Select
包裹在 RelatedFieldWidgetWrapper
中)。
elif (metadata_names[i].field_type == MetaData.MODELCHOICEFIELD):
fields[metadata_names[i].name] = forms.ModelChoiceField(queryset=MetaDataValue.objects.filter(metadata_id=metadata_names[i].metadata_id).order_by('value'),required=False,label=metadata_names[i].label,help_text=metadata_names[i].help_text)
# add the green plus (add) and pencil (edit) links to each select field
fields[metadata_names[i].name].widget = RelatedFieldWidgetWrapper(fields[metadata_names[i].name].widget,MetaDataValue._meta.get_field('tag_value'),admin_site,can_add_related=True,can_change_related=True)
if 'documentType_id' in fields:
# Editing/add a new document type seems like a bad idea,as document type is used a lot in the processing logic
fields['documentType_id'].widget.can_add_related = False
fields['documentType_id'].widget.can_change_related = False
困难的部分是为 RelatedFieldWidgetWrapper
获取正确的参数。该小部件的文档有点稀少,因为我认为它是管理的早期部分,但是自从首次实现以来,Django 代码的大部分内容都发生了变化,因此过去使用此包装器的方式很多(即堆栈溢出帖子)已被弃用。我只是查看了来源,并尝试了似乎合适的方法,直到它起作用为止。最后,这些文章很有帮助:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。