Django:查询没有主键的只读视图
Posted
技术标签:
【中文标题】Django:查询没有主键的只读视图【英文标题】:Django: Querying read-only view with no primary key 【发布时间】:2009-03-03 10:36:46 【问题描述】:class dbview(models.Model):
# field definitions omitted for brevity
class Meta:
db_table = 'read_only_view'
def main(request):
result = dbview.objects.all()
渲染时遇到异常:(1054, "Unknown column 'read_only_view.id' in 'field list'")
我可以在视图中看到没有主键。有解决办法吗?
评论: 我无法控制使用 Django 访问的视图。 mysql 浏览器在那里显示列,但没有主键。
【问题讨论】:
【参考方案1】:当您说“我无法控制使用 Django 访问的视图时。 MySQL 浏览器在那里显示列,但没有主键。'
我假设您的意思是这是一个旧表,并且不允许您添加或更改列?
如果是这样并且确实没有主键(甚至是字符串或非 int 列*),那么表设置得不是很好,性能可能很糟糕。
不过,这对你来说并不重要。您所需要的只是保证每一行都是唯一的列。在您的模型中将其设置为 'primary_key = True,Django 会很高兴。
还有另一种可能存在问题的可能性。如果没有保证唯一的列,则该表可能正在使用复合主键。也就是说 - 它指定将两列放在一起将提供一个唯一的主键。这是完全有效的关系建模,但不幸的是 Django 不支持。在这种情况下,除了原始 SQL 之外,您将无能为力,除非您可以添加另一列。【讨论】:
非常感谢,这真的很有帮助! 非常有帮助。要补充的一件事;如果要用作主键的列是 CHAR 类型,则不能超过 255 个字符。 这并没有真正解决与数据库视图有关的问题,而不是表。您已将其中一个字段指定为 django 的 pk,无论是否。您可以摆脱这一点,因为永远不会通过 ORM 对关系进行任何插入/更新。有关此技术的更多信息,请参阅the answer from David S 和我的评论。【参考方案2】:我一直有这个问题。我有一个不能或不想更改的视图,但我希望有一个页面来显示复合信息(可能在管理部分)。我只是覆盖保存并引发 NotImplementedError:
def save(self, **kwargs):
raise NotImplementedError()
(虽然这在大多数情况下可能不需要,但它让我感觉好一点)
我还在 Meta 类中将 managed 设置为 False。
class Meta:
managed = False
然后我只需选择任何字段并将其标记为主键。它是否真的很独特并不重要,您只是在做过滤器以在页面上显示信息等。
对我来说似乎工作得很好。如果我忽略的这种技术有任何问题,请发表评论。
【讨论】:
您可以将非唯一字段标记为只读访问的主键,但这会对queryset.distinct().count()
和实例比较等内容产生影响。作为后者的解决方法,您可以在模型上重新定义__eq__()
。
如果您想拥有一个 id,您可以对视图执行的操作是使用 row_number()
函数(至少在 PostgreSQL 中)。 SELECT row_number() OVER (ORDER BY field ASC) AS id,
【参考方案3】:
如果视图中确实没有主键,那么就没有变通方法。
Django requires each model to have exactly one field primary_key=True
.
【讨论】:
谢谢!如果我在视图中看不到主键,这意味着没有主键......?我想我会恢复到原始 SQL。 不一定。请参阅下面的评论。【参考方案4】:当你运行 syncdb
时应该有一个自动生成的 id
字段(如果你的模型中没有定义主键,那么 Django 会为你插入一个 AutoField
)。
这个错误意味着 Django 正在向您的数据库询问 id
字段,但不存在。你能运行django manage.py dbshell
然后DESCRIBE read_only_view;
并发布结果吗?这将显示数据库中的所有列。
或者,您可以包含您排除的模型定义吗? (并确认您在运行 syncdb
后没有更改模型定义?)
【讨论】:
谢谢,我应该在一开始就说得更清楚。请查看更新。 我不是要查看您正在访问的行,我只是想查看您的模型定义(不是同一件事)。 模型定义是这样的: text = models.CharField() 但是,我不能用 'primary_key=True' 定义一个字段,因为视图似乎没有主键。 不好意思说得这么直白,但是你知道主键是什么吗? 我看问题的方式:视图没有主键(我看不到),Django要求每个模型都有一个主键(要么手动定义'primary_key=True ' 或默认的 'id' 如果用户未定义)。以上是关于Django:查询没有主键的只读视图的主要内容,如果未能解决你的问题,请参考以下文章