是否可以使用django orm按字段名分组?



我有两个模型:

class ExampleOne(models.Model):
# some fields

class ExampleTwo(models.Model):
example_one = models.ForeignKey(
"App.ExampleOne",
on_delete=models.CASCADE,
related_name="examples",
)
field_one = ...
field_two = ...

我为端点创建了这个视图:

class MyViewSet(viewsets.ViewSet):
def list(self, request):
queryset = ExampleOne.objects.all().values(
"id",
"examples__field_one",
"examples__field_two",
)
return Response({"data": queryset})

返回这个:

{
"data": [
{
"id": 1,
"examples__id": 1,
"examples__field_one": foo,
"examples__field_two": bar,
},
{
{
"id": 1,
"examples__id": 2,
"examples__field_one": foo,
"examples__field_two": bar,
},
{
"id": 2,
"examples__id": 3,
"examples__field_one": foo,
"examples__field_two": bar,
}

但是我想要一种按第一个模型分组的方法。这是可能的吗?我想要这样的东西:

{
"data": [
{
"1": [
{
"examples__id": 1,
"examples__field_one": foo,
"examples__field_two": bar,
},
{
"examples__id": 2,
"examples__field_one": foo,
"examples__field_two": bar,
},      
],
"2": [
{
"examples__id": 3,
"examples__field_one": foo,
"examples__field_two": bar,
},      
]
}
}

这是可能的吗?我找到的关于分组的所有信息都涉及值(count, sum,…)。但是我只想按一个字段(模型id)分组。

在Django ORM中没有直接的方法。

使用原始SQL

一种选择是使用原始SQL查询,但偏离主题,因为您指定要使用ORM实现此目标。

修改query.group_by属性

另一种是修改给定查询集的querygroup_by属性(这将大致转换为GROUP_BYSQL语句):

qs = MyModel.objects.all()
qs.query.group_by = ['my_field']

这是而不是建议使用它,因为它不是一个文档化的API,并且它可能(将会)在您的查询集上做不必要的东西。

自己创建字典

另一个选择是不直接使用ORM:

group_by_values = MyModel.objects.values_list(
'group_by_field', flat=True
).distinct() # This is a list of all existing values for group_by_field
result = {
value: MyModel.objects.filter(group_by_field=value)
for value in group_by_values
}
<标题>

第三方选择最后一个选择是使用第三方库,比如django-group-by。

当处理模板显示时(与你无关)

{% regroup %}模板标签是完美的。

你可以试试:

queryset_data={}
for e in queryset:
if e.value('id') not in new_data :
new_data[e.value('id')]=[e.value("examples__id","examples__field_one","examples__field_two")]
else :
new_data[e.value('id')].append(e.value("examples__id","examples__field_one","examples__field_two"))
return Response({"data": queryset_data})

你可以这样做


class ExampleOne(models.Model):
# some fields

class ExampleTwo(models.Model):
example_one = models.ForeignKey(
"App.ExampleOne",
on_delete=models.CASCADE,
related_name="examples",
)
field_one = ManyToManyField(YourModel, related_name="*")
field_two = ManyToManyField(YourModel, related_name="*")

或者使用forloop

data = []
for i in yourmodel:
dicts = {}
dicts["id"] = i.id
dicts["your_data"] = [{i.model_1}]
data.append(dicts)
return Response({"data": data})

相关内容

最新更新