我有一个Django应用程序,用户上传照片,并在其下留下评论。反映这些对象的数据模型分别为Photo
和PhotoComment
。
第三个数据模型叫PhotoThreadSubscription
。每当用户在照片下发表评论时,用户通过在PhotoThreadSubscription
中创建对象来订阅该特定线程。这样,他/她可以随后被其他用户通知在同一线程中留下的评论。
class PhotoThreadSubscription(models.Model):
viewer = models.ForeignKey(User)
viewed_at = models.DateTimeField(db_index=True)
which_photo = models.ForeignKey(Photo)
每当用户在照片下发表评论时,我都会更新该特定照片的用户viewed_at
对象的PhotoThreadSubscription
属性。因此,其他用户对该特定帖子的提交时间大于viewed_at
的任何评论 new 。
假设我有一个评论的查询集,都属于从不重复的独特照片。我想遍历此查询集并找到最新看不见的评论。
目前,我正在以沉重的数据库方式尝试这一点:
latest_unseen_comment = PhotoComment(id=1) #i.e. a very old comment
for comment in comments:
if comment.submitted_on > PhotoThreadSubscription.objects.get(viewer=user, which_photo_id=comment.which_photo_id).viewed_at and comment.submitted_on > latest_unseen_comment.submitted_on:
latest_unseen_comment = comment
这显然不是一个很好的方法。首先,我不想在for循环中进行DB调用。如何在一个电话中管理上述内容?具体来说,如何在一次调用中获取相关的PhotoThreadSubscription
查询集,接下来,如何使用它来计算 max_unseen_comment ?我现在非常困惑。
class Photo(models.Model):
owner = models.ForeignKey(User)
image_file = models.ImageField(upload_to=upload_photo_to_location, storage=OverwriteStorage())
upload_time = models.DateTimeField(auto_now_add=True, db_index=True)
latest_comment = models.ForeignKey(blank=True, null=True, on_delete=models.CASCADE)
class PhotoComment(models.Model):
which_photo = models.ForeignKey(Photo)
text = models.TextField(validators=[MaxLengthValidator(250)])
submitted_by = models.ForeignKey(User)
submitted_on = models.DateTimeField(auto_now_add=True)
如果问题看起来模糊,请询问澄清。
答案 0 :(得分:2)
我认为这将在一个查询中完成:
latest_unseen_comment = (
comments.filter(which_photo__photothreadsubscription__viewer=user,
which_photo__photothreadsubscription__viewed_at__lt=F("submitted_on"))
.order_by("-submitted_on")
.first()
)
这里的关键是使用F expressions
,以便可以对每个评论的个别日期进行比较,而不是使用查询中硬编码的单个日期。在将查询集过滤为仅包含未见的注释后,我们会order_by
注释的日期并获取第一个。