Django F 字段迭代

use*_*619 2 python django

我创建了一个简单的 Django 模型来探索 F 字段,但可以遍历该字段。

class PostgreSQLModel(models.Model):
    class Meta:
        abstract = True
        required_db_vendor = 'postgresql'

class NullableIntegerArrayModel(PostgreSQLModel):
    field = ArrayField(models.IntegerField(), blank=True, null=True)    
Run Code Online (Sandbox Code Playgroud)

现在,从我的 django shell 中,我创建了一个 F 对象,如下所示。不确定这个对象包含什么。它是否包含所有 ID?如何迭代结果?

>>> a=F('id')
>>> a
F(id)
>>> dir(a)
['ADD', 'BITAND', 'BITOR', 'DIV', 'MOD', 'MUL', 'POW', 'SUB', '__add__', '__and__', '__class__', '__delattr__', '__dict__', '__dir__', '__div__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__mod__', '__module__', '__mul__', '__ne__', '__new__', '__or__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__weakref__', '_combine', 'asc', 'bitand', 'bitor', 'desc', 'name', 'resolve_expression']
Run Code Online (Sandbox Code Playgroud)

Tin*_*nce 7

F 不是一个字段。

F() 对象表示模型字段或带注释的列的值。它可以引用模型字段值并使用它们执行数据库操作,而实际上不必将它们从数据库中提取到 Python 内存中。- F() 表达式

总之,F()只要您需要在查询中引用另一个字段的值,就可以使用对象。就其本身而言,F()物体并不意味着什么。它们用于引用同一查询集上的字段值。

例如(一个非常简单的例子),在你的模型中,如果你想查询field值是它的两倍的对象id,你需要在过滤时引用id字段的值,所以你可以这样使用F()

NullableIntegerArrayModel.objects.filter(field=F('id') *2)
Run Code Online (Sandbox Code Playgroud)

F('id')简单地引用该id模型的值。Django 使用它来创建相应的 SQL 语句。在这种情况下是这样的:

'SELECT "app_model"."id", "app_model"."field" FROM "app_model" 
 WHERE "app_model"."field" = (("app_model"."id" * 2))'
Run Code Online (Sandbox Code Playgroud)

如果没有F()表达式,您要么编写原始 SQL,要么在 Python 中进行过滤(这会降低性能,尤其是在有大量对象时)。


参考:

F()类定义:

能够解析对现有查询对象的引用的对象。- ˚F源