如何在Django管理员中为关系字段设置初始值?

时间:2019-02-21 16:40:10

标签: python django foreign-keys django-admin relationship

摘要

我们想在Django管理员的基本“添加”或“更改”页面上设置代表不同种类模型关系的选择框的初始选择。 如果用户单击“保存”按钮之一,则初始选择应保存到数据库中。

我们特别想通过在表单字段(对于initialModelAdmin)上设置TabularInline值来做到这一点。

问题是:

为不同类型的关系表单域分配给 {em> Field.initial的正确“值”是什么?

背景

假设我们有一个简单的Model,其中有一个或多个 relationship fields,即OneToOneFieldForeignKeyManyToManyField。默认情况下,后者具有隐式 through模型,但也可以使用 explicit through模型,如{{3 }}。显式through模型是具有docs两个ForeignKey字段的模型。

由选择框表示的关系字段自动显示在标准ModelAdmin“添加”或“更改”表单上,但带有显性 {{ {1}}模型。如文档at least所述,该代码需要内联,例如ManyToManyField

请注意,隐式 through与(admin)表单上的TabularInline关联,而其他关系字段也与ManyToManyField关联。后者包括具有显式 ModelMultipleChoiceField模型的ModelChoiceField,因为它实际上由ManyToManyField中的through字段表示。

目标

现在考虑此模型的基本Django ForeignKey“添加”(或“更改”)页面,包括任何 explicit TabularInline模型的内联。下面是一个基于Django的Pizza-Topping的示例。

我们要实现两个目标:

  1. 为一个或多个关系字段设置初始选择
  2. 如果我们单击“保存”按钮之一(假设我们没有手动更改选择),则初始选择必须保存到数据库中

请注意,第二个看似微不足道,但显然不是(见下文)。

here

方法

据我所知,有几种方法可以实现这一目标:

  • 设置模型字段ModelAdmin的值,例如through,可以选择传递可调用(django pizza admin example
  • 设置管理表单(docs)的default
  • 为管理表单字段(docs)设置ForeignKey.default

无论哪种方法在特定用例中都是“最佳”,这个问题是关于最后一种方法:设置Form.initial的值。 / p>

我们通过扩展Field.initial(或Field.initial)来做到这一点,如下所示:

ModelAdmin.formfield_for_dbfield

此示例中的TabularInline.formfield_for_dbfield可以是def formfield_for_dbfield(self, db_field, request, **kwargs): if db_field.name == 'some_relationship_field_name': kwargs['initial'] = value return super().formfield_for_dbfield(db_field, request, **kwargs) valueobj.idobj,其中[obj.id, ...]是{{ 1}}实例。

问题

根据关系字段的类型,不同类型的[obj, ...]可能会或可能不会。

对于具有隐式obj模型的Model,我们只能分配一个对象列表,这样很容易。

对于其他关系,在某些情况下,初始选择框选择与分配的值匹配,但未保存(例如,因为docs返回value)。 在其他情况下,将保存初始选择框值,但与分配的值不匹配。

问题

因此,显而易见的问题是:

对于管理表单上不同类型的关系字段,应将ManyToManyField分配给through的正确方法是什么?

相关

尽管花了很多时间进行搜索,但我在文档中,SO或其他任何地方都找不到清晰的答案。还试图通过源代码来解决这个问题,但这确实很棘手。

一些类似的问题:

1 个答案:

答案 0 :(得分:0)

下表显示了使用Django 2.1的一些最小的专用示例的实验结果。根据该表,看起来:

  • objobj.id仅适用于OneToOneFieldForeignKey
  • [obj.id]适用于ModelChoiceField
  • 表示的所有关系
  • [obj]仅适用于由ManyToManyField表示的隐式ModelMultipleChoiceField

但是,我不能说每种情况下预期的处理方式。例如,为ForeignKey字段分配列表没有多大意义。但是,有趣的是,即使具有显式ManyToManyField模型的through内联了ModelChoiceField的{​​{1}},我们也不能只分配{{1 }}或ForeignKey:它必须在列表中。

任何评论在这里都非常感谢。

表1的关键字:

  • 1 :选择框的初始选择对应于obj的值
  • 2 :单击“保存”后,将保存选择框的初始选择(注意:如果1失败,则选择框的初始选择是第一个可用选项)
  • T obj.id(对象不可迭代)
  • A Field.initial(“ int”对象没有属性“ pk”)

请注意,我们的所需行为 1&2

表1:为不同关系字段向TypeError分配不同值的结果

AttributeError