Django:迭代数据库视图的QuerySet

Django:迭代数据库视图的QuerySet,django,postgresql,Django,Postgresql,我有一个Postgres数据库视图,它结合了来自其他表的一些数据,我有一个Django模型来反映这个视图(针对这个问题简化了): 请注意managed=False语句,以确保Django不会尝试创建或更改表 除了在模型上迭代之外,所有这些都可以很好地使用该模型。当我这样做时,例如: for item in MyModel.objects.all(): .... 我得到以下例外情况: django.db.utils.ProgrammingError:列app_mymodel.id不存在

我有一个Postgres数据库视图,它结合了来自其他表的一些数据,我有一个Django模型来反映这个视图(针对这个问题简化了):

请注意managed=False语句,以确保Django不会尝试创建或更改表

除了在模型上迭代之外,所有这些都可以很好地使用该模型。当我这样做时,例如:

for item in MyModel.objects.all():
    ....
我得到以下例外情况:

django.db.utils.ProgrammingError:列app_mymodel.id不存在 第1行:选择“应用程序我的模型”,“id”,“应用程序我的模型…”

我理解这个错误,因为这个(虚拟)表中确实没有列“id”,但迭代器使用它来迭代结果

在没有主键列的情况下,如何迭代此查询集

谢谢, 埃里克

Django

如果您不指定,Django将添加一个id字段。在您的情况下,该字段不存在,因为模型未被管理,所以您会得到错误

如果模型上有主键,则可以为该字段设置
primary\u key=True
。如果
other\u model
是唯一的,则可以使用该字段

class MyModel(models.Model):
    othermodel = models.ForeignKey(MyOtherModel, primary_key=True, related_name='cached_points')
    ...
我不知道还有其他的解决办法。

Django

如果您不指定,Django将添加一个id字段。在您的情况下,该字段不存在,因为模型未被管理,所以您会得到错误

如果模型上有主键,则可以为该字段设置
primary\u key=True
。如果
other\u model
是唯一的,则可以使用该字段

class MyModel(models.Model):
    othermodel = models.ForeignKey(MyOtherModel, primary_key=True, related_name='cached_points')
    ...

我不知道还有其他解决方法。

解决方法是使用例如
行号()
在视图中定义任意唯一id字段,例如,通过如下方式预先结束视图查询:

CREATE VIEW app_mymodel AS
SELECT row_number() OVER() as id, ...
我想django会很乐意使用这个id来迭代您的查询集


大警告标签:这假设排序并不重要。任何试图对查询集进行更复杂处理的尝试(例如,此id上的联合或联接)将返回虚假结果,因为django无法区分行。不过,在DB级别也是如此,因此如果需要此功能,则应通过在
OVER
子句中添加
ORDER by
指令,在查询之间强制某种一致的排序。

解决方法是定义ar使用例如
row_number()
在视图中输入唯一的id字段,例如,通过如下方式预先输入视图查询:

CREATE VIEW app_mymodel AS
SELECT row_number() OVER() as id, ...
我想django会很乐意使用这个id来迭代您的查询集


大警告标签:这假设排序并不重要。任何试图对查询集进行更复杂处理的尝试(例如,此id上的联合或联接)将返回虚假结果,因为django无法区分行。不过,在DB级别也是如此,因此如果您需要此功能,那么您应该通过在
OVER
子句中添加
ORDER by
指令,在查询之间执行某种一致的排序。

我在通过创建一个值字典而不是访问模型字段,通过使用:

items = MyModel.objects.all()
for item in items.values('field1', 'field2', ..):
    item['field1'] ...  # Access the data
我确信还有其他解决方案,但这是我的用例中最简单的


感谢您为我指明了正确的方向,@gbs&@Alasdair.

我通过创建一个值字典而不是访问模型字段,并通过使用以下方法对结果进行了迭代:

items = MyModel.objects.all()
for item in items.values('field1', 'field2', ..):
    item['field1'] ...  # Access the data
我确信还有其他解决方案,但这是我的用例中最简单的

谢谢你给我指出了正确的方向,@gbs&@Alasdair