用户可以在我们的网站上传三种不同类型的内容:图片,视频,音频。以下是每种类型的模型:
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
的页面,它按照从最近上传的到最早上传的顺序呈现用户上传的所有项目(显示title
和每个实例的upload_date
,并在左侧放置一个小图标,表示它是什么类型的项目。
假设它需要三个单独的查询,我如何合并三个查询集?如何确保它们最近上传的顺序?
答案 0 :(得分:5)
作为替代方案,您可以使用multi-table inheritance并将公共属性因子分解为超类模型。然后你只需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()
这样,只需一个查询就可以得到你想要的东西(有3个连接)。此外,您的数据更加规范化,并且支持各种更复杂的查询以及分页非常简单。
即使您没有这样做,我仍然会使用abstract base class inheritance来概念化您的数据模型,即使您没有获得数据库端和ORM权益
答案 1 :(得分: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")
答案 2 :(得分:0)
参考问题,这是我使用的确切解决方案。受到monkut答案的影响以及Frantzdy在评论中的链接的最佳答案(谢谢你们)。
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)