phil0s0pher
phil0s0pher

Reputation: 545

Best way to write views for multiple queries in Django?

It's a simple question. I've organised my models so that most objects served to the page are of one type - Item. The model contains various attributes which help me serve it in different ways.

I have articles, and videos, which are determined by a 'type' field on the model. Type = 'article' etc.

I have a listview, which shows all the objects in the Item model, sorted by date.

class ItemListView(generic.ListView):

    # This handles the logic for the UserForm and ProfileForm - without it, nothing happens.
    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        # return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
        return Item.objects.all().order_by('-create_date')

I want a view which shows all the articles, sorted by date, and all the videos, sorted by date. I have a feeling I'll be writing many more such views.

Is there a better way to do it than to write a new view for every single query? As, this is what I'm currently doing:

Views.py

class ItemListViewArticle(generic.ListView):

    # This handles the logic for the UserForm and ProfileForm - without it, nothing happens.
    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        # return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
        return Item.objects.filter(type__contains='article').order_by('-create_date')

class ItemListViewVideo(generic.ListView):

    # This handles the logic for the UserForm and ProfileForm - without it, nothing happens.
    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        # return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
        return Item.objects.filter(type__contains='video').order_by('-create_date')

urls.py

    path('new/', views.ItemListView.as_view(), name='new_list'),
    path('new/articles', views.ItemListViewArticle.as_view(), name='article_list'),
    path('new/videos', views.ItemListViewVideo.as_view(), name='video_list'),

Upvotes: 2

Views: 1019

Answers (1)

ruddra
ruddra

Reputation: 51948

You can use URL querystring(ie request.GET) to get type of the item from url and filter by it. Like this:

path('new/', views.ItemListView.as_view(), name='new_list'),


class ItemListViewArticle(generic.ListView):

    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        content_type = self.request.GET.get('type')
        return Item.objects.filter(type__contains=content_type).order_by('-create_date')

# usage
localhost:8000/new/?type=article
localhost:8000/new/?type=video

Or you can use URL parameter to get the type of data:

path('new/<str:content_type>/', views.ItemListView.as_view(), name='new_list'),

class ItemListViewArticle(generic.ListView):

    def item(self, request, *args, **kwargs):
        return index(request)

    def get_queryset(self):
        content_type = self.kwargs.get('content_type')
        return Item.objects.filter(type__contains=content_type).order_by('-create_date')

# usage
localhost:8000/new/article/
localhost:8000/new/video/

Upvotes: 3

Related Questions