我有以下型号,
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)
这里
bank
和 customer
是其类的已保存实例。这样做违反了 not_null
表中 city
外键的 Bank_customer
约束。
我将对模型进行此更改以开始。
注意保留字
class
,必须全部小写。
定义类时,顺序很重要。继承或向后相关的类必须是“最后定义”。 (例如: Bank
必须在
Customer
之后定义,否则您将收到类似 “客户未定义”或类似内容的错误)。
name
模型中的
Bank
属性/字段。我的意思是,银行有名字。
Bank
类中我认为最好明确使用相关名称关键字:
related_name='banks'
。它使可读性更好。
)。
使用 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_id
中有 null=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=True
字段中添加 city
。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 并迁移
) 此后,不会出现任何错误。
讨论该问题的其他一些来源:
django.db.utils.IntegrityError:NOT NULL 约束失败:app.area_iddjango.db.utils.IntegrityError:NOT NULL 约束失败:products_product.image 图像字段错误https://code.djangoproject.com/ticket/21783https://forum.djangoproject.com/t/polls-not-null-constraint-failed/4396/2https://github.com/sibtc/django-beginners-guide/issues/20如果您检查管理员,您会发现Bank
模型仅接受
name
而不接受customers
。BankCustomer
(在你的代码中:
Bank_customer
)。我希望这有帮助。
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()
功能