tags:

views:

15

answers:

2

Hi,

Is it possible to instantiate a subclassed model from its parent?

class Object1(models.Model):
  field1a = models.CharField()
  field1b = models.CharField()
  feild1c = models.ForeignKey(Object4)      

class Object2(Object1):
  field3 = models.CharField()

class Object3(Object1):
  field3 = models.CharField()

class Object4(models.Model):
  field4 = models.CharField()

What I want to do is create the base class first and then based on some rule instantiate one of the subclasses but using the already created base class.

Something like:

obj4 = Object4(field4='d')
obj1 = Object1(field1a='a', field1b='b', field1c=obj4)
if somerule:
  obj2 = Object2(object1_ptr=obj1, field2='2')
else:
  obj3 = Object3(object1_ptr=obj1, field3='3')

I don't want to repeat the Object1 fields in the if/else clauses. Is it possible to accomplish this? When I try this I get a Foreign key error; Cannot add or update a child row: A foreign key constraint fails

A: 

I recommend doing something like this:

attr = dict(field1a='a', field1b='b', field1c=obj4)
obj1 = Object1(**attr)
if somerule:
    attr["field2"] = 2
    obj2 = Object2(**attr)
else:
    attr["field3"]='3'
    obj3 = Object3(**attr)

Be aware that the dictionary attr changes in place.

stefanw
Thanks. I will give it ago and see if it does what I want.
Andrew Gee
A: 

What you're doing is almost correct, but if you want to copy it you will have to remove the primary key.

So... this should fix it: del obj2.id Do note however that if some other model references your model with a foreign key that it references obj1, not obj2. And obj1 will, ofcourse, still exist.

WoLpH
I don't see how Object2(object1_ptr=obj1, can be almost correct. And where do you want to insert a del obj2.id?
stefanw
I am assuming `obj1` already exists in the database, although that might be an incorrect assumption.The del woud naturally be before the insert/save. Although, seeing your answer, it seems as I might have misinterpreted the question.The point still stands though, if the object already exists in the database you will need to delete the primary key for Django to reinsert it.
WoLpH
Thanks for the replies. I am currenly just using if/else statements to handle this and creating each object depending on the result of the rule, all I was wanting to avoid was duplicating the code for creating the objects, my example is small but the real objects have a larger number of fields. The add/edit save/delete is another matter that I am handling in similiar fashion to your suggestions. Thanks again.
Andrew Gee