Django:对查询集值使用自定义方法()

Posted

技术标签:

【中文标题】Django:对查询集值使用自定义方法()【英文标题】:Django: use custom methods for queryset values() 【发布时间】:2013-11-23 08:34:06 【问题描述】:

我正在尝试使用模型中的自定义方法作为 QuerySet 对象的值方法中的字段。

型号:

class MyModel(models.Model):
    field1
    field2
    field3
    ...

    def custom_method(self):
        return 'somestring'

在另一个模块中,我正在尝试这个:

MyModel.objects.all().values('field1', 'field2', 'custom_method').annotate(field3Tot= Sum('field3'))

我需要按 field1field2custom_method 对总和进行分组。这是可能的还是我只能使用像 field1...这样的“真实”字段?

【问题讨论】:

据我所知,您仅限于“真实”字段,即“模型字段定义”。也许自定义字段可能是您的解决方案,但我不确定。 【参考方案1】:

您不能。values() 根据传递给该模型的字段返回结果集。 如果您将传递任何自定义方法,它将不起作用。

【讨论】:

那我们应该如何解决这个问题,任何想法都会很棒。谢谢【参考方案2】:

不幸的是,现在不可能。 Django queryset 将您的查询表达式转换为 SQL,因此将自定义方法转换为 SQL 是一项过于复杂的任务。

可以通过queryset的extra方法实现自定义字段表达式。 例如:

MyModel.objects.extra(select='custom_field': "'some string or expr'")
.values('field1', 'field2', 'custom_field')

但是这里不能使用annotate,queryset raise FieldError: Cannot resolve keyword 'custom_field' into field. grouping 会被python执行。

另一种方式 - 使用raw qerysets 例如:

MyModel.objects.raw("select max(id) as id, 'some string or expr' as custom_field 
from table group by custom_field")

【讨论】:

【参考方案3】:

也许有一种更复杂的方法来覆盖/修改 QuerySet 类

我发现我解决这个问题的方法就是制作一个迭代器

class Person(models.Model):

    first_name = models.CharField(...)
    last_name = models.CharField(...)
    dob = models.DateTimeField(...)

    def full_name(self):
        return self.first_name + ' ' + self.last_name

然后我试图做出一个 json 响应来混合字段和方法

 jsonresponse = []
 for person in Person.objects.all():
     jsonresponse.append("name": person.full_name(), "birthdate" :  person.dob)

 return JsonResponse("results":jsonresponse)

【讨论】:

以上是关于Django:对查询集值使用自定义方法()的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 自定义方言

init是一个自定义方法名

Hibernate 3.6动态方言解析器

防止 ASP.NET Web API 路由引擎扣除自定义方法名

ASP.NET Web API 中的自定义方法名称

在admin中添加自定义actions并填写自定义参数