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

У меня есть модель Item, которая обратно связана с двумя другими моделями (ItemComponent и ItemComponentCategory). Идея заключается в том, что я хотел бы иметь возможность проверить, что Item имеет не более 4 связей с двумя другими моделями, вместе взятыми, перед сохранением.

class Item(models.Model):
    name = models.CharField(max_length=40, unique=True)

class ItemComponent(models.Model):
    parent_item = models.ForeignKey(Item, related_name='components')

class ItemComponentCategory(models.Model):
    parent_item = models.ForeignKey(Item, related_name='categories')

Я хотел бы создать проверку, которая вызывает ошибку перед сохранением объектов Item, ItemComponent или ItemComponentCategory, если сохраненные объекты приведут к > 4 объектным отношениям между ними.

Я попробовал добавить что-то вроде этого в методы очистки для всех трех:

    def clean(self):

        if (self.parent_item.components.count() + self.parent_item.categories.count()) > 4:
            raise ValidationError(_(f'Items can have no more than 4 components and/or component categories'))

Это, кажется, работает, пока предметы и их отношения уже сохранены с 4, и вы пытаетесь добавить больше отношений.

Однако, если я создам TabularInline в ItemAdmin для добавления этих "подтипов", если хотите... Я могу создать новый элемент и добавить столько же этих подтипов и сохранить его без проблем.

Что я здесь упускаю?

Похоже, моя проблема связана со временем и порядком процессов.

При сохранении страницы администратора с инлайн-ссылками сначала сохраняется модель главной страницы, а затем инлайн-объекты. Это создает проблему при попытке использовать метод clean() модели для проверки отношения, поскольку оно просто еще не существует.

Как упоминается в статье THIS, кажется, что мое решение заключается в изменении функций modelAdmin, чтобы убедиться, что сначала сохраняются встроенные объекты, а затем проверяются основные объекты после их сохранения.

Также, я думаю, что этот метод save_related для modelAdmin пригодится.

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