属性错误:'NoneType'对象没有属性'attname'(Django)

fnatzsnv  于 2022-11-19  发布在  Go
关注(0)|答案(5)|浏览(316)

我有一个相当复杂的模型,对于该模型,第一次调用MyModel.objects.create(**kwargs)失败,
属性错误:'NoneType'对象没有属性'attname'
堆栈跟踪像这样向下(在Django 1.11中)

django/db/models/manager.py:85: in manager_method
   return getattr(self.get_queryset(), name)(*args, **kwargs)
django/db/models/query.py:394: in create
   obj.save(force_insert=True, using=self.db)
django/db/models/base.py:807: in save
   force_update=force_update, update_fields=update_fields)
django/db/models/base.py:837: in save_base
   updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
django/db/models/base.py:889: in _save_table
   pk_val = self._get_pk_val(meta)
django/db/models/base.py:644: in _get_pk_val
   return getattr(self, meta.pk.attname)
django/db/models/query_utils.py:114: in __get__
   val = self._check_parent_chain(instance, self.field_name)
django/db/models/query_utils.py:131: in __check_parent_chain
   return getattr(instance, link_field.attname)

模型定义看起来不错。我已经检查了create调用的所有参数都是我想要的。
我并不热衷于剥离模型来找出问题所在,因为模型太复杂了(我的所有其他模型,其中许多都很相似,看起来都运行得很好)。
那么,是什么原因导致了这种奇怪的信息呢?

qlzsbp2j

qlzsbp2j1#

我花了大约90分钟才找到它,直到我从模型中取出抽象超级模型,然后是所有关系字段,然后是除一个以外的所有数据字段,直到只剩下一个IntegerFieldcreate仍然不起作用。
此时,我在完全相同的测试上下文中调用了其他一些简单模型类MyModel2上的create,它工作了(就像惯用的breeze)。
那么MyModel到底有什么特别之处呢?
我恍然大悟:MyModel具有__init__方法;我的其他模特都没有。所以看看这个。然后敲你的额头:我只是忘记了强制性的(Python 3风格)

super().__init__(*args, **kwargs)

寓意:不要忘记这一点,否则你可能会遭受一个真正坚韧的错误消息。

  • (注:如果你不喜欢这篇文章的风格,我很抱歉。这是我的治疗性写作要求。)*
kuhbmx9i

kuhbmx9i2#

至于我,我有:

def __init__(self):
        return self.title

代替

def __str__(self):
        return self.title

所以我在__str__的地方打错了__init__

toiithl6

toiithl63#

重新表述前一个,使其更加明确:此错误是由于__init__方法没有引用其父类。请确保您的__init__方法定义如下:

def __init__(self, *args, **kwargs):
    super().__init__(*args,**kwargs)
    ...
aelbi1ox

aelbi1ox4#

我遇到了这个错误,但是来自一个完全不同的用例。我最终通过从__dict__表示中移除id属性来破坏我的Django模型示例对象,然后再尝试访问id属性,如下所示。解决方案:如果您打算稍后在原始示例对象上使用这些属性,请不要从Django模型示例的__dict__中删除条目。

instance1 = File.objects.get(path = '/path/to/sample1.txt')

print(instance1)
# /path/to/sample1.txt # this is my normal __str__ method for the model

# preview the instance dict representation
print(instance1.__dict__)
# {'_state': <django.db.models.base.ModelState object>, 'id': 7, 'path': '/path/to/sample1.txt'}

# create object to hold the dict
instance1_dict = instance1.__dict__

# remove 'id' for test case because its non-deterministic
instance1_dict.pop('id')

# check what the dict object looks like now
print(instance1_dict)
# {'_state': <django.db.models.base.ModelState object>, 'path': '/path/to/sample1.txt'}
# 'id' no longer present

# check what the original instance object dict representation looks like
print(instance1.__dict__)
# {'_state': <django.db.models.base.ModelState object>, 'path': '/path/to/sample1.txt'}
# 'id' is no longer present anymore

# try to access 'id' on the original instance object
expected_id = instance1.id
# AttributeError: 'NoneType' object has no attribute 'attname'
0md85ypi

0md85ypi5#

遇到了同样的错误,但我的解决方案不同。在我的应用中,我有标准的django模型Report和代理模型ReportExist。当我从ReportExist继承创建一个新的ReportSelect类时,错误发生了:

class ReportSelect(ReportExist):
   # no meta, error

我所要做的就是添加一个Meta类,其中proxy = True也是第二个子类:

class ReportSelect(ReportExist):
   class Meta:
       proxy = True

   # no error

相关问题