Django和Postgresql中的重复条目

4

我的一个视图需要将多个值插入到数据库中。我曾认为,如果我使用唯一的vendor_name设置我的模型:

class Page(models.Model):
  vendor_name = models.CharField(max_length=128, unique=True)
  website = models.CharField(max_length=128)
  food_type = models.CharField(max_length=128)
  img_url = models.CharField(max_length=128)

如果我这样做:

  for vendor in vendors:
    c = Page(vendor_name=vendor["name"], 
             website=vendor["link"], 
             food_type=vendor["type"],
             img_url=vendor["imageurl"])
    c.save()

重复出现的条目将被跳过,数据库中只会有一份副本。至少这是我从这里理解的。我是否需要添加一个if语句来检查每个条目是否已经在数据库中,如果没有则插入,否则跳过?或者我漏掉了什么?唯一约束的目的是什么?它只是在出现重复时抛出错误吗?我能否利用这一点呢?
我得到的错误是:
Exception Value: duplicate key value violates unique constraint...

根据文档:`如果为True,则此字段必须在整个表中唯一。这是通过数据库级别和模型验证来强制执行的。如果您尝试保存具有唯一字段中重复值的模型,则模型的save()方法将引发django.db.IntegrityError异常。` - André Fratelli
为什么不使用外键呢?因为似乎有一个供应商模型。 - Pynchia
所以,是的,它不应该重复。您是否有未应用的迁移? - André Fratelli
@AndréFratelli 我最近的迁移已经被应用了。不过我遇到了一个错误,请看上面的内容。 - theamateurdataanalyst
@Pynchia,这里没有供应商模型,但您能解释一下如何在这里使用外键吗?供应商来自对象数组。 - theamateurdataanalyst
2个回答

2
在Django中,unique强制执行数据库级别的条目验证。因此,如果在表已经创建后将该属性添加到模型字段中,则即使稍后进行syncdb,唯一条件也不会添加到您的表中。
如果您不想创建具有相同vendor_name的行,则应使用Page.objects.get_or_crate让Django仅在不存在该供应商名称的情况下创建Page对象。
for vendor in vendors:
    page, created = Page.objects.get_or_create(
        vendor_name=vendor['name'], 
        defaults={'website': vendor['link'], 
                  'food_type': vendor['type'], 
                  'img_url': vendor['imageurl'])

    if created:
        print('Page created: ', page)

0

您有未应用的迁移。如果出现异常值:重复键违反唯一约束,则意味着您需要在应用迁移之前从数据库中清除重复项。您不能只添加已经被违反的约束。

如果可以的话,可以尝试从数据库中删除整个表并再次应用迁移。如果不可以,则需要删除重复项,并在之后应用迁移。

如果不应用迁移,则unique将无法工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接