Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django ForeignKey _set on an inherited model

I have two models Category and Entry. There is another model ExtEntry that inherits from Entry

class Category(models.Model):
    title = models.CharField('title', max_length=255)
    description = models.TextField('description', blank=True)
    ...

class Entry(models.Model):
    title = models.CharField('title', max_length=255)    
    categories = models.ManyToManyField(Category)
    ...

class ExtEntry(Entry):    
    groups= models.CharField('title', max_length=255)
    value= models.CharField('title', max_length=255)
    ...

I am able to use the Category.entry_set but I want to be able to do Category.blogentry_set but it is not available. If this is not available,then I need another method to get all ExtEntryrelated to one particular Category

EDIT My end goal is to have a QuerySet of ExtEntry objects

Thanks

like image 232
neolaser Avatar asked Jan 31 '11 22:01

neolaser


1 Answers

I need another method to get all ExtEntryrelated to one particular Category

Easy:

ExtEntry.objects.filter(categories=my_category)

Do you know if there is a way to use the _set feature of an inherited

I don't know if there is a direct they for that. It is not mentioned in documentation.

But it is possible to get similar results with the select_related.

for e in category.entry_set.select_related('extentry'):
    e.extentry # already loaded because of `select_related`, 
               # however might be None if there is no Extentry for current e

It is possible to select only entries which has ExtEntry:

for e in category.entry_set.select_related('extentry').exlude(extentry=None):
    e.extentry # now this definitely is something, not None

Bad thing about the exclude is that it generates terrybly inefficient query:

SELECT entry.*, extentry.* FROM entry
LEFT OUTER JOIN `extentry` ON (entry.id = extentry.entry_ptr_id) 
WHERE NOT (entry.id IN (SELECT U0.id FROM entry U0 LEFT OUTER JOIN 
                        extentry U1 ON (U0.id = U1.entry_ptr_id) 
                        WHERE U1.entry_ptr_id IS NULL))

So my resume would be: use ExtEntry.objects.filter() to get your results. The backwards relations (object.something_set) is just a convenience and does not work in every situation.

like image 110
Ski Avatar answered Nov 14 '22 21:11

Ski