Django model inheritance with proxy classes

Viewed 64

I've got proxy classes which have been created mainly to implement custom filtering, but there are some other fairly small custom methods as well, and they will be expanded to provide other custom logic as well.

So say I have models:

class Videos(models.Model):
    title = models.CharField(max_length=200)
    publisher = models.Charfield(max_length=100)
    release_date = models.DateField()

class Superheroes(Videos):
    objects = SuperheroesManager()

    class Meta:
        proxy = True

class Recent(Videos):
    objects = RecentManager()

    class Meta:
        proxy = True

and model managers:

class SuperheroesManager():
    def get_queryset(self):
        return super().get_queryset().filter(publisher__in=['Marvel','DC'])

class RecentManager():
    def get_queryset(self):
        return super().get_queryset().filter(release_date__gte='2020-01-01')

On the front end a user may pick a category which corresponds to one of the proxy classes. What would be the best way to maintain a mapping between the category which is passed to the view and the associated proxy class?

Currently I have an implicit dependency whereby the category name supplied by the front end must be the same as the proxy class name, allowing for a standard interface in the view:

def index(request, report_picked)
    category = getattr(sys.modules[__name__], report_picked)
    videos = category.objects.all()

I'd like to move away from this implicit dependency, but not sure what the best way would be.

I wouldn't want to maintain a dictionary and can't use a factory method either as that should return a fully initialised object whereas I just need the class returned.

What would be the best way to implement this?

1 Answers

I've decided to set the category name used by the front end as a class variable:

class Superheroes(Videos):
    category = 'superheroes'
    objects = SuperheroesManager()

    class Meta:
        proxy = True

And so the view just loops through all the models, and returns the model whose category matches the provided value from the front end:

from django.apps import apps

def index(request, report_picked):
    for model in apps.get_models():
        try:
            print(f"Report picked: {report_picked}, model: {model.name}")
            if model.category == report_picked.lower():
                category = model
                break
        except AttributeError:
            pass

I'd be curious to know if there is any better alternatives though.

Related