Как использовать один и тот же класс ListView для разных моделей?

Есть 3 модели (компании, подразделения и штабные группы) для отображения в виде списка.

Я пытаюсь создать базовый класс представления, расширенный из ListView, чтобы перечислять различные модели, передавая имя модели в шаблонах URL.

Я создал отдельный класс представления для каждой модели, но там по сути копи-паст коды. Есть ли способ упростить код до одного класса и получить модель из 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 

Подкласс get_queryset. (Закладка Виды, основанные на классах)

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}"'

Если вам не нужны "специальные" модели, вы можете либо найти нужную модель в дикте классов:

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

Или вы можете использовать функцию Django, название которой я забыл, чтобы получить класс модели по имени приложения и модели.

Решено.

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()
Вернуться на верх