在 django 模型中提取 OneToOne 字段

Extract OneToOne Field in django model

class Post(models.Model):
    created_time = models.DateTimeField()
    comment_count = models.IntegerField(default=0)
    like_count = models.IntegerField(default=0)
    group = models.ForeignKey(Group)

class MonthPost(models.Model):
    created_time = models.DateTimeField()
    comment_count = models.IntegerField(default=0)
    like_count = models.IntegerField(default=0)
    group = models.ForeignKey(Group)
    post = models.OneToOneField(Post)

我用的是这两款。月 Post 是 Post 的一部分。 当筛选日期小于月份时,我想使用月份Post。

_models = Model.extra(
            select={'score': 'like_count + comment_count'},
            order_by=('-score',)
        ) 

以上两款我用的比较多。 Post 很好用,但是 MonthPost 不行。

django.db.utils.ProgrammingError: column reference "like_count" is ambiguous
LINE 1: ... ("archive_post"."is_show" = false)) ORDER BY (like_count...

这是错误信息。

_models.values_list("post", flat=True)

然后,我想从 MonthPost 中提取 OneToOne 字段 (post)。 我尝试使用 values_list("post", flat=True)。它 return 只有 id 列表。 我需要 post django rest 框架的对象列表。

我不太明白你想用你的 MonthPost 模型实现什么以及为什么它会重复 Post 字段。话虽如此,我认为您可以通过此信息获得想要的结果。

首先extra折旧见docs on extra。在任何一种情况下,您的 select 都是无效的 SQL 语法,您的查询应该更像这样:

annotate(val=RawSQL(
            "select col from sometable where othercol =%s",
            (someparam,)))

但是,您在这里所追求的既不需要额外的也不需要 RawSql。这些方法只应在没有内置方法来实现所需结果时使用。使用 RawSql 或 extra 时,您必须为您的特定支持定制 SQL。 Django 内置了此类查询的方法:

qs = Post.objects.all().annotate(
    score=(Count('like_count') + Count('comment_count'))

A values_list() 查询需要显式列出相关模型中的所有字段以及额外或带注释的字段。对于 MonthPost,它应该如下所示:

MonthPost.objects.all().values_list('post', 'post__score', 'post__created_time')

最后,如果 MonthPost 的目的只是列出给定月份得分最高的帖子,您可以完全消除 MonthPost 模型并查询您的 Post 这个模型。

import datetime
today = datetime.date.today()

# Filter for posts this month
# Annotate the score
# Order the results by the score field
qs = Post.objects\
         .filter(created_time__year=today.year, created_time__month=today.month)\
         .annotate(score=(Count('like_count') + Count('comment_count'))\
         .order_by('score')

# Slice the top ten posts for the month
qs = qs[:10]

上面的代码没有经过测试,但应该能让您更好地掌握如何执行这些类型的查询。