0

我有以下模型,

Class Bank(models.Model):
    customers = models.ManyToManyField(Customer,'banks', through='bank_customer')

Class Customer(models.Model):
    name = models.CharField(max_length=50)

Class Bank_customer(models.Model):
    customer = models.ForeignKey(Customer,on_delete=models.CASCADE)
    bank = models.ForeignKey(Bank,on_delete=models.CASCADE)
    city = models.ForeignKey(City,on_delete=models.CASCADE)
    
Class City(models.Model):
    name = models.CharField(max_length=100)   

如何添加Customer对象Bank?以下不起作用

bank.customers.add(customer)

这里是他们bankcustomer的保存实例。这样做违反了表中ForeignKey 的not_null约束。cityBank_customer

4

2 回答 2

1

我找不到它的 django 文档。但是查看 Django3.1 的源代码ManyRelatedManager__add,它接受through_defaults参数

def add(self, *objs, through_defaults=None):
...
                self._add_items(
                    self.source_field_name, self.target_field_name, *objs,
                    through_defaults=through_defaults,
                )
...

所以,而不是

bank.customers.add(customer)

尝试

bank.customers.add(customer, through_defaults={'city_id':SOME_CITY_OBJ_ID_YOU_WANT})

这也适用于.set()功能

于 2021-11-03T21:22:22.240 回答
1

首先,一些一般性评论。我不是专家,但我会开始对模型进行更改。

  • 注意保留字class,必须全部小写。

  • 定义类时,顺序很重要。继承或向后相关的类必须最后定义。(例如:Bank必须在 之后定义Customer,否则会出现“未定义客户”或类似的错误)。

  • 我认为您可能需要模型name中的属性/字段Bank。我的意思是,银行有一个名字。

  • Bank课堂上,我认为最好明确使用相关的名称关键字:related_name='banks'. 它使可读性更好。

  • 使用 CapWords 约定 ( PEP 8 ) 命名类更符合 Pythonic。使用BankCustomer代替Bank_customer模型。


关于你的具体问题。

我这样做了:

c1 = Customer(name="Guido van Rossum")
c1.save()
b1 = Bank(name="Bank of America")
b1.save()

然后我做了b1.customers.add(c1),并提出了这个错误:IntegrityError: NOT NULL constraint failed: app2_bankcustomer.city_id。似乎它期望city_idnull=True.BankCustomer

我继续说:

ct1 = City('New York')
ct1.save()
bc1 = BankCustomer(customer=c1, bank=b1, city=ct1)
bc1.save()

然后当我这样做时,b1.customers.add(c1)没有提出任何错误。

问题是IntegrityError错误,显然:

django.db.utils.IntegrityError: NOT NULL--> 这对于初学者来说是一个很常见的错误。这意味着您有一个字段 null=False(也称为default),并且您正在尝试创建该模型而该字段没有任何数据。(来源

所以你可以对BankCustomer. 您null=Truecity字段中添加。

class BankCustomer(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    bank = models.ForeignKey(Bank, on_delete=models.CASCADE)
    city = models.ForeignKey(City, null=True, on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.customer} - {self.bank} - {self.city}'

不要忘记运行 makemigrations 和 migrate

在此之后,不会引发任何错误。

讨论该问题的其他一些来源:

django.db.utils.IntegrityError:NOT NULL 约束失败:app.area_id

django.db.utils.IntegrityError:NOT NULL 约束失败:products_product.image ERROR WITH IMAGE FIELD

https://code.djangoproject.com/ticket/21783

https://forum.djangoproject.com/t/polls-not-null-constraint-failed/4396/2

https://github.com/sibtc/django-beginners-guide/issues/20


如果您检查管理员,您会看到该Bank模型只接受name并且不接受customers.

在此处输入图像描述

我认为这是合乎逻辑的,因为您想使用BankCustomer(在您的代码中:)Bank_customer

我希望这有帮助。

于 2021-03-28T00:15:07.907 回答