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