Home > database >  Show blogpost suitable to the current category
Show blogpost suitable to the current category

Time:06-17

I want to filter my database based on the menuItem or category of my blog posts. With self.request.path I get something like '/py/' what represents one of my categories.

By now I do this way and it works fine, but is there a better way? Should I create for each category a different app and write it's own IndexView with fix queryset filter? If there is a better solution to my problem than I would happy to know :)

Here my CategoryIndexView:

class CategoryIndexView(ListView):
    model = Post
    template_name = 'blog/category_index.html'
    # context_object_name = 'category'

    def get_queryset(self):
        category = self.request.path[1:-1]
        if category.lower() == 'ml':
            query_set = Post.objects.filter(category=0)
        elif category.lower() == 'py':
            query_set = Post.objects.filter(category=1)
        elif category.lower() == 'kt':  
            query_set = Post.objects.filter(category=2) 
        elif category.lower() == 'cpp':
            query_set = Post.objects.filter(category=3)
        else: 
            query_set = Post.objects.filter(category=0)
        return query_set

Here a snippet of my urlpatterns:

urlpatterns = [
    path('about/', genViews.about, name='about'),
    path('imprint/', genViews.imprint, name='imprint'),
    path('admin/', admin.site.urls),
    path('',genViews.HomeView.as_view(), name='home'), 
    path('ml/',blogViews.CategoryIndexView.as_view(), name='machine_learning'),
    path('py/',blogViews.CategoryIndexView.as_view(), name='python'),
    path('kt/',blogViews.CategoryIndexView.as_view(), name='android'),
    path('cpp/',blogViews.CategoryIndexView.as_view(), name='cpp')
]

CodePudding user response:

There is a better way yes, try adding a parameter to the url, like so:

urls.py

...
    path("posts/<category>/", views.posts, name="posts"),
...

views.py

def posts(request, category):
    query_set = Post.objects.filter(category=0)
    ...  

CodePudding user response:

Yes, there's is a more efficient way of getting it done. I'd suggest that you use only one view to handle and filter the queryset based on the category clicked on. For example:

urls.py

urlpatterns = [
     # other URLs 
     path('categories/<str:category>/',blogViews.CategoryIndexView.as_view(), name='categories'),
     
     # [ <str:category> ] accepting the category the user clicks on to filter the database 
]

views.py

class CategoryIndexView(ListView):
     model = Post
     template_name = 'blog/category_index.html'
     # context_object_name = 'category'

     def get_queryset(self):
         # Using kwargs.get() to capture the category passed via the url
         category = self.kwargs.get('category', None)  

         queryset = Post.objects.filter(category__iexact=category)

         # If your category field is a FK field then use 
         # queryset = Post.objects.filter(category__name__iexact=category)

         return queryset 
  • Related