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

4

假设我有一个照片模型和一个标签模型

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')

但这是不起作用的。我需要按相关哈希表中的PK进行排序。

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

目前,我是这样做的:

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

但是问题在于,它按照帖子ID的降序排列。我还有一个评论模型,从中可以创建和附加到帖子上的标签。所以按照帖子PK进行排序是行不通的。有什么建议或解决方案吗?

4个回答

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)

(这个带有顺序的文章列表可能会包含重复内容。)

谢谢您的快速回复,但问题在于这基本上就是related_hashtag表所做的事情。related_hashtag表是您的PostHashtagLinker。 - deadlock

1

您可以不定义中间模型也实现与@steffens21相同的功能:

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

问题在于它不返回QuerySet,而是ValuesQuerySet。而且它也会包含重复项...

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')

0
爵士乐队库django-sortedm2m提供了一个可直接替换ManyToManyField的功能,该功能添加了一个隐藏的排序字段(默认情况下命名为“sort_value_field_name”)。
正如他们所说:

提供的SortedManyToManyField的行为方式类似于原始的字段,但它会记住添加关系的顺序。

虽然我不知道他们为什么不使用私钥。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接