Django 验证列组合是不是存在(具有布尔字段的唯一性)

Posted

技术标签:

【中文标题】Django 验证列组合是不是存在(具有布尔字段的唯一性)【英文标题】:Django validate column combination existence (Unique with boolean field)Django 验证列组合是否存在(具有布尔字段的唯一性) 【发布时间】:2016-07-01 00:06:00 【问题描述】:

我使用的是 Django 1.9。我有一个简单的模型:

#Goods
class Goods(models.Model):
    code = models.CharField(max_length=50)
    decription = models.CharField(max_length=100)
    ...etc

#Vendors
class Vendors(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=100)
    ...etc

还有一个类来定义多个厂商获取一个好。

#Purchase_options
class PurchaseOptions(models.Model):
    preferred_vendor = models.BooleanField()
    vendor = models.ForeignKey(Vendors)
    good = models.ForeignKey(Goods)

问题来了: 如何确保可以将特定商品的只有一个供应商设置为首选?

表格上接受的值:

**Vendor | Product | Preferred**
  V_01   | Good_01 | True
  V_02   | Good_01 | False
  V_03   | Good_01 | False
  V_02   | Good_02 | True
  V_04   | Good_02 | False

表格上的值错误:

**Vendor | Product | Preferred**
  V_01   | Good_01 | True
  V_02   | Good_01 | **True**  <-There's already a preferred vendor.
  V_03   | Good_01 | False
  V_02   | Good_02 | True
  V_04   | Good_02 | False

我正在使用 Django 的管理界面来填充 Puchase_Options 上的数据。 我试过这个:

1) 定义一个验证器,在给定首选值和产品 ID 的情况下,检查该组合是否存在于表中:

def validator(preferred, id):
    if Purchase_Option.objects.filter(good.id=id,preferred_vendor=preferred).exists():
        Raise ValidationError("There's already a preferred vendor defined for this product")

但它告诉我对象 Purchase_Options 不存在。我相信我实际上无法在验证器函数中查询数据库或处理查询集。

2) 我尝试使用元属性 unique-together("preferred_vendor","good_id")。除了我必须允许 False + Good_Id 的多种组合(因为我有很多非首选供应商)之外,这将起作用......但只有 True+Good_id 的 1 个组合.

我真的不知道还能尝试什么,我真的很期待听到您的想法。你之前曾多次救过我 :D

【问题讨论】:

【参考方案1】:

您可以将NullBooleanField 用于preferred_vendor,将unique_together 用于preferred_vendorgood。对一个首选供应商使用True,对所有其他供应商使用NULL 而不是False

这将允许您拥有多对 (good, NULL) 和仅一对 (good,True)。缺点是您也只能拥有一对 (good,False),但这应该不是问题。

例如:

class PurchaseOptions(models.Model):
    preferred_vendor = models.NullBooleanField()
    vendor = models.ForeignKey(Vendors)
    good = models.ForeignKey(Goods)

    class Meta:
        unique_together = ("preferred_vendor", "good")

然后:

  Vendor | Product | Preferred
  V_01   | Good_01 | True
  V_02   | Good_01 | NULL
  V_03   | Good_01 | NULL
  V_02   | Good_02 | True
  V_04   | Good_02 | NULL

【讨论】:

尼基塔,你的方法有效。所以我真的很感激。尽管我对您的问题感到满意,但我会将这个问题再讨论一段时间以允许任何其他选择。为什么good和null的组合不是重复的?我真的不明白。 太棒了!实际上,我没有研究您的问题是否重复,我只是想出了一个想法并发布了它。所以可能有一些类似的问题,但如果没有,那么这肯定会帮助其他人。 不,伙计,不要误会我的意思。我不是说你的答案是重复的,也许我没有正确表达自己。我的意思是在 SQL 和 Django 方面。 .. 为什么 True+Good 和 False + Good 只允许一种组合,而 NULL+Good 允许多种组合.. 我根本不明白。谢谢!!! 我明白了,据说任何NULL 都被认为不等于其他NULL,所以它可以用于唯一约束。但是允许NULL 是唯一的可能是一个实现特性,即依赖于数据库,但我不确定这一点。 谢谢你...我会把你的答案标记为好。祝你有美好的一天。

以上是关于Django 验证列组合是不是存在(具有布尔字段的唯一性)的主要内容,如果未能解决你的问题,请参考以下文章

Django Modelform - 它没有验证,为什么?

Oracle - 验证表是不是存在与具有表名值的列同名

Django 管理员。当对象具有布尔字段== True时,如何为列表视图中的每一行添加背景颜色?

将 django 表单中的布尔模型字段显示为单选按钮而不是默认复选框

检查Table1中的字段组合是不是存在于另一个Table2中(SQL)

检查 json 类型列 PostgreSQL 中是不是存在字段