首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django Postgres循环多个引用-表上的插入或更新违反外键约束

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

Stack Overflow用户
提问于 2016-05-19 18:21:03
回答 2查看 637关注 0票数 2

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

背景:在我的本地机器上使用sqlite3开发,我对下面的代码没有问题。一旦部署到Heroku上的Postgres,我就会第一次遇到这个问题。

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

模型:

代码语言:javascript
复制
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名称、poc电话和poc电子邮件输入表单并提交。然后视图获取或创建供应者对象,将其添加到用户的公司对象,创建POC对象,并以poc_employer的形式将供应商添加到POC对象。在下面的代码中,供应商还不存在,必须创建。

视图:

代码语言:javascript
复制
#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“上插入或更新违反外键约束supplyhelix_supplier_poc_poc_employer 详细信息: Key (company_id)=(11)不在表"supplyhelix_company“中。

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

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

不知道为什么,但据我所知,poc.poc_employer.add(new_supplier)不是简单地使用传递的供应者对象的id,而是简单地使用一个自动递增的id,每当它试图向poc中添加一个供应者对象时,这个id就会递增1。

我知道这很长。非常感谢你读了这么多!我非常感谢你的时间和你对我的任何反馈/帮助。

EN

回答 2

Stack Overflow用户

发布于 2016-05-19 20:21:22

我会考虑重新做你的模特。看起来你使用的是公司模式,既是公司,也是供应商。我知道供应商是一家公司,但如果你对待他们的方式不同,最好把他们分开。你可能会让公司成为一个基本模式,并让供应商和雇主从它那里继承下来。

至于你的模型,我会考虑把它们写成:

代码语言:javascript
复制
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)

就你的观点而言,我会考虑把它写成:

代码语言:javascript
复制
#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不会被保存或添加。

票数 0
EN

Stack Overflow用户

发布于 2016-05-21 17:59:01

首先,感谢柯蒂斯奥尔森和克尼尔森的时间和建议。我真的很感激!这两项建议的努力使我在面临巨大挫折时继续前进。另外,我很抱歉没有尽快发帖。我的岳父在城里,我愚蠢地期望比我实际有更多的时间去做这件事。

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

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

代码语言:javascript
复制
poc_employer = models.ForeignKey('Company', blank = True, null = True)

然后,在视图中,我显式地设置了将供应商添加到poc_employer的id,下面是我在这里找到的一个示例:

Django: Set foreign key using integer?

代码语言:javascript
复制
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和都是有效的。如果我让poc_employer保持一个多个字段,我不确定我是否能够做类似的事情,但稍后可能会对它进行研究。

再次感谢!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37331245

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档