views:

67

answers:

1

I am using Polymorphic Models.

Simple Question: My code below works without using this line below, which I see in other people's code. What is it supposed to do?

#super(GeneralModel, self).__init__(*args, **kwargs)

Messy Question: I have a feeling my code below, although it seems to work, is not the most beautiful solution.

Synopsis of what I am doing: I am instantiating (or making) a new datastore model entity based on a 'unclean' JSON object posted to the server. 1st I want to do some general input data cleaning specified in the general (or super) model and then 2nd do some special methods, which is specified in each special (or sub-class) model as def parse.

class GeneralModel(polymodel.PolyModel):
 lat_long_list = db.ListProperty(db.GeoPt)
 zooms = db.ListProperty(int)

     def __init__(self, *args, **kwargs):
  self.lat_long_list = [ db.GeoPt( pt[0] , pt[1] ) for pt in zip( kwargs["lat"] , kwargs["lon"] ) ]
  del kwargs["lat"]
  del kwargs["lon"]
  if "zooms" not in kwargs: kwargs["zooms"] = ZOOMS # some default
  for property,value in kwargs.items():
   setattr(self,property,value)
  #super(NamedModel, self).__init__(*args, **kwargs)
  self.parse()

 def parse(self):
         raise NotImplementedError('Need to define this for each category')


class SpecialModel(GeneralModel):
 stringText = db.StringProperty()
 words_list = db.StringListProperty()

 def parse( self ):
  self.words_list = self.stringText.split(",")  

This is how I test whether my code works:

>>>kwargs={'stringText':'boris,ted','lat':[0,1,2,3],'lon':[0,1,2,8],'zooms':[0,10]}
>>>entity=SpecialModel(key_name="tester",**kwargs)
>>>entity.words_list
['boris', 'ted']
A: 

The 'super' line calls the constructor of the parent entity. If you don't include it, the parent constructor will not be called, and your model will not be initialized properly. You should, in fact, be calling this first, before any of your own initialization.

However, overriding the constructor on models is strongly discouraged. The constructor is not just used when you call it, but also by the system to construct instances that are being loaded from the datastore, and in the latter case, the arguments - and the expected behaviour - are different, and implementation dependent.

Instead, you should probably define a factory method, like so:

class MyModel(db.PolyModel):
  @classmethod
  def create(cls, foo, bar):
    # Do some stuff
    return cls(foo, bleh)
Nick Johnson
Thanks. That makes much more sense!
indiehacker