Лучший способ моделирования текущей версии/одного элемента поднятого списка в Django?
Предположим, я Санта Клаус и делаю сайт для отслеживания рождественских списков детей. У меня может быть что-то вроде этого:
class Kid(models.Model):
name = models.CharField()
class Gift(models.Model):
name = models.CharField()
class WishList(models.Model):
date_received = models.DateTimeField()
kid = models.ForeignKey(Kid, on_delete=CASCADE)
Я реализовал модель WishList, вместо того чтобы просто связать Gifts с Kids с помощью ForeignKeys напрямую, потому что я хотел бы отслеживать отдельные рождественские списки желаний дискретно. Я хочу архивировать все старые рождественские списки по мере их получения. Наиболее очевидным способом реализации этого было бы добавить что-то вроде current = models.BooleanField()
в класс WishList, а затем фильтровать по wishlist.current=true
, когда я хочу получить текущий список желаний для данного ребенка. Однако с этим есть две проблемы: 1. Я не знаю, как алгоритм запросов к базе данных работает за кулисами, и я не хочу заставлять компьютер просматривать каждый список, чтобы найти текущий, когда 99% времени это единственный список, который я буду просматривать, и 2. Это не помешает мне иметь два текущих списка желаний, и я не хочу писать специальный код валидатора, чтобы убедиться в этом.
Второй вариант, о котором я подумал, - просто отображать последний полученный список желаний. Однако это не удовлетворяет всем моим потребностям - я могу столкнуться с тем, что ребенок напишет мне: "Подожди, вообще-то, не обращай внимания на список, который я отправил в октябре, и используй тот, который я отправил в августе". Конечно, я мог бы сделать копию августовского списка с сегодняшней датой, но это кажется ненужным и запутанным.
Третьим вариантом, о котором я подумал, было то, что я мог бы избавиться от поля ForeignKey в WishList, и вместо этого поместить ссылки в модель Kid:
class Kid(models.Model):
name = models.CharField()
current_wishlist = models.OneToOneField(WishList)
archived_wishlists = models.ManyToManyField(WishList)
Последний вариант кажется наиболее перспективным, но я не знаком с OneToOneFields и ManyToManyFields и не уверен, что это лучшая практика. Кроме того, не хочется иметь два отдельных поля для одного типа отношения модели. Может ли кто-нибудь подсказать мне, как лучше всего решить эту задачу?
Я не уверен, что это лучший способ, но вы также можете сделать что-то вроде:
class Kid(models.Model):
name = models.CharField()
current_wishlist = models.ManyToManyField(Gift)
archived_wishlists = models.ManyToManyField(Gift)
и при архивировании подарка просто сделайте
kidObj.current_wishlist.remove(giftObj)
kidObj.archived_wishlist.add(giftObj)
и их просмотр
listofgifts = kidObj.current_wishlist.all()
powerrangergifts = kidObj.current_wishlist.filter(name__icontains='Power Ranger')
archived_wishlists = models.ManyToManyField(WishList)
это работает, но теперь вы можете добавить один вишлист к нескольким детям kid - whishlist является отношением "один-много", поэтому вы должны поместить внешний ключ в модель "много"
- Я не знаю, как алгоритм запросов к базе данных работает за кулисами, и я не хочу заставлять компьютер просматривать каждый список, чтобы найти текущий, когда 99% времени это единственный список, который я буду просматривать
.
Ну, тебе не обязательно знать
- это не мешает мне иметь два текущих списка желаний, и я не хочу писать специальный код валидатора для обеспечения этого.
тогда выбирайте OnetoOne, но вы должны убедиться, что ребенок соответствует тому, который указан в вишлисте