object has no attribute '_state'

3,348 views
Skip to first unread message

jcage

unread,
Jul 5, 2010, 10:51:51 PM7/5/10
to Django users
Hi everyone. I'm quite new to python and django. I was wondering if
anyone could shed some light on this topic :

My models.py contains the classes QuestionSet and Question, which
inherits the former.
In the shell, I define a Question object as follows

q1 = Question(script = "How are you?", comment = "no comment", order =
1)


but an attempt to run q1.save() results in the following error :

>>> q1.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/
python2.6/site-packages/django/db/models/base.py", line 435, in save
self.save_base(using=using, force_insert=force_insert,
force_update=force_update)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/
python2.6/site-packages/django/db/models/base.py", line 447, in
save_base
using = using or router.db_for_write(self.__class__,
instance=self)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/
python2.6/site-packages/django/db/utils.py", line 133, in _route_db
return hints['instance']._state.db or DEFAULT_DB_ALIAS
AttributeError: 'Question' object has no attribute '_state'



The class definitions are :

class QuestionSet(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
order = models.IntegerField()

def __init__(self, *args, **kwargs):
self.title = kwargs.get('title','Default Title')
self.description = kwargs.get('description', 'DefDescription')
self.order = kwargs.get('order', 0)


class Question(QuestionSet):
script = models.CharField(max_length=200)
comment = models.TextField()


def __init__(self, *args, **kwargs):
QuestionSet.__init__(self, args, kwargs)
self.script = kwargs.get('script', "undefined")
self.comment = kwargs.get('comment', "no comment")




Would greatly appreciate any suggestions

Tom Evans

unread,
Jul 6, 2010, 4:50:10 AM7/6/10
to django...@googlegroups.com

You aren't calling the django.db.models.Model constructor on either of
your derived classes. When you write a derived class, be sure to call
the super class constructor:

class MyModel(Model):
def __init__(self, *args, **kwargs):
super(MyModel, self).__init__(*args, **kwargs)

Cheers

Tom

Demian Brecht

unread,
Oct 5, 2012, 10:56:12 AM10/5/12
to django...@googlegroups.com

>> class QuestionSet(models.Model):
>> title = models.CharField(max_length=100)
>> description = models.TextField()
>> order = models.IntegerField()
>>
>> def __init__(self, *args, **kwargs):
>> self.title = kwargs.get('title','Default Title')
>> self.description = kwargs.get('description', 'DefDescription')
>> self.order = kwargs.get('order', 0)

One thing that looks suspect to me here is that you're not calling
__init__ on models.Model.

def __init__(self, *args, **kwargs):
models.Model.__init__(self, ...)

Which will prevent the base class from initializing.

For example:

>>> class A(object):
... def __init__(self):
... print 'A init'
...
>>> class B(A):
... def __init__(self):
... A.__init__(self)
... print 'B init'
...
>>> class C(A):
... def __init__(self):
... print 'C init'
...
>>> C()
C init
<__main__.C object at 0x7fd811c23bd0>
>>> B()
A init
B init
<__main__.B object at 0x7fd811c23c50>

Constructor calls don't bubble up on their own, you have to explicitly
call them.

I would assume that something in the model's base class is what adds the
_state attribute. By short circuiting the constructor, you're preventing
this from ever happening.

--
Demian Brecht
@demianbrecht
http://demianbrecht.github.com

Tom Evans

unread,
Oct 5, 2012, 11:33:07 AM10/5/12
to django...@googlegroups.com
On Fri, Oct 5, 2012 at 3:56 PM, Demian Brecht <demian...@gmail.com> wrote:
>
>>> class QuestionSet(models.Model):
>>> title = models.CharField(max_length=100)
>>> description = models.TextField()
>>> order = models.IntegerField()
>>>
>>> def __init__(self, *args, **kwargs):
>>> self.title = kwargs.get('title','Default Title')
>>> self.description = kwargs.get('description', 'DefDescription')
>>> self.order = kwargs.get('order', 0)
>
>
> One thing that looks suspect to me here is that you're not calling __init__
> on models.Model.
>

I'm sure the OP from June 2010 will be pleased that his question has
been answered so many times…

Cheers

Tom

PS: To call the parent class(es) constuctor(s) correctly when using
python "new style" classes (ie: all Django classes and classes derived
from Django classes), you should use super(ClassName, self).__init__()
and not call the base class directly.

Demian Brecht

unread,
Oct 5, 2012, 1:13:43 PM10/5/12
to django...@googlegroups.com

I'm sure the OP from June 2010 will be pleased that his question has
been answered so many times…
 
Eek, guess I should have read the posting date.
 
PS: To call the parent class(es) constuctor(s) correctly when using
python "new style" classes (ie: all Django classes and classes derived
from Django classes), you should use super(ClassName, self).__init__()
and not call the base class directly.

Call me paranoid: https://fuhm.net/super-harmful/ 

Tom Evans

unread,
Oct 9, 2012, 5:12:55 AM10/9/12
to django...@googlegroups.com
On Fri, Oct 5, 2012 at 6:13 PM, Demian Brecht <demian...@gmail.com> wrote:
> Call me paranoid: https://fuhm.net/super-harmful/

One guys (well publicized) internet rant on why he dislikes super does
not necessarily mean he is correct. Even if he is, follow his own
advice:

Subclasses must use super if their superclasses do

Django's model classes all use super, so should you when defining
subclasses derived from them.

Cheers

Tom

Demian Brecht

unread,
Oct 9, 2012, 10:54:35 AM10/9/12
to django...@googlegroups.com
On 12-10-09 02:12 AM, Tom Evans wrote:
> On Fri, Oct 5, 2012 at 6:13 PM, Demian Brecht <demian...@gmail.com> wrote:
>> Call me paranoid: https://fuhm.net/super-harmful/
>
> One guys (well publicized) internet rant on why he dislikes super does
> not necessarily mean he is correct. Even if he is, follow his own
> advice:
>
> Subclasses must use super if their superclasses do

Good catch, thanks.. Although now I'm interested as to *why* the
resulting behavior is as detailed in the blog..
Reply all
Reply to author
Forward
0 new messages