Рассмотрите систему бронирования номеров. У вас могут быть модели здания, пола, комнаты, а также бронирование. Мы даем комнате название основано на его здании и пол:Django обмен мнениями между связанными предметами
class Room(models.Model):
number = models.PositiveIntegerField()
name = models.CharField(..)
floor = models.ForeignKey('Floor')
def __str__(self):
return '%s, #%d Floor %d, %s' % (
self.name,
self.number,
self.floor.number,
self.floor.building.name
)
Это крайне неэффективно, когда вы делаете сотни из них (например, список администратора, большие отчеты и т.д.), поэтому я принял в письменной форме менеджеров:
class RoomManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
roomname=Concat(
'name',
V(', #'),
'number'
V(' Floor '),
'floor__number'
V(', '),
'floor__building__name',
output_field=models.CharField()
),
)
И что работает. Он делает все, что я хотел. Это быстро, и я переработал __str__
, чтобы сделать if hasattr(self, 'roomname'): return self.roomname
, прежде чем он сделает ужасный многострочный построитель строк.
Но теперь вместо этого у меня есть Бронирование. Каждый экземпляр бронирования связан с одной комнатой. Есть много случаев, когда перечислять заказы, я на самом деле также перечисляю имена комнат.
Что я сделал это написать BookingManager:
class RoomManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
roomname=Concat(
'room__name',
V(', #'),
'room__number'
V(' Floor '),
'room__floor__number'
V(', '),
'room__floor__building__name',
output_field=models.CharField()
),
)
Но что, черт возьми? Я повторяюсь. Django - все о DRY, и здесь я копирую и вставляю огромную грязную аннотацию. Это отвратительно.
Мой вопрос ... Есть ли другой способ?
это выглядит, как вы пытаетесь заставить вид на модель - если вам нужен метод, который возвращает полный «хлебных крошек» экземпляра, вы могли бы просто написать метод (по каждой модели), которая добавляет свой имя на корневой части родительского элемента - это будет относиться к базовому классу - зачем использовать аннотации запросов? – MarZab
, если вам действительно нужно отредактировать набор запросов, я думаю, что вы могли бы также построить аннотацию, используя этот метод. – MarZab
Если имя комнаты используется повсюду, почему бы просто не добавить его как столбец db? Комбинация номера с номером/зданием не похожа на то, что часто менялось бы, если вообще когда-либо. – serg