【问题标题】:Override a column value with django queryset使用 django 查询集覆盖列值
【发布时间】:2014-09-15 11:11:34
【问题描述】:

我有一张如下表-

name| age |
----|-----|
A   | 50  |
B   | 60  |
C   | 70  |

我的模型类是 -

class Persons(models.Model):
    p_id = models.AutoField(primary_key=True)
    p_name = models.CharField(max_length=32, null=False)
    p_age = models.IntegerField(null=False)

objects = ManagerEx()

class Meta:
    db_table = u'persons'

我想用类似的东西来查询表 -

persons = Persons.objects.all()

但是名称应该被“匿名”覆盖,这样对于每个人对象 p_name 的计算结果都是“匿名”

for person in persons:
    name = person.p_name # For all objects name should equal to 'anonymous'

我怎样才能做到这一点?

【问题讨论】:

  • 当你输出数据时肯定会这样做,不是吗?
  • 我可以用 sql 做到这一点。例如 select cast('anonymous' as varchar(32)) as p_name, p_age from people。我正在寻找一种使用 django queryset 的方法
  • 但是为什么呢?查询集在您输出之前没有用处。
  • 我在一个后端项目中使用 django ORM,并且有一个算法适用于从这里返回的查询集。如果 p_name 字段的值不是“匿名”并且我没有更改数据库中记录的选项,则算法的行为将是未定义的。该算法是通用的,也适用于其他数据。我也修改不了。

标签: python django django-queryset


【解决方案1】:

你可以使用annotate:

from django.db.models import Value, CharField

def get_anonymous:
    persons = Persons.objects.all()
    return persons.annotate(p_name=Value('anonymous', output_field=CharField()))

(使用 CharField 作为输出,因为您在 Persons 模型中使用的类型相同

或者如果你想有一些条件(只为孩子隐藏名字):

return queryset.annotate(
            p_name=Case(When(
                p_age__gte=18,
                then=F('p_name')),
                default=Value('anonymous'),
                output_field=CharField()
            ))

在第二种情况下,请记住还要从 django.db.models 导入 CaseWhen

【讨论】:

  • 对不起,我才意识到我在 6 年后才回答你 :) 但是我发现你的问题面临同样的问题,所以在我解决它之后,我想分享我的经验。
【解决方案2】:

如果你想在你的模板中做,那么简单:

<Table>
    <Th>
        <Td>Name</Td>
        <Td>Age</Td>
    </Th>
{% for person in persons %}
    <Tr>
        <Td>Anonymous</Td>
        <Td>person.p_age</Td>
    </Tr>
{% endfor %}
</Table>

如果您想在您的视图中执行此操作,您可以使用原始查询来执行此操作,就像您在 cmets 中所说的那样。

【讨论】:

  • 问题是关于查询集,而不是模板
猜你喜欢
  • 2011-06-18
  • 2017-07-09
  • 2020-06-14
  • 2012-09-03
  • 2015-01-02
  • 2014-11-04
  • 2019-12-10
  • 2017-02-12
  • 2014-07-17
相关资源
最近更新 更多