Django Postgres循环多引用-在表上插入或更新违反了外键约束



BLUF:如何获取poc.poc_employer.add(new_supplier)以使用new_supplier对象id?

背景:在使用sqlite3的本地机器上进行开发时,我对以下代码没有任何问题。一旦在Heroku上部署到Postgres,就是我第一次遇到这个问题的时候。

这个问题涉及两个相互参照的模型。第一个是公司,用于代表用户的公司以及用户的供应商公司。第二个是POC,它在特定的供应商组织中存储用户的POC的信息。

型号:

class Company(models.Model):
...
suppliers = models.ManyToManyField('self', db_index=True, symmetrical=True, related_name = "the_suppliers", blank = True)
POC = models.ManyToManyField('Supplier_POC', db_index=True, symmetrical=True, blank = True)
...
def __str__(self):
return self.company_name

class Supplier_POC(models.Model):
poc_employer = models.ManyToManyField('Company', symmetrical=True, blank = True)
poc_name = models.CharField(blank=True, null=True, max_length=200)
poc_phone = models.CharField(blank=True, null=True, max_length=200)
poc_email = models.EmailField(blank=True, null=True, max_length=200)

用户故事涉及有人通过在表格上输入供应商名称、poc名称、pok电话和poc电子邮件,将供应商添加到公司批准的供应商列表中并提交。然后,视图获取或创建供应商对象,将其添加到用户的公司对象,创建POC对象,并将供应商作为POC_employer添加到POC对象。在下面的代码中,供应商不存在,必须创建。

视图:

#Create and add supplier to Company table as non-member
new_supplier = Company(company_name = supplier, company_domain = domain, member = False)
new_supplier.save()

#Add new supplier to user company's supplier list.  No issues with this.
new_supplier =  Company.objects.get(company_name__iexact = supplier)
company.suppliers.add(new_supplier)

#Save POC to poc table.  No issues with this.
if phone != ""  :
poc = Supplier_POC( poc_name=name, poc_phone = phone, poc_email = email )
else:
poc = Supplier_POC( poc_name=name, poc_phone = "", poc_email = email )
poc.save()
#Add new_supplier to poc object.  Here's the trouble spot
try:
poc.poc_employer.add(new_supplier)
except Exception as e:
print('error trying to add supplier to poc object')
print(e)

Heroku日志中的错误:

在表"supplyhelix_supplier_poc_poc_employer"中插入或更新违反外键约束"supply helix_company_id_19a0767e7b462d_fk_supplyhelix-company_id">

详细信息:表中不存在关键字(company_id)=(11)"supplyhelix_company"。

对于我在Stackoverflow上看到的其他类似问题,解决方案只是添加的对象没有创建和/或保存。正如您在视图中看到的,该对象已创建并保存,并且在尝试添加到POC对象时出错之前,它已成功添加到用户的公司对象中。

我已经打印了几次new_supplier对象的id,以比较上面的错误详细信息,但它们不匹配。例如,产生上述错误的特定测试new_supplier.id是14,但添加的内容显然是在寻找我之前从数据库中删除的id=11。

不知道为什么,但据我所知,poc.poc_employer.add(new_supplier)不是简单地使用传递的供应商对象的id,而是简单地使用一个自动递增的id,每次尝试将供应商对象添加到poc时递增1。

我知道这很长。非常感谢你读到这里!我真的很感谢您的时间和您可能为我提供的任何反馈/帮助。

我会考虑重做你的模型。看起来您正在使用公司模型来既是公司又是供应商。我知道供应商是一家公司,但如果你对他们另眼相看,最好把他们分开。有可能你可以让公司成为一个基础模型,并从中继承供应商和雇主

就你的模型而言,我会考虑把它们写成:

class Company(models.Model):
company_name = ...
...
class Employer(Company):
suppliers = models.ManyToManyField('Supplier', db_index=True, related_name="employers", blank=True)

class Supplier(Company):
...
class POC(models.Model):
name = models.CharField(blank=True, null=True, max_length=200)
phone = models.CharField(blank=True, null=True, max_length=200)
email = models.EmailField(blank=True, null=True, max_length=200)
...
class SupplierPOC(POC):
supplier = models.ForeignKeyField('Supplier', blank=True)

在你看来,我会考虑这样写:

#Create and add supplier to Company table as non-member
new_supplier = Supplier(company_name=supplier_name, company_domain=domain, member=False)
new_supplier.save()
#Add new supplier to user company's supplier list. (I wouldn't use names. Instead use id's.)
new_supplier = Supplier.objects.get(company__id=supplier.id)
employer.suppliers.add(new_supplier)
#Save POC to poc table.
poc = SupplierPOC(supplier=new_supplier, name=name, phone=phone, email=email)
poc.save()

忽略所有这些,您的if phone != "" :块中没有保存,这意味着poc不会被保存或添加。

首先,感谢Curtis Olson和knelson为您提供的时间和建议。我真的很感激!这两个建议都让我在面对巨大挫折时继续前进。此外,我很抱歉没有尽快发布。我的姻亲在城里,我愚蠢地期望有比实际更多的时间来做这件事。

好吧,下面是我所做的更改:

我把Supplier_poc的poc_employer字段作为公司的外键。

poc_employer = models.ForeignKey('Company', blank = True, null = True)

然后,在视图中,我为添加到poc_employer的供应商设置了id,并明确地遵循了我在这里找到的一个示例:

Django:用integer设置外键?

poc = Supplier_POC( poc_name=name, poc_phone = phone, poc_email = email )
poc.poc_employer_id = new_supplier.id
poc.save()  #knelson, thanks for the catch on the save.

这在sqlite3和heroku Postgres上都可以在本地工作。如果我把poc_employer保留在一个很多领域,我不确定我是否能够做类似的事情,但以后可能会研究它。

再次感谢!

最新更新