如何将值ID更改为Queryset中的模型属性

问题描述 投票:1回答:2

Django QuerySets返回关联对象的PK,但我需要属性名称。例如,Sitting.objects.filter(complete=True).values('user')将返回查询集,例如:<QuerySet[{'user':2}, {'user':3}]>。如何轻松地将2转换为user.get_full_name()等?

给出我正在尝试的想法:

tests_taken = Sitting.objects.filter(complete=True).values('user')
for test in tests_taken:
   try:
      tests_taken[test]['user'] = Employee.objects.get(pk=test['user'])
   except TypeError:
      pass
print(tests_taken)

这似乎效率很低,我不确定从这里开始该怎么做。

此:

qs = Sitting.objects.filter(complete=True).values('user')
tests_taken = [{'user': Employee.objects.filter(pk=user).get_full_name()} for user in qs]
print(tests_taken)

给出此错误:

int()参数必须是字符串,类似字节的对象或数字,而不是'dict'

模型

class Sitting(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        verbose_name=_("User"),
        on_delete=models.CASCADE)

class Employee(AbstractUser):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)

    def get_full_name(self):
        # returns self.first_name + self.last_name

我的目标

[{'user':2}应该转换为{'user':'John Doe'}

django python-3.x
2个回答
1
投票

这里是代码的优化版本:

qs = Sitting.objects.filter(complete=True).values('user_id')
employees = Employee.objects.filter(id__in=qs)

编辑:

您实际上并不需要该map语句,并且在遍历查询集时调用get_full_name是最有效的。例如:

qs = Sitting.objects.filter(complete=True).values('user_id')
employees = Employee.objects.filter(id__in=qs)

for employee in employees:
    print(employee.get_full_name())

或在模板中:

{% for employee in employees %}
    <h1> {{ employee.get_full_name }}
{% endfor %}

编辑2:

我对为什么要将查询集转换为对象列表感到困惑,但是,到这里来了:

employees = [
    {'user':user.get_full_name()} 
    for user in Employee.objects.filter(id__in=qs)
]

我假设您实际上并不希望数据看起来像:

[{'user':'john doe'}, {'user':'jane doe'}]

这是我想您想要的:

employees = Employee.objects.filter(id__in=qs)

[{'id':user.id, 'full_name':user.full_name} for user in employees]

或作为元组列表:

[(user.id, user.full_name) for user in employees]

0
投票

您不能在值中使用方法,而是可以这样做,

queryset = Sitting.objects.filter(complete=True)
tests_taken = [{'full_name':user.get_full_name()} for user in queryset]

0
投票
In the 'Sitting' model, Just add a function

class Sitting(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    ...
    ...


    def __str__(self):
        return self.user.first_name + self.user.last_name


And Query the model:-

Sitting.objects.filter(complete=True)
© www.soinside.com 2019 - 2024. All rights reserved.