Python Django ModelForms-如何设置连接表的默认值

Python Django ModelForms-如何设置连接表的默认值,python,django,postgresql,Python,Django,Postgresql,我使用ModelForms填充两个具有多对多关系的表。为了简化问题描述,我将使用一个典型的示例,其中有一个比萨桌和一个配料桌,一个比萨可以有许多配料,一个配料可以在许多比萨上。真正的应用程序有更复杂的表,但我认为它可以归结为这里定义的关系: 连接表将两个表连接在一起,其中每个记录由pizza_id、topping_id和create_time组成。该应用程序有一个用于比萨饼和浇头表的模型表单,但只有一个用于连接表的模型(无模型表单)。连接表记录由django自动创建,因为表之间存在多对多关系。比

我使用ModelForms填充两个具有多对多关系的表。为了简化问题描述,我将使用一个典型的示例,其中有一个比萨桌和一个配料桌,一个比萨可以有许多配料,一个配料可以在许多比萨上。真正的应用程序有更复杂的表,但我认为它可以归结为这里定义的关系:

连接表将两个表连接在一起,其中每个记录由pizza_id、topping_id和create_time组成。该应用程序有一个用于比萨饼和浇头表的模型表单,但只有一个用于连接表的模型(无模型表单)。连接表记录由django自动创建,因为表之间存在多对多关系。比萨饼模型有以下“字段”:

定义多人关系

在本例中,“创建时间”字段必须不为空。(注意:还有其他字段,即用户id字段和“已删除”布尔值需要设置。我以创建时间为例)

保存Pizza记录时,django尝试创建连接表,但失败了,因为它对必填字段没有值。我猜我应该使用“through_defaults”,但我没有成功

我尝试捕捉m2m_更改的信号并将关系添加到pk_集合:

(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_更改信号后清除该表,所以这是有意义的

感谢您的指导


谢谢。

PizzaToppingJunction.create\u time
可以拥有此功能,它将自动将值设置为创建记录的时间

create_time = models.DateTimeField(auto_now_add=True)

然后,如果在“m2m\U更改”期间修改了交叉点记录中的额外字段,则无需在表单中设置任何默认值“信号处理。我不确定这样做是否正确,但到目前为止,这是我唯一能想到的办法。下面的代码需要清理,但它通常对我有用

使用pizza场景:


    def m2m_changed_signal (self, sender, **kwargs):
        django.db.models.signals.m2m_changed.disconnect (self.m2m_changed_signal, sender=models.Pizza.toppings.through)

        instance_time = django.utils.timezone.now()
        instance_user = self.request.user.username

        pizza = kwargs ["instance"]
        pizza_id = pizza.pizza_id
        topping_ids = []
        for topping_id in kwargs ["pk_set"]:
            topping = models.Topping.objects.filter (topping_id = topping_id) [0]
            pizza.toppings.add ( topping, through_defaults = {"create_user": instance_user, "create_time": instance_time, "update_user": instance_user, "update_time":instance_time, "deleted": False})
            topping_ids.append (topping_id)

        for topping_id in topping_ids:
            kwargs  ["pk_set"].remove (topping_id)

需要从pk_集中删除元素以避免重复记录(创建的_by等列的值为空)


如有任何改进建议,我们将不胜感激。

很高兴知道,谢谢!不过,我可能把问题简单化了。我还必须将用户id传递给记录。表上有一个来自请求的“user”列。有没有一个简单的方法来设定?

    def m2m_changed_signal (self, sender, **kwargs):
        django.db.models.signals.m2m_changed.disconnect (self.m2m_changed_signal, sender=models.Pizza.toppings.through)

        instance_time = django.utils.timezone.now()
        instance_user = self.request.user.username

        pizza = kwargs ["instance"]
        pizza_id = pizza.pizza_id
        topping_ids = []
        for topping_id in kwargs ["pk_set"]:
            topping = models.Topping.objects.filter (topping_id = topping_id) [0]
            pizza.toppings.add ( topping, through_defaults = {"create_user": instance_user, "create_time": instance_time, "update_user": instance_user, "update_time":instance_time, "deleted": False})
            topping_ids.append (topping_id)

        for topping_id in topping_ids:
            kwargs  ["pk_set"].remove (topping_id)