在django模型中提取OneToOne字段

时间:2016-02-27 16:08:04

标签: python django django-queryset django-orm

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)

我使用这两个模型。 MonthPost是Post的一部分。 我希望在过滤日期小于月份时使用MonthPost。

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

我使用额外的两个以上型号。帖子效果很好,但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)。它只返回id列表。 我需要发布django rest框架的对象列表。

1 个答案:

答案 0 :(得分:0)

我不太了解您尝试使用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'))

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]

上面的代码未经过测试,但可以让您更好地处理如何执行这些类型的查询。