Django:按降序排序查询集的ManyToMany主键

时间:2014-05-29 17:50:49

标签: django

我们说我有照片模型和标签模型

class Post(models.Model):
    user = models.ForeignKey(User, related_name = 'posts_owned')
    created = models.DateTimeField(auto_now_add=True)
    description = models.CharField(max_length=255, blank=True)
    media_url = models.URLField(max_length=225, blank=True)
    related_hashtag = models.ManyToManyField('Hashtag', related_name = 'tagged_post', null=True, blank=True)

class Hashtag(models.Model):
    hashtag = models.CharField(max_length=60, unique = True)
    count = models.IntegerField(default=1)

如何按插入的降序查询ManyToMany字段的帖子? ManyToMany表有每行的主键,我想按ManyToMany字段的ID排序。

我尝试了以下内容:

queryset = Post.objects.filter(related_hashtag__hashtag = hashtag).order_by('-related_hashtag__id')

但这并不奏效。我需要通过related_hashtag表中的PK对其进行排序。

这可能吗?我应该使用原始SQL吗?如果我要使用原始SQL,它会是什么样的?

现在,我这样做:

queryset = Post.objects.filter(related_hashtag__hashtag = hashtag).order_by(-pk)

但问题在于,这是按邮政编码的顺序排序。我还有一个Comment模型,可以从中创建主题标签并将其附加到Post。因此,Post PK的订购不会起作用。任何建议或解决方案?

4 个答案:

答案 0 :(得分:2)

我希望我能理解这个问题。好吧,我试一试。您可以明确定义Post和Hashtag类之间的链接,如下所示:

class Post(models.Model):
    user = models.ForeignKey(User, related_name = 'posts_owned')
    created = models.DateTimeField(auto_now_add=True)
    description = models.CharField(max_length=255, blank=True)
    media_url = models.URLField(max_length=225, blank=True)
    related_hashtag = models.ManyToManyField('Hashtag', related_name = 'tagged_post', null=True, blank=True, through='PostHashtagLinker')

class Hashtag(models.Model):
    hashtag = models.CharField(max_length=60, unique = True)
    count = models.IntegerField(default=1)

class PostHashtagLinker(models.Model):
    hashtag = models.ForeignKey(Hashtag)
    post = models.ForeignKey(Post)

然后你可以形成这样的查询:

orderedPosts = PostHashtagLinker.objects.filter(hashtag=my_hashtag).order_by(-pk).values(post)

(这个有序的帖子列表可能包含重复项。)

答案 1 :(得分:1)

你可以在不定义中间模型的情况下实现与@ steffens21相同的效果:

Post.related_hashtag.through.objects.filter(id=my_hashtag).order_by('-pk').values('post')

问题是它不返回QuerySet,而是返回ValuesQuerySet。它也将包含重复...

答案 2 :(得分:0)

您可以使用extra()修饰符从ManyToMany表中提取pk:

Post.objects.extra(select={
    'm2m_pk': '''
        SELECT id
        FROM appname_post_related_hashtag
        WHERE appname_post_related_hashtag.hashtag_id={}
            AND appname_post_related_hashtag.post_id=appname_post.id
     '''.format(hashtag)
}).order_by('-m2m_pk')

答案 3 :(得分:0)

爵士乐队库django-sortedm2m提供了ManyToManyField的直接替代,其中添加了一个隐藏的订购字段(默认情况下名为“ sort_value_field_name”)。

如他们所说:

提供的SortedManyToManyField的行为与原始行为类似,但记住添加关系的顺序。

我不是为什么他们不使用私钥。