我有两个模型:
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
属性
另一种是修改给定查询集的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 %}
模板标签是完美的。
你可以试试:
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})