Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Multi-table inheritance: specify custom one-to-one column name

I'm trying to create a Django ORM mapping that's compatible with an existing data model, so I'm trying to work with an existing set of table and column names.

I've got a multi-table inheritance situation where a class InformationObject derives from class Object. I'd like to let Django handle this the usual way:

class Object(models.Model):
    class Meta:
        db_table = "object"          

class InformationObject(Object):
    class Meta:
        db_table = "information_object"

In this case Django would automatically create a one-to-one field on the inheriting model called object_ptr_id. However, on the schema I'm constrained to use, the reference to the Object is simply called "id". So:

Is there a way to somehow specify the name of the column Django auto-magically uses for multi-table inheritance?

The alternative, which I'll have to use otherwise, is to use an explicit one-to-one field, but then I won't be able to inherit non-database methods from the Object model:

class Object(models.Model):
    class Meta:
        db_table = "object"          

class InformationObject(models.Model):
    class Meta:
        db_table = "information_object"
    id = models.OneToOneField(Object, primary_key=True, db_column="id")  

Any ideas? Maybe I could create a common base class for both of them and put non-db methods there...?

like image 853
Mikesname Avatar asked Sep 01 '11 10:09

Mikesname


2 Answers

From the django docs (development version):

As mentioned, Django will automatically create a OneToOneField linking your child class back any non-abstract parent models. If you want to control the name of the attribute linking back to the parent, you can create your own OneToOneField and set parent_link=True to indicate that your field is the link back to the parent class.

like image 75
fusion Avatar answered Nov 11 '22 22:11

fusion


As mentioned by @fusion quoting from the docs, you will have to create a OneToOneField if you want to specify the column, while using model inheritance. The inherited fields will be available in the child class in both self scope AND the one-to-one field.

class Object(models.Model):
    class Meta:
        db_table = "object"   
    column_1 = models.CharField()

class InformationObject(Object):
    class Meta:
        db_table = "information_object"
    # arbitrary property name (parent_link)
    parent_link = models.OneToOneField(Object, primary_key=True, db_column="id", parent_link=True) 

In this example:

>>> inf_obj = InformationObject.objects.get(pk=1)
>>> print inf_obj.column_1 == inf_obj.parent_link.column_1
True
like image 23
laffuste Avatar answered Nov 11 '22 21:11

laffuste