我正在使用ModelForms填充具有多对多关系的两个表。为了简化问题描述,我将使用一个典型示例,其中有一个比萨饼表和一个浇头表,一个比萨饼可以有很多浇头,而一个浇头可以在许多比萨饼上。实际的应用程序具有更复杂的表,但我认为它取决于此处定义的关系:https://docs.djangoproject.com/en/3.0/topics/db/models/#many-to-many-relationships
一个联结表,其中每个记录由pizza_id和topping_id和create_time组成,将这两个表联系在一起。该应用程序具有用于比萨饼和浇头表的Modelform,但是仅具有用于联接表的模型(无ModelForm)。由于表之间的多对多关系,django自动创建联结表记录。披萨模型具有此“字段”:
toppings=models.ManyToManyField (Topping, through=PizzaToppingJunction)
定义ManyToMany关系。
在此示例中,“ create_time字段必须不为空。(注意:还有其他字段,即用户ID字段和我需要设置的” deleted“布尔值。我将create_time用作例)。
保存Pizza记录时,django尝试创建联结表,但是失败,因为它没有必填字段的值。我猜我应该使用“ through_defaults”,但是我没有成功。
我尝试捕获m2m_changed信号并将关系添加到pk_set:
(pizza.toppings.add ( topping, through_defaults = {"create_time": instance_time})
这(可以理解)会导致递归错误。
我尝试手动创建它们:
PizzaToppingsJunction.objects.create (create_time = instance_tine, pizza_id = pizza_id, topping_id = topping_id).
这似乎对下游处理没有任何影响,因为django尝试创建缺少必填字段的联结表记录。我认为代码会在m2m_changed信号之后清除该表,因此很有意义。
感谢任何指导。
谢谢。
[PizzaToppingJunction.create_time
可以有auto_now_add=True
,它将自动将值设置为创建记录的时间]
auto_now_add=True
然后您无需在表单中设置任何默认值
如果在“ m2m_changed”信号处理过程中完成了修改联结记录中的额外字段的工作,则可以使用。我不确定这是否是正确的方法,但是到目前为止,这是我唯一能想到的。下面的代码需要清理,但这通常对我有用。
使用披萨场景:
create_time = models.DateTimeField(auto_now_add=True)
需要从pk_set中删除元素,以避免重复的记录(对于created_by等,列为空值)。
任何改进建议都将不胜感激。