如何在Django中重命名values()中的项目?

Mar*_*tin 86 django django-orm

我想在djangoproject.com的这张票中做同样的事情,但是有一些额外的格式.从这个查询

>>> MyModel.objects.values('cryptic_value_name')
[{'cryptic_value_name': 1}, {'cryptic_value_name': 2}]
Run Code Online (Sandbox Code Playgroud)

我希望得到类似的东西:

>>> MyModel.objects.values(renamed_value='cryptic_value_name')
[{'renamed_value': 1}, {'renamed_value': 2}]
Run Code Online (Sandbox Code Playgroud)

是否有其他更内置的方式或我必须手动执行此操作?

ale*_*dnm 159

django>=1.8您可以使用annotate和F对象

from django.db.models import F

MyModel.objects.annotate(renamed_value=F('cryptic_value_name')).values('renamed_value')
Run Code Online (Sandbox Code Playgroud)

extra()将被弃用,来自django文档:

这是一个旧的API,我们打算在将来的某个时候弃用.仅当您无法使用其他查询集方法表达查询时才使用它.如果您确实需要使用它,请使用您的用例使用QuerySet.extra关键字提交票证(请先检查现有票证列表),以便我们可以增强QuerySet API以允许删除extra().我们不再改进或修复此方法的错误.

  • `MyModel.objects.values(renamed_value = models.F('cryptic_value_name'))`有效 (8认同)
  • 这个答案有效但多余。传递给 `values()` 的关键字参数将代表您通过 `annotate()` 传递(请参阅 https://docs.djangoproject.com/en/2.2/ref/models/querysets/#django.db.models.query .QuerySet.values)。IMO,“MyModel.objects.values(renamed_value=F('cryptic_value_name'))”的答案更简单、更清晰。 (4认同)
  • 这个答案只适用于`django> = 1.8`.查询表达式使`annotate`能够接受聚合以外的表达式.参考:https://docs.djangoproject.com/en/1.9/releases/1.8/#query-expressions-conditional-expressions-and-database-functions (3认同)
  • 它有效,但不是原始问题中提出的语法只是**这么好**?`MyModel.objects.values(renamed_value = 'cryptic_value_name')` (3认同)
  • 这正是我想要的。谢啦。 (2认同)

Dan*_*man 63

这有点hacky,但你可以使用这个extra方法:

MyModel.objects.extra(
  select={
    'renamed_value': 'cryptic_value_name'
  }
).values(
  'renamed_value'
)
Run Code Online (Sandbox Code Playgroud)

这基本上SELECT cryptic_value_name AS renamed_value在SQL中.

另一个选项,如果您总是希望重命名的版本但数据库具有隐藏名称,则使用新名称命名您的字段,但用于db_column引用数据库中的原始名称.

  • -1因为`.values(supports__through_tables)`而且这个hack没有(顺便说一句,可能是想要重命名`ValuesQuerySet`字典键的最明显的用例) (17认同)
  • 不幸的是,这个解决方案不支持像`.values('foreignkeymodel__id','foreignkeymodel__name')`这样的相关名称. (12认同)
  • 来自票证16735的Model.objects.annotate(my_alias = F('some__long__name__to__alias')).values('my_alias'). (12认同)
  • 显然在1.7.*中你可以直接将别名作为命名参数写入`values()`.资料来源:https://code.djangoproject.com/ticket/16735 (5认同)

Arp*_*ngh 54

不使用任何其他管理器方法(测试v2.0.8):

from django.db.models import F

MyModel.objects.values(renamed_value=F('cryptic_value_name'))
Run Code Online (Sandbox Code Playgroud)

  • 对于多个值,您可以使用:``MyModel.objects.values(renamed_value=F('cryptic_value_name'),renamed_value2=F('cryptic_value_name2'))`` (7认同)
  • @Malte我认为没有必要让这件事变得复杂。只需尝试 `inv.values('price', name=F("stock__name"))`。在 python 中,只能将命名参数放在未命名参数之后。 (5认同)
  • @Azzonith,您可以使用关键字参数,例如 `MyModel.objects.values(**{'Renamed value': F('cryptic_value_name')})` (2认同)