Django:按外键分组项目
Django: group items by foreign key
我有如下评论和post模特
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
parent = models.ForeignKey('self', unique=False, blank=True, null=True, on_delete=models.CASCADE)
class Post(models.Model):
title = models.CharField(max_length=120, null=False, blank=False)
我使用这个原始 sql 查询来获取所有具有 post_id 11 的评论并对结果进行分组。
all_comments = Comment.objects.raw('SELECT * FROM comments_comment where post_id=11 order by coalesce(parent_id, id), (case when parent_id is null then 1 else 2 end ), created_at')
这个查询对我来说完全没问题。但是,我想以 Django 方式进行查询而不是使用原始查询。 Django 的等价物是什么?
我们可以 .annotate(..)
[Django-doc] 使用我们想要订购的标准。例如,我们可以用 pid
引用 Coalesce(…)
,用 type
引用 case when … then … else … end
:
from django.db.models import Case, IntegerField, Value, When
from django.db.models import Coalesce
Comment.objects.filter(
post_id=11
).annotate(
pid=Coalesce('parent_id', 'id'),
type=Case(
When(parent_id__isnull=True, then=Value(1))
default=Value(2),
output_field=IntegerField()
)
).order_by(
'pid', 'type', 'created_at'
)
我有如下评论和post模特
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
parent = models.ForeignKey('self', unique=False, blank=True, null=True, on_delete=models.CASCADE)
class Post(models.Model):
title = models.CharField(max_length=120, null=False, blank=False)
我使用这个原始 sql 查询来获取所有具有 post_id 11 的评论并对结果进行分组。
all_comments = Comment.objects.raw('SELECT * FROM comments_comment where post_id=11 order by coalesce(parent_id, id), (case when parent_id is null then 1 else 2 end ), created_at')
这个查询对我来说完全没问题。但是,我想以 Django 方式进行查询而不是使用原始查询。 Django 的等价物是什么?
我们可以 .annotate(..)
[Django-doc] 使用我们想要订购的标准。例如,我们可以用 pid
引用 Coalesce(…)
,用 type
引用 case when … then … else … end
:
from django.db.models import Case, IntegerField, Value, When
from django.db.models import Coalesce
Comment.objects.filter(
post_id=11
).annotate(
pid=Coalesce('parent_id', 'id'),
type=Case(
When(parent_id__isnull=True, then=Value(1))
default=Value(2),
output_field=IntegerField()
)
).order_by(
'pid', 'type', 'created_at'
)