如何将两个字段"唯一"定义为情侣

Gio*_*lia 345 python django django-models

有没有办法在Django中定义几个字段是唯一的?

我有一个卷(期刊)表,我不想要同一期刊的一个卷号.

class Volume(models.Model):
    id = models.AutoField(primary_key=True)
    journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
    volume_number = models.CharField('Volume Number', max_length=100)
    comments = models.TextField('Comments', max_length=4000, blank=True)
Run Code Online (Sandbox Code Playgroud)

我试图unique = True在字段中添加属性journal_id,volume_number但它不起作用.

Jen*_*ens 575

有一个简单的解决方案叫做unique_together,它可以完全满足您的需求.

例如:

class MyModel(models.Model):
  field1 = models.CharField(max_length=50)
  field2 = models.CharField(max_length=50)

  class Meta:
    unique_together = ('field1', 'field2',)
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

class Volume(models.Model):
  id = models.AutoField(primary_key=True)
  journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
  volume_number = models.CharField('Volume Number', max_length=100)
  comments = models.TextField('Comments', max_length=4000, blank=True)

  class Meta:
    unique_together = ('journal_id', 'volume_number',)
Run Code Online (Sandbox Code Playgroud)

  • 如果你试图添加副本,它会抛出一个django.db.utils.IntegrityError. (23认同)
  • @Greg - 根据ANSI标准SQL:2003(以及之前的那些),`UNIQUE`约束应该禁止重复的非`'NULL`值,但允许多个'NULL`值(参见草案http:// www. wiscorp.com/sql_2003_standard.zip,Framework,第22页).如果您希望您的唯一约束禁止多个空值,那么您可能做错了,比如使用`NULL`作为有意义的值.请记住,可空字段说"我们并不总是对该字段有价值,但是当我们这样做时,它必须是唯一的." (7认同)
  • 我会说你会得到一个"ValidationError"异常.看看Django文档:Model.validate_unique (2认同)
  • 如果volume_number可以为null,你会如何处理?在这种情况下,Mysql似乎不会强制执行. (2认同)
  • 多个`unique_together`约束怎么样?例如 - 当我想让模式列在父级范围内是唯一的时?好吧,这个属性实际上是一个元组本身,请参阅:https://docs.djangoproject.com/en/1.4/ref/models/options/#django.db.models.Options.unique_together所以你的约束应该更明确地写as:`unique_together =(('journal_id','volume_number',),)`. (2认同)

daa*_*awx 45

Django 2.2以上

UniqueConstraint与该constraints选项一起使用。与相比unique_together,它提供的功能更多,将来可能会不推荐使用。

例如:

class Volume(models.Model):
    id = models.AutoField(primary_key=True)
    journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name="Journal")
    volume_number = models.CharField('Volume Number', max_length=100)
    comments = models.TextField('Comments', max_length=4000, blank=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['journal_id', 'volume_number'], name='name of constraint')
        ]
Run Code Online (Sandbox Code Playgroud)

  • @user7733611 命名约束在许多情况下都会有所帮助。例如,如果您要连接到旧数据库,或者您只是希望约束名称在数据库中更易于阅读。有一次我迁移了 MySQL 数据库的字符集,Django 生成的约束名称对于我们的特定目标来说实际上太长了。 (2认同)

Sup*_*ova 15

在 Django 4.0 中,

UniqueConstraint() 的新 *expressions 位置参数支持在表达式和数据库函数上创建功能唯一约束。例如:

from django.db import models
from django.db.models import UniqueConstraint
from django.db.models.functions import Lower


class MyModel(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    class Meta:
        constraints = [
            UniqueConstraint(
                Lower('first_name'),
                Lower('last_name').desc(),
                name='first_last_name_unique',
            ),
        ]
Run Code Online (Sandbox Code Playgroud)

  • 它实际上是“violation_error_message”,以防有人在看...... https://docs.djangoproject.com/en/4.1/ref/models/constraints/#violation-error-message (5认同)

Dhi*_*abi 7

是的,您可以使用 Django 类 Meta 将多个字段定义为唯一字段,如下例所示:

class Volume(models.Model):
    id = models.AutoField(primary_key=True)
    journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
    volume_number = models.CharField('Volume Number', max_length=100)
    comments = models.TextField('Comments', max_length=4000, blank=True)

    class Meta:
        unique_together = ('volume_number', 'journal_id') 
Run Code Online (Sandbox Code Playgroud)

注意:
为了使事情能够写入,您不应将属性添加unique=True到您在属性中定义的任何字段unique_together,否则它将无法作为唯一的一起工作。