简体   繁体   中英

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)

I use this two models. MonthPost is part of Post. I want to use MonthPost when filtered date is smaller than month.

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

I use extra about above two models. Post works well, but MonthPost doesn't work.

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

This is the error message.

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

And then, I want to extract OneToOne field(post) from MonthPost. I try to use values_list("post", flat=True). It return only id list. I need to post object list for django rest framework.

I don't' quite understand what you are trying to achieve with your MonthPost model and why it duplicates Post fields. With that being said I think you can get the results you want with this info.

First of all extra is depreciated see the docs on extra . In either case, your select is not valid SQL syntax, your query should look more like this:

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

However, what you are after here requires neither extra or RawSql. These methods should only be used when there is no built in way to achieve the desired results. When using RawSql or extra, you must tailor the SQL for your specific backed. Django has built in methods for such queries:

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

A values_list() query needs to explicitly list all fields from related models and extra or annotated fields. For MonthPost it should look like this:

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

Finally, if the purpose of MonthPost is simply to list the posts with he greatest score for a given month, you can eliminate the MonthPost model entirely and query your Post model for this.

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]

The code above is not tested, but should give you a better handle on how to perform these types of queries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM