Django IntegrityError с UniqueConstraint
У меня есть модель с UniqueConstraint
на полях: site
, name
, type
, когда status
является либо живым, либо черновым.
Однако, когда я создаю 2 объекта с одинаковым сайтом, именем и типом (один с status = live
, а другой с status = draft
), он выдает эту ошибку:
django.db.utils.IntegrityError: UNIQUE constraint failed: site_config_configuration.site_id, site_config_configuration.name, site_config_configuration.type
Я использовал этот документ для UniqueConstraint: https://docs.djangoproject.com/en/3.2/ref/models/constraints/#uniqueconstraint
Вот моя модель:
class Configuration(models.Model):
CSS = 'css'
SECRET = 'secret'
TYPES = [
(CSS, 'css'),
(SECRET, 'secret')
]
LIVE = 'live'
DRAFT = 'draft'
HISTORY = 'history'
STATUSES = [
(LIVE, 'Live'),
(DRAFT, 'Draft'),
(HISTORY, 'History')
]
site = models.ForeignKey(Site, on_delete=models.CASCADE)
name = models.CharField(max_length=255, blank=False)
type = models.CharField(
max_length=255,
choices=TYPES)
value = models.JSONField(
null=True)
status = models.CharField(
max_length=20,
choices=STATUSES)
created = models.DateTimeField(editable=False, auto_now_add=True)
modified = models.DateTimeField(editable=False, auto_now=True)
class Meta(object):
constraints = [
models.UniqueConstraint(
fields=['site', 'name', 'type'],
condition=(Q(status='draft') | Q(status='live')),
name='unique config')
]
Вот мой простой тест, в котором я создаю 2 объекта, и он выбрасывает django.db.utils.IntegrityError
при создании config_draft
:
import pytest
from site_config.models import Site, Configuration
@pytest.mark.django_db
def test_configuration_model():
"""
Tests for Configuration Model
"""
site = Site.objects.create(domain_name='hello-world.org')
config_live = Configuration.objects.create(
site=site,
name="$cta-button-border",
type='css',
value="2px solid #0090c1",
status='draft',
structure_version='v1',
author_email='example@example.com')
config_draft = Configuration.objects.create(
site=site,
name="$cta-button-border",
type='css',
value="5px solid #0090c1",
status='live',
structure_version='v2',
author_email='example@example.com')
assert config.status == 'draft'
assert str(config) == "Configuration: hello-world.org \"$cta-button-border\""
Я думаю, что вы также должны поместить 'статус' в уникальные поля:
constraints = [
models.UniqueConstraint(
fields=['site', 'name', 'type', 'status'],
condition=(Q(status='draft') | Q(status='live')),
name='unique config')
]