Home > Enterprise >  How to use same ListView class for different model?
How to use same ListView class for different model?

Time:01-21

There are 3 models (companies, divisions and staffgroups) to display as list.

I am trying to create a class base view extended from ListView to list various models through passing the model name in the URLpatterns.

I had created individual class view for each model but there are essentially copy paste codes. Is there a way to streamline the code into just one class and get the model from urlpath.

models.py

from django.db import models
...
class Company(models.Model):
    id = models.CharField(max_length=5, primary_key=True)
    name = models.CharField(max_length=100)
    is_active = models.BooleanField()
...
class Division(models.Model):
    id = models.CharField(max_length=5, primary_key=True)
    name = models.CharField(max_length=100)
    is_active = models.BooleanField()
...
class StaffGroup(models.Model):
    name = models.CharField(max_length=20)
    is_active = models.BooleanField()
...

urls.py

from django.urls import path
from srrp.views import srrpIndexView, srrpListView

app_name = 'srrp'

urlpatterns = [
    path('', srrpIndexView.as_view(), name='srrp_index'),
    path('<str:modelname>', srrpListView.as_view(), name='srrp_list'),   
] 

views.py

class srrpListView(ListView):
    template_name = 'srrp/srrplist.html'
    model = self.kwargs['modelname'] # I know this is wrong, this is just placeholder for the right solution
    paginate_by = 10 

CodePudding user response:

Subclass get_queryset. (Bookmark Classy Class-based views)

def get_queryset(self):
     model = self.kwargs['modelname']
     if model == 'foo':
          return Foo.objects.all()
     if model == 'bar':
          return Bar.objects.all()
     if model == 'green_bar':
          return Bar.objects.filter( colour='green' )
     ...
     raise ValueError(
          f'This shouldn't be possible: model = "{model}"'

If you don't want any "special" models, you could either look up the right model in a dict of classes:

klass = MODEL_CLASSES[model] # KeyError if bad model in URL 
return klass.objects.all()

or you could use a Django function whose name I have forgotten to get the model class by app and model names.

CodePudding user response:

Solved.

views.py

class srrpListView(ListView):
    template_name = 'srrp/srrplist.html'
    paginate_by = 10 
    
    def get_queryset(self):
        modelname = self.kwargs['modelname']
        ctype = ContentType.objects.get(app_label='srrp', model=modelname)
        model = ctype.model_class()
        return model.objects.all()
  •  Tags:  
  • Related