【问题标题】:Django rename column when multiple tables are joined连接多个表时Django重命名列
【发布时间】:2025-12-10 15:35:01
【问题描述】:

我在models.py中有这个类:

class Customer(models.Model):
    code = models.CharField(unique=True, max_length=10)
    user = models.OneToOneField(User, on_delete=models.PROTECT)
    phone = models.CharField(max_length=20)
    address = models.TextField(blank=True)
    balance = models.PositiveIntegerField(default=20000)

Customer 与 User 类是一对一的关系。 User 类是 Django 中默认的 User 类:

from django.contrib.auth.models import User

我想返回这样的结果:

    "customers": [
        {
            "code": a1,
            "username": "arashb91",            
            "email": "arash@example.com",
            "phone": "111111",
            "address": "somewhere",
            "balance": 20000
        },
 

但是当我使用这段代码时:

result = Customer.objects.all().values("code", 'user__username', 'user__email', "phone", "address", "balance")

我的结果会是这样的:

    "customers":
        {
            "code": a1,
            "user__username": "arashb91",
            "user__email": "arash@example.com",
            "phone": "111111",
            "address": "somewhere",
            "balance": 20000
        },

我可以通过F方法重命名字段:

result = Customer.objects.all().values("code", username=F('user__username'),
                                       email=F('user__email'), "phone", "address", "balance")

但我在“电话”、“地址”、“余额”上收到此错误:

Positional argument after keyword argument

"code" 没问题,因为它在 F 方法之前。 结果顺序对我来说很重要。

我也不能使用此代码(其他字段为 F):

result = Customer.objects.all().values("code", username=F('user__username'),
                                       email=F('user__email'), phone=F("phone"))

因为我收到此错误:

The annotation 'phone' conflicts with a field on the model.

我不希望我的结果是这样的: 其他表__字段

为了解决我的问题,我使用 python 代码重命名字典键,但这不是一个好的选择。 我该怎么办? 有什么简单的解决办法吗?

【问题讨论】:

  • values之前使用annotate
  • 非常感谢。我使用了 annotate ,但不是在值之前
  • 注释更改顺序:
  • lookups = Customer.objects.all().annotate(username=F("user__username")).values("code", 'username', "balance")) :余额在代码之后结果,不是在用户名之后

标签: python django django-models jsonresponse


【解决方案1】:

首先,如果您使用的是.values(),则可以跳过.all() 其次,这里是解决方案:

result = Customer.objects.values("code", "phone").annotate(
    username=F('user__username'), 
    email=F('user__email')
)

【讨论】:

  • 它改变了结果中的顺序:“电话”在结果中的“代码”之后而不是在用户名和电子邮件之后。你有什么建议?因为我的项目中存在这个问题,不仅针对客户模型。也适用于我创建的其他模型。我想用 Json 返回结果。所以顺序在答案中很重要。
【解决方案2】:

也许你可以使用额外的东西

address = Customer.objects.extra(select={'code': 'code', 'user__username': 'username', 'user__email': 'email'})

【讨论】:

  • 也许我可以使用它。但请正确语法。我做了类似你的代码的事情,但我得到了这个错误:“没有这样的列:user__username”
  • 这取决于您和您的模型字段名称