部屋予約システムを考えてみましょう。あなたは、Building、Floor、Roomのモデルと予約を持っているかもしれません。私たちは、その建物や床に基づいて部屋に名前を付ける: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__
を修正してから、恐ろしいマルチクエリ文字列ビルダーを実行します。
今のところ私は予約をしています。各予約インスタンスは1つの部屋にリンクされています。 Bookingsをリストするケースは多くありますが、実際に部屋の名前も記載しています。
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()
),
)
しかし、どのような地獄:私は何をやったか
はBookingManagerを書くのですか?私は自分自身を繰り返している。 DjangoはDRYに関するもので、ここで私は厄介なアノテーションをコピーして貼り付けています。嫌な感じです。
私の質問は...別の方法がありますか?
これは、ビューをモデルに強制的に挿入しようとしているようです。インスタンスの完全な「ブレッドクラム」を返すメソッドが必要な場合は、そのモデルを追加するメソッドその親のブレッドクラム上の名前 - それは基本クラスに再帰します - なぜクエリーセット注釈を使用していますか? – MarZab
実際にクエリセットを編集する必要がある場合は、このメソッドを使用して注釈を作成することもできます。 – MarZab
ルーム名がどこでも使用されている場合は、単にdbカラムとして追加するだけです。床/建物/部屋番号の組み合わせは、これまでになく頻繁に変更されるようなものではありません。 – serg