0

I have a base model and derived model from it. base model is not abstract, so it also has table associated with it.

Problem : I create a base instance first and then derived instance. And associate derived instance to base. But I get FileField in my derived class as None, even if its saved and available in parent. Why so? Am I missing something?

Some sample code:

def get_filepath(instance):
     return u''+instance.name

def BaseModel(models.Model):
     name = models.CharField(max_length=50)
     filepath = models.FileField(upload_to=get_filepath,
            max_length=255, null=True)
     #some other fields

def DerivedModel(BaseModel):
     type = models.CharField(max_length=50, null=True, blank=True)

Sample on django shell:

>>> obj = BaseModel.objects.create(name='y')
>>> obj.id
56
>>> obj.save()
>>> obj.id
56
>>> nf=ContentFile("this is dummy text")
>>> obj.filepath.save('dummyfile', nf)
>>> dobj=DerivedModel()
>>> dobj.basemodel_ptr=obj
>>> dobj.save()
>>> dobj.id
56
>>> dobj.filepath
<FieldFile: None>
>>> obj.filepath
<FieldFile: y>

Update: for @dgel's answer:

  • save_base() does it save the derived object? dobj does not get id after that.
  • After dobj.save(), it seems attributes in base class are getting overwritten by attributes in derived class.
  • I added ctime created time in BaseModel with default datetime.datetime.utcnow. So once I save derived object, ctime is updated to save time of derived object.
  • When I look at the DB through sqlitebrowser, filepath field of the BaseModel row is empty.

>>> dobj.save_base(raw=True)
>>> dobj.id
>>> dobj.save()
>>> dobj.filepath
<FieldFile: None>
>>> obj.ctime
datetime.datetime(2012, 8, 23, 8, 50, 3, 171573)
>>> dobj.ctime
datetime.datetime(2012, 8, 23, 8, 51, 9, 946434)
>>> newdobj = DerivedModel.objects.get(id=dobj.id)
>>> newdobj.ctime
datetime.datetime(2012, 8, 23, 8, 51, 9, 946434)

Thanks.

Rohan
  • 52,392
  • 12
  • 90
  • 87
  • It is duplicate of http://stackoverflow.com/questions/4064808/django-model-inheritance-create-sub-instance-of-existing-instance-downcast – Rohan Aug 23 '12 at 09:53

1 Answers1

1

Try this:

dobj = DerivedModel()
dobj.basemodel_ptr=obj
dobj.save_base(raw=True)
dgel
  • 16,352
  • 8
  • 58
  • 75
  • Unfortunately, this doesn't seem to work. I didn't find any documentation for `save_base`. Can you post some link? – Rohan Aug 23 '12 at 04:41
  • In what way does it not work? I've used [this technique](http://stackoverflow.com/a/10641305/473232) many times to create a subclass instance for an existing superclass instance. It's not in the documentation, but the source is [here](https://github.com/django/django/blob/stable/1.4.x/django/db/models/base.py#L467). – dgel Aug 23 '12 at 07:25
  • please see my update in question. Does `save_base()` saves `dobj` also in DB? – Rohan Aug 23 '12 at 09:16
  • 1
    `dobj.__dict__.update(obj.__dict__)`, does the trick, found from http://stackoverflow.com/questions/4064808/django-model-inheritance-create-sub-instance-of-existing-instance-downcast – Rohan Aug 23 '12 at 09:55