Добавление ограничения на модели Django на основе значений другого поля - PullRequest
1 голос
/ 26 июня 2019

У меня есть простая модель с 1 первичным ключом и 3 полями (упрощенно):

  • проходной балл
  • Максимальный балл
  • Макс. Попытка

Эта модель создана путем наследования от django.db.models. Это минимальный воспроизводимый код:

from django.db import models
class QuestionSet(models.Model):
    passingscore = models.PositiveSmallIntegerField("passing score")
    maxscore = models.PositiveSmallIntegerField("max score")
    maxattempt = models.PositiveSmallIntegerField("max attempt")

Я хотел бы добавить ограничение, чтобы passingscore никогда не превышало maxscore в базе данных.

Я использовал ограничение, охватывающее несколько полей, например unique_together, согласно этого потока в StackOverflow . Но ясно, что это другой вариант использования.

Я также кратко рассмотрел возможность добавления ограничения непосредственно при написании кода PostgreSQL:

ALTER TABLE tableB ADD CONSTRAINT score_policy_1 CHECK (maxscore >= passingscore) 

Но это противоречит цели использования ORM и нарушает философию «слабо связанных», что затрудняет миграцию между различными бэкэндами базы данных.

Если это вообще возможно, пожалуйста, укажите мне более идиоматический способ написания этого ограничения в Django.

1 Ответ

1 голос
/ 26 июня 2019

Вы можете сделать это либо в слое вида, либо в слое БД.

Если вы хотите сделать это на уровне БД, вы можете переопределить метод save модели и проверить там значения:

def save(self, *args, **kwargs):

    if self.passingscore > self.maxscore:
        raise ValueError("passingscore can't be greater than maxscore")

    super().save(*args, **kwargs)

Если вы хотите справиться с ограничениями базы данных, вы можете создать свой собственный класс ограничений, создав подкласс BaseConstraint и поместив свой sql в метод constraint_sql.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...