Django how to filter queryset by a subclass using django model utils?

6.4k Views Asked by At

I am using django-model-utils for inheritance Managers. I want to get results of only one subclass at a time.

managers.py

from model_utils.managers import InheritanceManager
class PostManager(InheritanceManager):
    pass

models.py

from .managers import PostManager
class Post(models.Model):
    title = models.CharField(max_length=20)
    text = models.TextField()
    objects = PostManager()


class ImagePost(Post, models.Model):
    source = models.URLField()
    image = models.ImageField(upload_to="images/%Y/%m/%d")


class VideoPost(Post, models.Model):
    source = models.URLField()

I want to return results of only image type. by writing a simpler query like this.

Post.objects.filter(type='image').select_subclasses()

What i have tried:

if type == 'image':
    Post.objects.filter(imagepost__isnull=False).select_subclasses()

This works but is kind of anti-pattern, i don't want to write conditions in views for every content type.

Is there better way like defining a property in models or converting it into a manager method? or am i missing something?

1

There are 1 best solutions below

3
On BEST ANSWER

Have you tried to pass the class to select_subclasses method?

Post.objects.select_subclasses(ImagePost)

Check their doc about this feature.

Edit:

I misunderstood the question, but sounds like OP wants only the Post with type ImagePost. Doing select_subclasses(ImagePost) would fetch everything and convert the objects with type ImagePost to ImagePost instances. The solution should be as simple as :

image_posts = ImagePost.objects.all()