«Правильный» способ определения вспомогательных функций для мета-классов моделей Django

Я пытаюсь упростить очень многословное и повторяющееся ограничение Check для модели, логику которой в настоящее время очень трудно разобрать, вычитая и метко переименовывая повторяющиеся части.

В принципе, я хочу сделать так (упрощенный и абстрагированный фрагмент):

class MyModel(models.Model):
    class Meta:
        constraints = [
            models.CheckConstraint(
                check = (
                    (
                        models.Q(foo = True)
                        & (
                            (
                                models.Q(field1 = 'X')
                                & models.Q(field2 = 'Y')
                                & models.Q(field3 = 'Z')
                            )
                            |
                            (
                                models.Q(field4 = 1)
                                & models.Q(field5 = 2)
                                & models.Q(field6 = 3)
                            )
                        )
                    )
                    |
                    (
                        models.Q(foo = False)
                        & (
                            (
                                models.Q(field1 = 'X')
                                & models.Q(field2 = 'Y')
                                & models.Q(field3 = 'Z')
                            )
                            |
                            (
                                models.Q(field4 = 4)
                                & models.Q(field5 = 5)
                                & models.Q(field6 = 6)
                            )
                        )
                    )
                ),
                name = 'foo',
            ),
        ]

В этом:

class MyModel(models.Model):
    class Meta:
        constraints = [
            models.CheckConstraint(
                check = (
                    (
                        models.Q(foo = True)
                        & (
                            condition1
                            |
                            condition2
                        )
                    )
                    |
                    (
                        models.Q(foo = False)
                        & (
                            condition1
                            |
                            condition3
                        )
                    )
                ),
                name = 'foo',
            ),
        ]

Что я пробовал/думал попробовать:

  1. Выделение условий, как в виде атрибутов, так и в виде методов в самой Мета; это не помогло: TypeError: 'class Meta' got invalid attribute(s): condition1,condition2,condition3;
  2. Факторизация условий, как атрибутов, так и методов в MyModel; это, конечно, не сработает, так как вы не можете напрямую ссылаться MyModel изнутри Meta;
  3. Выделение условий в качестве атрибутов в корне models.py (следовательно, вне Meta и MyModel); это сработало; однако это оставляет условия слабо связанными с MyModel и его Meta, что нежелательно в данном случае, так как эти условия строго привязаны к обоим, и они не предназначены для повторного использования в любом случае.

Поэтому, несмотря на то что проблема была решена простым помещением условий в другое место, мне стало интересно: есть ли элегантный способ сделать то же самое, но сохранив строгую связь между условиями и MyModel или его Meta классом ?

Вернуться на верх