Как в Django обеспечить связь между таблицами без использования ограничений?
Я создаю простое приложение со списком, в котором есть группы и элементы, каждый из которых имеет связанного с ним пользователя. Как я могу обеспечить в модели, чтобы элемент, созданный одним пользователем, никогда не мог быть связан с группой, созданной другим пользователем? Вот модель:
class Group(models.Model):
name = models.CharField(max_length=200)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class Item(models.Model):
name = models.CharField(max_length=200)
group = models.ForeignKey(Group, on_delete=models.PROTECT)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
Я выяснил, что это невозможно сделать с помощью CheckConstraint в class Meta, потому что ограничения, очевидно, делаются в самой базе данных (я использую postgres), а межтабличные ограничения не разрешены.
Кодируя без фреймворка, вы просто запросите группу перед сохранением ссылки и выбросите исключение, если пользователи не совпадут. Как же это сделать в django?
Я понял это несколько мгновений спустя. Из документации:
https://docs.djangoproject.com/en/4.0/topics/db/models/#overriding-predefined-model-methods
Вы можете переопределить метод save() в классе Item, чтобы предварительно выполнить проверку:
from django.db.utils import IntegrityError
.
.
def save(self, *args, **kwargs):
# if no user is given don't fail here; instead let normal integrity check catch it
if hasattr(self, 'user') and self.user != self.group.user:
raise IntegrityError("Item user must match group user")
super().save(*args, **kwargs)
Но я оставлю это открытым на случай, если есть лучший способ...