Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object has no attribute _state

Tags:

python

django

I'm developing Django application, and I have following error

'Sheep' object has no attribute _state

My models are constructed like this

class Animal(models.Model):
    aul = models.ForeignKey(Aul)
    weight = models.IntegerField()
    quality = models.IntegerField()
    age = models.IntegerField()

    def __init__(self,aul):
        self.aul=aul
        self.weight=3
        self.quality=10
        self.age=0

    def __str__(self):
        return self.age


class Sheep(Animal):
    wool = models.IntegerField()

    def __init__(self,aul):
        Animal.__init__(self,aul)

What I must do?

like image 389
ardakshalkar Avatar asked Mar 13 '11 14:03

ardakshalkar


2 Answers

firstly, you must be very careful overriding __init__ to have non-optional arguments. remember it will be called every time you get an object from a queryset!

this is the correct code you want:

class Animal(models.Model):
   #class Meta:          #uncomment this for an abstract class
   #    abstract = True 
   aul = models.ForeignKey(Aul)
   weight = models.IntegerField(default=3)
   quality = models.IntegerField(default=10)
   age = models.IntegerField(default=0)

   def __unicode__(self):
       return self.age

class Sheep(Animal):
   wool = models.IntegerField()

I highly suggest setting the abstract option on Animal if you will only ever be using subclasses of this object. This ensures a table is not created for animal and only for Sheep (etc..). if abstract is not set, then an Animal table will be created and the Sheep class will be given it's own table and an automatic 'animal' field which will be a foreign key to the Animal model.

like image 163
Thomas Avatar answered Oct 31 '22 17:10

Thomas


Django docs recommend against you to use __init__ method in models:

You may be tempted to customize the model by overriding the __init__ method. If you do so, however, take care not to change the calling signature as any change may prevent the model instance from being saved. Rather than overriding __init__, try using one of these approaches:

  1. Add a classmethod on the model class
  2. Add a method on a custom manager (usually preferred)
like image 22
GrvTyagi Avatar answered Oct 31 '22 19:10

GrvTyagi