Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetching inherited model objects in django

I have a django application with the following model:

Object A is a simple object extending from Model with a few fields, and let's say, a particular one is a char field called "NAME" and an Integer field called "ORDER". A is abstract, meaning there are no A objects in the database, but instead...

Objects B and C are specializations of A, meaning they inherit from A and they add some other fields.

Now suppose I need all the objects whose field NAME start with the letter "Z", ordered by the ORDER field, but I want all the B and C-specific fields too for those objects. Now I see 2 approaches:

a) Do the queries individually for B and C objects and fetch two lists, merge them, order manually and work with that.

b) Query A objects for names starting with "Z" ordered by "ORDER" and with the result query the B and C objects to bring all the remaining data.

Both approaches sound highly inefficient, in the first one I have to order them myself, in the second one I have to query the database multiple times.

Is there a magical way I'm missing to fetch all B and C objects, ordered in one single method? Or at least a more efficient way to do this than the both mentioned?

Thanks in Advance!

Bruno

like image 863
Bruno Avatar asked Mar 02 '11 23:03

Bruno


People also ask

Can we inherit models in Django?

Model Inheritance in Django works almost identically to the way normal class inheritance works in python. In this article we will revolve around how to create abstract base class in Django Models. Abstract Base Class are useful when you want to put some common information into a number of other models.

What does .all do in Django?

Definition of the all() manager method: all() Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result.

What is multi table inheritance in Django?

In multi-table inheritance, each model corresponds to a database table. Django creates a OneToOneField field for the relationship in the child's model to its parent. To use multi-table inheritance, you have to subclass an existing model. Django will create a database table for both the original model and the sub-model.


2 Answers

If A can be concrete, you can do this all in one query using select_related.

from django.db import connection
q = A.objects.filter(NAME__istartswith='z').order_by('ORDER').select_related('b', 'c')
for obj in q:
   obj = obj.b or obj.c or obj
   print repr(obj), obj.__dict__ # (to prove the subclass-specific attributes exist)
print "query count:", len(connection.queries)
like image 191
DrMeers Avatar answered Oct 24 '22 12:10

DrMeers


This question was answered here.

Use the InheritanceManager from the django-model-utils project.

like image 24
Philipp Zedler Avatar answered Oct 24 '22 12:10

Philipp Zedler