Оформление и ограничение связей в django
В проекте есть 4 модели. Первая содержит все объекты, их категорию и какие-то характеристики. Вторая - все возможные связи объект - дочерний объект. Третья - связи объект - категория дочернего объекта. Четвёртая - конфликты объектов.
class Item(models.Model):
name = models.CharField(max_length=250)
...
category = models.CharField(max_length=250)
class Connection(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
child_item = models.ForeignKey(Item, on_delete=models.CASCADE)
class ChildCategory(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
child_category = models.ForeignKey(????????, on_delete=models.CASCADE)
required = models.IntegerField(blank=True)
class Conflict(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
conflict_item = models.ForeignKey(Item, on_delete=models.CASCADE)
Представляется, всё должно работать таким образом, что:
- У выбранного пользователем объекта программа определяет категории дочерних объектов. Количество категорий дочерних объектов у объекта = количество возможных связей от объекта.
- Выбирает все возможные дочерние объекты, группируя по категориям.
- Для дочерних объектов делает то же самое, что в пункте 1.
- Доходит до объектов, у которых нет вариантов дочерних, и получает древо возможных вариантов.
- Граф(ограниченный условиями пользователя, единственностью каждого объекта в структуре и конфликтами в 4й таблице - когда один объект есть, второго нет) проходит по древу, определяя наилучший вариант структуры.
Во всех таблицах, кроме 3й, просто связи один к одному, как мне кажется (хотя, могу ошибаться). А в третьей совсем не уверен. Должно ли вместо вопросов стоять просто Item.category, или это связь один ко многим? Где и как тогда указывать программе, что выбирать надо дочерний объект из группы с такой-то категорией?
Ответы (1 шт):
В первой модели ты хранишь объекты и их категории. Так как дочерние объекты это по сути те же сами объекты, то получается, что ты в ней же хранишь и категории дочернего объекта. Во второй модели ты хранишь связи между объектами. По сути во второй таблице у тебя уже хранятся связи между объектом и категориями дочерних объектов(так как сами категории хранятся там же где и сам объект). поэтому, вообще не понятна необходимость в третьей модели.
Я бы вынес категории в отдельную модель, что бы избежать разночтения, когда у тебя ссылка на объект Item является в одном случае ссылкой на объект, в другом случае на категорию.
class Category(models.Model):
name = models.CharField(max_length=250)
...
class Item(models.Model):
name = models.CharField(max_length=250)
category = models.ForeignKey(Category)
class Connection(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
child_item = models.ForeignKey(Item, on_delete=models.CASCADE)
по сути модель Connection можно упразднить, добавив в модель Item
children = models.ManyToMany('Item', related_name='parents')
или, если хочется оставить модель, на случай, если планируются какие-либо дополнительный характеристики для этой связи в дальнейшем указывать, то можно добавить в Item
connections = models.ManyToMany('Item', related_name='connections', through='Connection',)
class Conflict(models.Model)
аналогично с предыдущей моделью, либо упраздняем, либо просто добавляем в Item
conflicts = models.ManyToMany('Item', related_name='conflicts', through='Conflict')
теперь, если нужно отдельно сохранять список дочерних категорий, для каждого объекта, тогда получается
class ChildCategory(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
child_category = models.ForeignKey(Category, on_delete=models.CASCADE)
required = models.IntegerField(blank=True)
опять таки, в модель Item добавляем строку
children_categories = models.ManyToMany(Category, related_names='children_categories', through='ChildCategory')