Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在抽象模型中创建models.UniqueConstraint_Python_Django_Python 3.x_Django Models - Fatal编程技术网

Python 在抽象模型中创建models.UniqueConstraint

Python 在抽象模型中创建models.UniqueConstraint,python,django,python-3.x,django-models,Python,Django,Python 3.x,Django Models,我正在为我的django应用程序创建一个抽象模型,SrdObject。我的模型的一个特点是它有一对字段,这些字段加在一起必须是唯一的:“name”和外键“module” 这是我所拥有的一个例子 class SrdObject(models.Model): name = models.CharField(max_length=50) slug_name = models.SlugField(max_length=75, unique=True) active = model

我正在为我的django应用程序创建一个抽象模型,
SrdObject
。我的模型的一个特点是它有一对字段,这些字段加在一起必须是唯一的:“name”和外键“module”

这是我所拥有的一个例子

class SrdObject(models.Model):
    name = models.CharField(max_length=50)
    slug_name = models.SlugField(max_length=75, unique=True)
    active = models.BooleanField(default=True)
    module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name='%(class)s', blank=False, null=False, default='default')

    class Meta:
        unique_together = ['name', 'module']
        ordering = ['name']
        abstract = True
这似乎工作正常,但django已将
unique\u-together
属性标记为不推荐使用(请参阅),因此我将其更改为

class Meta:
    constraints = [
        models.UniqueConstraint(fields=['name', 'module'], name='unique-in-module')
    ]
    ordering = ['name']
    abstract = True
这不起作用,因为name字段必须是唯一的,而且因为这是一个抽象类,所以约束会在多个模型上重复

我也试过了

models.UniqueConstraint(fields=['name', 'module'], name='{}-unique-in-module'.format(model_name))
但很明显,这属于范围问题,所以我尝试了一种装饰方法

def add_unique_in_module_constraint(cls):
    cls._meta.constraints = [
        models.UniqueConstraint(fields=['name', 'module'], name='unique-in-module')
    ]
    return cls

@add_unique_in_module_constraint
class SrdObject(models.Model):
    class Meta:
        ordering = ['name']
        abstract = True
但这似乎没有任何作用


那么,如果每个约束都需要唯一的名称属性,那么如何在抽象模型中创建models.UniqueConstraint?

我采用了以下模型设置:

class Module(models.Model):
    pass


class SrdObject(models.Model):
    name = models.CharField(max_length=50)
    slug_name = models.SlugField(max_length=75, unique=True)
    active = models.BooleanField(default=True)
    module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name='%(class)s', blank=False, null=False, default='default')

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['name', 'module'], name='unique-in-module')
        ]
        ordering = ['name']
        abstract = True


class SrdObjectA(SrdObject):
    pass


class SrdObjectB(SrdObject):
    pass
然后运行这些测试:

class TestSrdObject(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.module = Module.objects.create()
        SrdObjectA.objects.create(name='A', module=cls.module)

    def test_unique_applies_to_same_model(self):
        with self.assertRaises(IntegrityError):
            SrdObjectA.objects.create(name='A', module=self.module)

    def test_unique_does_not_apply_to_different_model(self):
        self.assertTrue(SrdObjectB.objects.create(name='A', module=self.module))
他们通过了。也许我还没有找到您遇到的问题?

最新更新

从第三版开始,您最终可以通过以下方式实现:

例如:

UniqueConstraint(字段=['room','date'],name='%(应用程序标签)s\u unique\u booking')
OLD(Django<3.0)

你不能那样做,我也有同样的问题,很伤心

资料来源:

抽象基类中的约束

必须始终为约束指定唯一的名称。因此,通常不能在抽象基类上指定约束,因为Meta.constraints选项由子类继承,每次属性(包括名称)的值都完全相同。相反,直接在子类上指定constraints选项,为每个约束提供唯一的名称


只是想澄清一下-名称/模块的唯一性是跨所有从SrdObject继承的模型的?也就是说,假设我们有两个模型——SrdObjectA和SrdObjectB——继承自SrdObject,如果我有一个名为“test”且模块id为1的SrdObject,那么我也不能有一个名为“test”且模块id为1的SrdObject?这不是一个要求。当我尝试迁移我得到的数据库时,每个SrdObject模型都有自己的名称空间
django.db.utils.ProgrammingError:relation“unique in module”已经存在
。嗯,很有趣。你使用什么数据库?你能分享一下你的迁移文件吗?这到底是什么意思?插值?@NoName,你可以随意命名,我刚从官员那里抄来的docs@NoName添加示例
Changed in Django 3.0:
Interpolation of '%(app_label)s' and '%(class)s' was added.