Django模型错误E007:为什么不能直接访问数据库字段并将其重新用作外键指针?

Django模型错误E007:为什么不能直接访问数据库字段并将其重新用作外键指针?,django,django-models,Django,Django Models,我认为以下内容过去是允许的,但在1.7版本中,系统检查框架返回: 模型0.E007错误 假设我有两个模型,Foo和Bar。Foo有一个值bar_id,它毫不奇怪地表示bar的主键,允许我在Foo和bar之间建立ForeignKey关系。所以这很好: from django.db import models class Bar(models.Model): id = models.IntegerField(primary_key=True) blah = models.TextField

我认为以下内容过去是允许的,但在1.7版本中,系统检查框架返回:

模型0.E007错误

假设我有两个模型,Foo和Bar。Foo有一个值bar_id,它毫不奇怪地表示bar的主键,允许我在Foo和bar之间建立ForeignKey关系。所以这很好:

from django.db import models

class Bar(models.Model):
  id = models.IntegerField(primary_key=True)
  blah = models.TextField()

class Foo:
  asdf = models.TextField()
  bar = models.ForeignKey(Bar, db_column='bar_id' to_field='id')
但是,如果我想直接在Foo中访问bar_id的值并使用它指向bar,我就不能再这样做了:

from django.db import models

class Bar(models.Model):
  id = models.IntegerField(primary_key=True)
  blah = models.TextField()

class Foo:
  asdf = models.TextField()
  bar_value = models.IntegerField(db_column='bar_id')
  bar_fk = models.ForeignKey(Bar, db_column='bar_id' to_field='id')
在1.7之前,我很确定这一切都很好。升级到1.7后,它会使用

models.E007错误。 Foo:models.E007字段“bar\u fk”的列名为“bar\u value”,即 被另一个领域使用。提示:为字段指定“db_列”

好吧,这个提示没有什么好处,因为您可以看到db_列的值确实已经设置好了

是的,我可以重构代码,用Foo.bar_fk.id替换Foo.bar_value的实例;也许我甚至可以这样做

class Foo:
  asdf = models.TextField()
  bar_fk = models.ForeignKey(Bar, db_column='bar_id' to_field='id')
  @property
  def bar_value(self):
    return self.bar_fk.id 
但这两种方法都涉及到查询外部表以返回Foo中已经存在的值的数据库开销?我当然可以在数据库中复制该字段,但那将是对自然的犯罪

如果它真的在1.6下工作,是否有一个根本原因它在1.7下不工作?还是models.E007错误本身给出了假阳性

提前谢谢


史蒂夫·沃克(Steve Walker)

我不确定你的方法在1.7之前是否有效,但它看起来很不寻常。我不清楚为什么要定义字段bar_值

通常的方法是使用

bar = models.ForeignKey(Bar, db_column='bar_id' to_field='id')
请注意,这里不需要db_列和to_字段,因为您使用的是默认值

然后,您将访问相关实例和值,如下所示:

返回需要查找的bar实例 foo.bar_id返回id的值,无需查找。
我不确定你的方法在1.7之前是否有效,但它看起来很不寻常。我不清楚为什么要定义字段bar_值

通常的方法是使用

bar = models.ForeignKey(Bar, db_column='bar_id' to_field='id')
请注意,这里不需要db_列和to_字段,因为您使用的是默认值

然后,您将访问相关实例和值,如下所示:

返回需要查找的bar实例 foo.bar_id返回id的值,无需查找。
因为它在1.6中运行良好

-及-

因为我的生产环境在1.7中运行良好,而与错误消息无关

-所以-

我的结论是我可以抑制这个错误

在settings.py中:

静音系统检查=['models.E007',]

见:

我仍然相信这个错误本身就是一个假阳性


-史蒂夫

因为它在1.6中运行良好

-及-

因为我的生产环境在1.7中运行良好,而与错误消息无关

-所以-

我的结论是我可以抑制这个错误

在settings.py中:

静音系统检查=['models.E007',]

见:

我仍然相信这个错误本身就是一个假阳性


-史蒂夫

感谢您的快速回复。已验证其在1.6中确实是可接受的;这里的用例是有问题的字段“bar_id”(在本例中为“bar_id”)本身具有内在价值,[编辑注:上面的oops部分注释]我确实忽略了通过在外键字段名称的末尾添加“\u id”来访问基础值的能力,谢谢,但我上面过于简化的模型没有明确说明问题。我将字段命名为“bar\u id”,这是一个巧合,允许“bar\u id”FK命名约定与我想要的完全一样。如果字段名不是'bar_id',而是'bar_booger',那么我当然可以通过指定foo.bar_id来获得bar_booger的值,但我不能再直接指定foo.bar_booger了。我不确定我是否理解你的评论。您总是可以通过附加_id来访问基础值。我不明白为什么能够指定访问此值的名称很重要。我认为,允许多个字段引用同一列似乎很脆弱。如果您在Django 1.6中设置了foo.bar_值,那么foo.bar可能不会自动更新。感谢您的快速响应。已验证其在1.6中确实是可接受的;这里的用例是有问题的字段“bar_id”(在本例中为“bar_id”)本身具有内在价值,[编辑注:上面的oops部分注释]我确实忽略了通过在外键字段名称的末尾添加“\u id”来访问基础值的能力,谢谢,但我上面过于简化的模型没有明确说明问题。我将字段命名为“bar\u id”,这是一个巧合,允许“bar\u id”FK命名约定与我想要的完全一样。如果不是“bar_id”bei
如果将字段名改为“bar_booger”,那么我当然可以通过指定foo.bar_id来获取bar_booger的值,但我不能再直接指定foo.bar_booger。我不确定我是否理解您的评论。您总是可以通过附加_id来访问基础值。我不明白为什么能够指定访问此值的名称很重要。我认为,允许多个字段引用同一列似乎很脆弱。如果在Django 1.6中设置foo.bar_值,那么foo.bar可能不会自动更新。