4

ユーザーは、画像、ビデオ、オーディオの3種類のコンテンツをサイトにアップロードできます。各タイプのモデルは次のとおりです。

class ImageItem(models.Model):
    user = models.ForeignKey(User)
    upload_date = models.DateTimeField(auto_now_add=True)
    image = models.ImageField(upload_to=img_get_file_path)
    title = models.CharFiled(max_length=1000,
                             blank=True)

class VideoItem(models.Model):
    user = models.ForeignKey(User)
    upload_date = models.DateTimeField(auto_now_add=True)
    video = models.FileField(upload_to=vid_get_file_path)
    title = models.CharFiled(max_length=1000,
                             blank=True)

class AudioItem(models.Model):
    user = models.ForeignKey(User)
    upload_date = models.DateTimeField(auto_now_add=True)
    audio = models.FileField(upload_to=aud_get_file_path)
    title = models.CharFiled(max_length=1000,
                             blank=True)

と呼ばれるページがあり、ユーザーがアップロードしたすべてのアイテムを、最近アップロードされたものから最も古いアップロードlibrary.htmlの順にレンダリングします(各インスタンスのとが表示され、左側にアイテムの種類を表す小さなアイコンが表示されます)。titleupload_date

3つの個別のクエリが必要だとすると、3つのクエリセットをマージするにはどうすればよいですか?最近アップロードされたものから順番になっていることを確認するにはどうすればよいですか?

4

3 に答える 3

5

別の方法として、マルチテーブル継承を使用して、共通属性をスーパークラスモデルに組み込むことができます。次にorder_by、スーパークラスモデルに日付をアップロードするだけです。サードパーティのアプリdjango-model-utilsは、クエリ内のサブクラスモデルに自動的にダウンキャストできる継承マネージャーと呼ばれるカスタムマネージャーを提供します。

from model_utils.managers import InheritanceManager

class MediaItem(models.Model):
    objects = InheritanceManager()

    user = models.ForeignKey(User)
    upload_date = models.DateTimeField(auto_now_add=True)
    title = models.CharFiled(max_length=1000,
                             blank=True)

class ImageItem(MediaItem):
    image = models.ImageField(upload_to=img_get_file_path)

class VideoItem(MediaItem):
    video = models.FileField(upload_to=vid_get_file_path)

class AudioItem(MediaItem):
    audio = models.FileField(upload_to=aud_get_file_path)

次に、クエリは次のようになります。

MediaItem.objects.all().order_by('upload_date').select_subclasses()

このようにして、1つのクエリ(3つの結合)で必要なものを取得できます。さらに、データはより適切に正規化されており、ページネーションだけでなく、あらゆる種類のより複雑なクエリをサポートするのはかなり簡単です。

それを行わなくても、データベース側とORMの利点が得られない場合でも、抽象基本クラスの継承を使用して、データモデルを概念的に正規化します。

于 2013-02-01T07:24:04.263 に答える
0

attrgetterソートをキーイングする可能性のあるオブジェクトの属性を引き出すために使用できます。

from operator import attrgetter

results = []
results.extend(list(AudioItem.objects.filter(...)))
results.extend(list(VideoItem.objects.filter(...)))
results.extend(list(ImageItem.objects.filter(...))
results.sort(key=attrgetter("upload_date")
于 2013-02-01T07:06:41.853 に答える
0

質問を参照すると、これは私が使用した正確な解決策です。モンクットの答えと彼のコメントのフランツディのリンクからのトップの答えに影響されました(みんなに感謝します)。

from itertools import chain
from operator import attrgetter

images = ImageItem.objects.filter(user=user)
video = VideoItem.objects.filter(user=user)
audio = AudioItem.objects.filter(user=user)
result_list = sorted(chain(images, video, audio),
                     key=attrgetter('upload_date'),
                     reverse=True)
于 2013-02-02T03:21:41.123 に答える