【问题标题】:Order a queryset by a field in another queryset按另一个查询集中的字段对查询集进行排序
【发布时间】:2021-05-29 07:29:50
【问题描述】:

在我的 django 博客应用程序中,我有一个 Bookmark 模型,其中包括指向 Post 和 User 的字段,以及创建书签时间的字段。

# models

class Post(models.Model):
    # ...

    title = models.CharField(max_length=70)
    body = RichTextField()
    author = models.ForeignKey(
        UserProfile,
        on_delete=models.CASCADE,
        related_name='posts')
    created_on = models.DateTimeField(default=timezone.now)

    # ...

    class Meta:
        ordering = ['created_on']


class Bookmark(models.Model):
    post = models.ForeignKey(
        Post, on_delete=CASCADE,
        related_name="bookmarked_post"
    )
    user = models.ForeignKey(
        User, on_delete=CASCADE,
        related_name="bookmarks"
    )
    created_on = models.DateTimeField(default=timezone.now)

    class Meta:
        ordering = ['created_on']

我有一个视图来显示我的用户的书签。我想按照添加书签的顺序对帖子查询集进行排序,最近添加书签的帖子在前。

# views.py

@login_required
def bookmarks_view(request):

    bookmarks = Bookmark.objects.filter(user=request.user)
    bookmarked_posts = Post.objects.filter(
        bookmarked_post__in=bookmarks).order_by(???)

    return render(request, 'bookmarks.html', {'posts': bookmarked_posts})

我正在努力弄清楚如何通过 Bookmark 模型中的 created_on 字段对我的 Posts 查询集进行排序。为了增加额外的复杂性,Post 和 Bookmark 模型都有一个 created_on 字段。

谁能指出我正确的方向?我已经搜索了 django 文档和 SO 并没有找到我需要的东西,可能我只是不知道正确的关键字......还是我错误地设置了我的模型来实现我想要的?

【问题讨论】:

    标签: django sorting django-queryset


    【解决方案1】:

    这样的事情应该可以工作:

    bookmarks = Bookmark.objects.filter(user=u0)
    bookmarked_posts = Post.objects.filter(
        bookmarked_post__in=bookmarks
    ).order_by("-bookmarked_post__created_on")
    

    您可以在末尾删除__created_on - 然后Django 将使用相关模型上指定的默认ordering。开头的- 表示降序,因此较新的日期在前。

    另见the documentation for order_by

    要按不同模型中的字段排序,请使用与跨模型关系查询时相同的语法。也就是说,字段名称后跟双下划线 (__),然后是新模型中的字段名称,依此类推,您想加入多少模型就可以。

    因为您指定了相关名称为bookmarked_post,所以这也是您需要指定的字段名称,从Post的角度来看,就像您在filter中使用的一样。

    没有related_name,它看起来像这样:

    bookmarks = Bookmark.objects.filter(user=u0)
    bookmarked_posts = Post.objects.filter(
        bookmark__in=bookmarks
    ).order_by("-bookmark__created_on")
    

    (请注意,您可能希望在 Bookmark 模型上为 postuser 指定 a unique_together constraint,以确保每个用户只能为帖子添加一次书签)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-13
      • 2020-08-16
      • 1970-01-01
      • 2012-09-30
      • 1970-01-01
      • 2020-08-18
      • 2020-10-22
      • 2020-10-24
      相关资源
      最近更新 更多