2015-08-20 2 views
0

У меня есть модель Django, как это:Джанго ограничение уникальности, когда конкретное поле Правды

class Process(Place): 
    isRunning = models.BooleanField(default=True) 
    name  = models.CharField(max_length=20) 

Я хотел бы, чтобы обеспечить соблюдение, что name поля является уникальным, когда isRunning верно.

Возможно ли это ограничение в моделях Django?


Это может быть дубликатом this question, но он не имеет общепринятый ответ, и Джанго разработал много, так как это было предложено.

+0

вы можете указать поля '' unique_together' '(https://docs.djangoproject.com/en/1.8/ref/models/options/#unique-together), но это также обеспечит соблюдение того, что 'name' является уникальным среди записи, где 'isRunning' является' false' (т.е. у вас есть две группы уникальных имен) ... в противном случае вы можете сделать обычную [проверку модели] (https://docs.djangoproject.com/en/1.8/ref/models/ instance/# validating-objects), но помните, что он вызывается автоматически при сохранении ModelForm и в Django admin, а не при выполнении 'instance.save()' – Anentropic

ответ

1

Уникальное поле подразумевает, что уникальный индекс строится в базе данных для этого поля.

Теперь, поскольку ваше поле зависит от поля из той же модели, у вас есть возможность проверить это, когда ваша модель сохраняется.

Вы можете переопределить модель СОХРАНИТЬ() метод, как:

def save(self, *args, **kwargs): 
    #check if isRunning is true or not  
    super(Model, self).save(*args, **kwargs) 
+1

Это хорошо и просто. Я бы предпочел оставить свой нос вне SQL, поэтому я поеду по этому маршруту. – ajwood

+0

upvote будет приятным: D –

+1

@ajwood: Просто имейте в виду, что если вы полагаетесь на переопределение 'save()', вы будете ограничены теми методами, которые его используют. В частности, вы не сможете использовать '.update()' и '.bulk_create()'.Преимущество наличия ограничения в базе данных состоит в том, что вы знаете, что оно будет соблюдаться независимо от того, что. –

0

Если ваша база данных поддерживает его можно настроить partial unique index.

Частичный индекс - это индекс, построенный над подмножеством таблицы; подмножество определяется условным выражением (называемым предикатом частичного индекса). Индекс содержит записи только для тех строк таблицы, которые удовлетворяют предикату.

Для этого нет специальной поддержки Django, но вы можете настроить его для переноса данных (см. here для получения дополнительной информации).

В вашем случае это будет выглядеть примерно так:

operations = [ 
    migrations.RunSQL("CREATE UNIQUE INDEX running_name ON app_process(isRunning, name) 
         WHERE isRunning"), 
] 
0

Вы можете добавить дополнительные поля, например stopped_at для записи раз процесс был убит.

И создать уникальное ограничение:

unique_together = ('name', 'stopped_at') 

stopped_at может быть установлено значение Нет или некоторой постоянной величины для новых процессов.

Это ограничение будет гарантировать, что имена уникальны среди запущенных процессов. И остановленные процессы могут иметь одинаковые имена, так как их stop_at всегда разные (надеюсь, или вы могли бы добавить другую информацию в это сложное поле, чтобы гарантировать уникальность остановленных процессов).

Смежные вопросы