是否可以使用 django orm 按字段名称分组?
Is it possible to group by field name using 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})
那个return这个:
{
"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,
},
]
}
}
这可能吗?我找到的所有关于分组的信息都涉及值(计数、总和……)。但我只想按一个字段分组(模型一id)。
使用 Django ORM 没有直接的方法可以做到这一点。
使用原始 SQL
一个选项是使用原始 SQL 查询,但正如您指定的那样,您希望使用 ORM 实现此目的。
修改 query.group_by
属性
另一种方法是修改给定查询集的 query
的 group_by
属性(这将大致翻译成 GROUP_BY
SQL 语句):
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 %}
模板标签非常适合这个。参见 its docs。
你可以做到
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="*")
或者您可以使用 for 循环
data = []
for i in yourmodel:
dicts = {}
dicts["id"] = i.id
dicts["your_data"] = [{i.model_1}]
data.append(dicts)
return Response({"data": data})
你可以试试这个:
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 = ...
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})
那个return这个:
{
"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,
},
]
}
}
这可能吗?我找到的所有关于分组的信息都涉及值(计数、总和……)。但我只想按一个字段分组(模型一id)。
使用 Django ORM 没有直接的方法可以做到这一点。
使用原始 SQL
一个选项是使用原始 SQL 查询,但正如您指定的那样,您希望使用 ORM 实现此目的。
修改 query.group_by
属性
另一种方法是修改给定查询集的 query
的 group_by
属性(这将大致翻译成 GROUP_BY
SQL 语句):
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 %}
模板标签非常适合这个。参见 its docs。
你可以做到
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="*")
或者您可以使用 for 循环
data = []
for i in yourmodel:
dicts = {}
dicts["id"] = i.id
dicts["your_data"] = [{i.model_1}]
data.append(dicts)
return Response({"data": data})
你可以试试这个:
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})