Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
370 views
in Technique[技术] by (71.8m points)

python - Making a multi-table inheritance design generic in Django

First of all, some links to pages I've used for reference: A SO question, and the Django docs on generic relations and multi-table inheritance.

So far, I have a multi-table inheritance design set up. Objects (e.g: Car, Dog, Computer) can inherit an Item class. I need to be able to retrieve Items from the DB, get the subclass, and do stuff with it. My design doesn't allow for retrieving the different kinds of objects one by one, so I need to use the Item container to wrap them all into one. Once I have the Item, the Django docs say I can get the subclass by referencing the attribute with the name of the model (e.g: myitem.car or myitem.computer).

I don't know which type of object my item is referencing, so how can I get the child? Is there a built in way to do this? Here are some other ideas that I had: (some crazier than others)

  1. I was thinking I could add some sort of GenericForeignKey to Item that references the child, but I doubt it is even legal for a parent class to relate via a ForeignKey to a child class.
  2. I suppose I could have a ForeignKey(ContentType) in the Item class, and find the attribute of Item to get the child based on the ContentType's name.
  3. Finally, although an ugly method, I might be able to keep a list of object types, and try each as an attribute until a DoesNotExist error is not thrown.

As you can see, these proposed solutions are not that elegant, but I'm hoping I won't have to use one of them and someone here might have a better suggestion.

Thanks in advance

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have done something similar to method 2 in one of my projects:

from django.db import models
from django.contrib.contenttypes.models import ContentType

class BaseModel(models.Model):
    type = models.ForeignKey(ContentType,editable=False)
    # other base fields here

    def save(self,force_insert=False,force_update=False):
        if self.type_id is None:
            self.type = ContentType.objects.get_for_model(self.__class__)
        super(BaseModel,self).save(force_insert,force_update)

    def get_instance(self):
        return self.type.get_object_for_this_type(id=self.id)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...