Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AttributeError: 'NoneType' object has no attribute 'attname' (Django)

I have a fairly complex model for which the first call to MyModel.objects.create(**kwargs) fails with

AttributeError: 'NoneType' object has no attribute 'attname'

The stack trace dives down like this (in 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)

The model definition looks alright to me. I have checked all the parameters of the create call are just what I want them to be.

I'm not keen on stripping down the model to find the problem, because the model is so complex. (All my other models, many of them similar, appear to work fine.)

So what might cause this strange message?

like image 903
Lutz Prechelt Avatar asked Sep 22 '17 08:09

Lutz Prechelt


2 Answers

It took about 90 minutes to find this. I only found it after I had taken out of my model first the abstract supermodel, then all relationship fields, then all-but-one data fields, until only a single IntegerField was left. The create still didn't work.

At that point I called create on some other simple model class MyModel2 in exactly the same test context. It worked (like the idiomatic breeze).

So what the hell was special about MyModel??

And then it dawned on me: MyModel had an __init__ method; most of my other models did not. So look at that. And bang your forehead: I simply had forgotten the mandatory (in Python 3 style)

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

Moral: Don't forget this or you may suffer from a really tough error message.

(Note: If you don't like the style of this post, I am sorry. It was required therapeutic writing for me.)

like image 73
Lutz Prechelt Avatar answered Sep 18 '22 17:09

Lutz Prechelt


As for me, I had:

 def __init__(self):
        return self.title

instead of

 def __str__(self):
        return self.title

so I had mistyped __init__ in place of __str__

like image 41
Jafeth Yahuma Avatar answered Sep 21 '22 17:09

Jafeth Yahuma