Django在模型中"无法设置属性"

mib*_*ibm 16 python django

我有一个像这样的模型:

class MyReport(models.Model):
    group_id    = models.PositiveIntegerField(blank=False, null=False)
    test        = models.ForeignKey(Test, on_delete=models.CASCADE)
    owner       = models.ForeignKey(User, editable=False, default=get_current_user, on_delete=models.CASCADE)

    user_objects = UserFilterManager()

    @property
    def location(self):
        return self.test.location
Run Code Online (Sandbox Code Playgroud)

我添加了一个位置属性.我在运行时遇到此错误.我只粘贴了我最近一次调用的部分,在这种情况下是len()(我知道,使用count代替).

  File "C:\Python27\Lib\site-packages\django\db\models\query.py", line 240, in __len__
    self._fetch_all()
  File "C:\Python27\Lib\site-packages\django\db\models\query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "C:\Python27\Lib\site-packages\django\db\models\query.py", line 75, in __iter__
    setattr(obj, attr_name, row[col_pos])
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么会出错?如果我称之为locationx,则没有错误.

Django有一些特殊的属性定义规则吗?

我怎么调试这个?

我添加了属性,因为我添加了测试间接,并希望尽可能少地更改代码.我当然可以,只是改变每个report.locationreport.test.location,但是这是一个麻烦.如果我可以为数据库搜索定义别名,那将是很好的,所以我需要更改它们.

编辑:回答评论:

  1. 我不想设置值,我只想要一个属性(getter).我希望能够report.location改为添加间接report.test.location(不想更改位置在报表模型中的现有代码).
  2. self.test.locationreport.test.location工作,也reports.locationx工作.
  3. 我在上面提到了这一点,但我会重复一遍.我所做的只是在查询上调用len(),例如len(MyReport.objects.all()).

以下是Eclipse控制台的完整跟踪:

Traceback (most recent call last):
  File "C:\Eclipse-SDK-4.2.1-win32-x86_64\plugins\org.python.pydev_2.7.1.2012100913\pysrc\pydevd_comm.py", line 765, in doIt
    result = pydevd_vars.evaluateExpression(self.thread_id, self.frame_id, self.expression, self.doExec)
  File "C:\Eclipse-SDK-4.2.1-win32-x86_64\plugins\org.python.pydev_2.7.1.2012100913\pysrc\pydevd_vars.py", line 378, in evaluateExpression
    sys.stdout.write('%s\n' % (result,))
  File "C:\Python27\Lib\site-packages\django\db\models\query.py", line 234, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "C:\Python27\Lib\site-packages\django\db\models\query.py", line 258, in __iter__
    self._fetch_all()
  File "C:\Python27\Lib\site-packages\django\db\models\query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "C:\Python27\Lib\site-packages\django\db\models\query.py", line 75, in __iter__
    setattr(obj, attr_name, row[col_pos])
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)

mib*_*ibm 22

问题是名字冲突.

显然在查询数据库时我有:

objs = MyReport.objects.annotate(location=F('test__location'))

这增加location了对象(没有看到它__dict__,但也许我只是错过了它).这意味着我可以放弃这个属性,因为我可以打电话report_instance.location.当然,这意味着访问MyReport的所有地方都需要添加注释(特殊管理器?).

  • 感谢您分享答案。我遇到了同样的问题,然后发现一个属性被存储在模型中,并使用了我试图注释的相同名称。 (4认同)