【问题标题】:Is it possible to group by field name using django orm?是否可以使用 django orm 按字段名分组?
【发布时间】:2021-05-03 17:58:02
【问题描述】:

我有两个模型:

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,
            },      
      ]
    }
}

有可能吗?我找到的关于分组的所有信息都涉及值(计数、总和......)。但我只想按一个字段(模型一个 id)分组。

【问题讨论】:

    标签: django django-rest-framework django-orm


    【解决方案1】:

    使用 Django ORM 没有直接的方法。

    使用原始 SQL

    一种选择是使用原始 SQL 查询,但正如您指定的那样,您希望使用 ORM 来实现这一目标。

    修改query.group_by属性

    另一个是修改给定查询集的querygroup_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

    【讨论】:

    • 嘿,Le Minaw,谢谢。不同的工作正常。
    【解决方案2】:

    你可以这样做

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

    【讨论】:

      【解决方案3】:

      你可以试试这个:

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

      【讨论】:

        猜你喜欢
        • 2017-03-30
        • 2021-10-23
        • 1970-01-01
        • 2012-04-26
        • 2018-03-10
        • 2018-08-12
        • 2015-12-05
        • 2020-10-27
        • 2011-10-19
        相关资源
        最近更新 更多