我如何在我的 Django 博客侧边栏上显示类别列表?
How I display category list on my django blog sidebar?
我正在开发一个 Django 博客 我尝试使用 Django-categories pip,在成功设置之后,我能够将我的 post 归类到不同的类别中,但我没有忘记我如何在列表中显示我的博客的所有可用类别。
我尝试使用 {{ category.name }} 但博客侧边栏中没有显示任何内容。
views.py
from django.shortcuts import get_object_or_404
from django.http import HttpResponse, Http404
from django.template.loader import select_template
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DetailView, ListView
from .models import Category
def category_detail(request, path, template_name='categories/category_detail.html', extra_context={}):
path_items = path.strip('/').split('/')
if len(path_items) >= 2:
category = get_object_or_404(
Category,
slug__iexact=path_items[-1],
level=len(path_items) - 1,
parent__slug__iexact=path_items[-2])
else:
category = get_object_or_404(
Category,
slug__iexact=path_items[-1],
level=len(path_items) - 1)
templates = []
while path_items:
templates.append('categories/%s.html' % '_'.join(path_items))
path_items.pop()
templates.append(template_name)
context = {'category': category}
if extra_context:
context.update(extra_context)
return HttpResponse(select_template(templates).render(context))
def get_category_for_path(path, queryset=Category.objects.all()):
path_items = path.strip('/').split('/')
if len(path_items) >= 2:
queryset = queryset.filter(
slug__iexact=path_items[-1],
level=len(path_items) - 1,
parent__slug__iexact=path_items[-2])
else:
queryset = queryset.filter(
slug__iexact=path_items[-1],
level=len(path_items) - 1)
return queryset.get()
class CategoryDetailView(DetailView):
model = Category
path_field = 'path'
def get_object(self, **kwargs):
if self.path_field not in self.kwargs:
raise AttributeError("Category detail view %s must be called with "
"a %s." % (self.__class__.__name__, self.path_field))
if self.queryset is None:
queryset = self.get_queryset()
try:
return get_category_for_path(self.kwargs[self.path_field], self.model.objects.all())
except Category.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
def get_template_names(self):
names = []
path_items = self.kwargs[self.path_field].strip('/').split('/')
while path_items:
names.append('categories/%s.html' % '_'.join(path_items))
path_items.pop()
names.extend(super(CategoryDetailView, self).get_template_names())
return names
class CategoryRelatedDetail(DetailView):
path_field = 'category_path'
object_name_field = None
def get_object(self, **kwargs):
if self.path_field not in self.kwargs:
raise AttributeError("Category detail view %s must be called with "
"a %s." % (self.__class__.__name__, self.path_field))
queryset = super(CategoryRelatedDetail, self).get_queryset()
try:
category = get_category_for_path(self.kwargs[self.path_field])
except Category.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
return queryset.get(category=category)
def get_template_names(self):
names = []
opts = self.object._meta
path_items = self.kwargs[self.path_field].strip('/').split('/')
if self.object_name_field:
path_items.append(getattr(self.object, self.object_name_field))
while path_items:
names.append('%s/category_%s_%s%s.html' % (
opts.app_label,
'_'.join(path_items),
opts.object_name.lower(),
self.template_name_suffix)
)
path_items.pop()
names.append('%s/category_%s%s.html' % (
opts.app_label,
opts.object_name.lower(),
self.template_name_suffix)
)
names.extend(super(CategoryRelatedDetail, self).get_template_names())
return names
class CategoryRelatedList(ListView):
path_field = 'category_path'
def get_queryset(self):
if self.path_field not in self.kwargs:
raise AttributeError("Category detail view %s must be called with "
"a %s." % (self.__class__.__name__, self.path_field))
queryset = super(CategoryRelatedList, self).get_queryset()
category = get_category_for_path(self.kwargs[self.path_field])
return queryset.filter(category=category)
def get_template_names(self):
names = []
if hasattr(self.object_list, 'model'):
opts = self.object_list.model._meta
path_items = self.kwargs[self.path_field].strip('/').split('/')
while path_items:
names.append('%s/category_%s_%s%s.html' % (
opts.app_label,
'_'.join(path_items),
opts.object_name.lower(),
self.template_name_suffix)
)
path_items.pop()
names.append('%s/category_%s%s.html' % (
opts.app_label,
opts.object_name.lower(),
self.template_name_suffix)
)
names.extend(super(CategoryRelatedList, self).get_template_names())
return names
正如@iamhush 所指出的,为了清晰起见,需要 post 更多代码。
我假设您的 Category 是一个与您的 Post 模型相关的独立模型。在这种情况下,您可以:
在处理列表的类视图下实施 get_context_data() 并添加所有类别的查询集。
然后,您可以在侧边栏的相应模板标签下访问模板中的类别(对象)。例如。
class PostListView(ListView):
model = Post
template = ''
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['categories_list'] = Category.objects.all()
return context
然后在您的模板中:
{% for category in categories_list %}
{{ category }}
{% endfor %}
我正在开发一个 Django 博客 我尝试使用 Django-categories pip,在成功设置之后,我能够将我的 post 归类到不同的类别中,但我没有忘记我如何在列表中显示我的博客的所有可用类别。
我尝试使用 {{ category.name }} 但博客侧边栏中没有显示任何内容。
views.py
from django.shortcuts import get_object_or_404
from django.http import HttpResponse, Http404
from django.template.loader import select_template
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DetailView, ListView
from .models import Category
def category_detail(request, path, template_name='categories/category_detail.html', extra_context={}):
path_items = path.strip('/').split('/')
if len(path_items) >= 2:
category = get_object_or_404(
Category,
slug__iexact=path_items[-1],
level=len(path_items) - 1,
parent__slug__iexact=path_items[-2])
else:
category = get_object_or_404(
Category,
slug__iexact=path_items[-1],
level=len(path_items) - 1)
templates = []
while path_items:
templates.append('categories/%s.html' % '_'.join(path_items))
path_items.pop()
templates.append(template_name)
context = {'category': category}
if extra_context:
context.update(extra_context)
return HttpResponse(select_template(templates).render(context))
def get_category_for_path(path, queryset=Category.objects.all()):
path_items = path.strip('/').split('/')
if len(path_items) >= 2:
queryset = queryset.filter(
slug__iexact=path_items[-1],
level=len(path_items) - 1,
parent__slug__iexact=path_items[-2])
else:
queryset = queryset.filter(
slug__iexact=path_items[-1],
level=len(path_items) - 1)
return queryset.get()
class CategoryDetailView(DetailView):
model = Category
path_field = 'path'
def get_object(self, **kwargs):
if self.path_field not in self.kwargs:
raise AttributeError("Category detail view %s must be called with "
"a %s." % (self.__class__.__name__, self.path_field))
if self.queryset is None:
queryset = self.get_queryset()
try:
return get_category_for_path(self.kwargs[self.path_field], self.model.objects.all())
except Category.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
def get_template_names(self):
names = []
path_items = self.kwargs[self.path_field].strip('/').split('/')
while path_items:
names.append('categories/%s.html' % '_'.join(path_items))
path_items.pop()
names.extend(super(CategoryDetailView, self).get_template_names())
return names
class CategoryRelatedDetail(DetailView):
path_field = 'category_path'
object_name_field = None
def get_object(self, **kwargs):
if self.path_field not in self.kwargs:
raise AttributeError("Category detail view %s must be called with "
"a %s." % (self.__class__.__name__, self.path_field))
queryset = super(CategoryRelatedDetail, self).get_queryset()
try:
category = get_category_for_path(self.kwargs[self.path_field])
except Category.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': queryset.model._meta.verbose_name})
return queryset.get(category=category)
def get_template_names(self):
names = []
opts = self.object._meta
path_items = self.kwargs[self.path_field].strip('/').split('/')
if self.object_name_field:
path_items.append(getattr(self.object, self.object_name_field))
while path_items:
names.append('%s/category_%s_%s%s.html' % (
opts.app_label,
'_'.join(path_items),
opts.object_name.lower(),
self.template_name_suffix)
)
path_items.pop()
names.append('%s/category_%s%s.html' % (
opts.app_label,
opts.object_name.lower(),
self.template_name_suffix)
)
names.extend(super(CategoryRelatedDetail, self).get_template_names())
return names
class CategoryRelatedList(ListView):
path_field = 'category_path'
def get_queryset(self):
if self.path_field not in self.kwargs:
raise AttributeError("Category detail view %s must be called with "
"a %s." % (self.__class__.__name__, self.path_field))
queryset = super(CategoryRelatedList, self).get_queryset()
category = get_category_for_path(self.kwargs[self.path_field])
return queryset.filter(category=category)
def get_template_names(self):
names = []
if hasattr(self.object_list, 'model'):
opts = self.object_list.model._meta
path_items = self.kwargs[self.path_field].strip('/').split('/')
while path_items:
names.append('%s/category_%s_%s%s.html' % (
opts.app_label,
'_'.join(path_items),
opts.object_name.lower(),
self.template_name_suffix)
)
path_items.pop()
names.append('%s/category_%s%s.html' % (
opts.app_label,
opts.object_name.lower(),
self.template_name_suffix)
)
names.extend(super(CategoryRelatedList, self).get_template_names())
return names
正如@iamhush 所指出的,为了清晰起见,需要 post 更多代码。 我假设您的 Category 是一个与您的 Post 模型相关的独立模型。在这种情况下,您可以:
在处理列表的类视图下实施 get_context_data() 并添加所有类别的查询集。 然后,您可以在侧边栏的相应模板标签下访问模板中的类别(对象)。例如。
class PostListView(ListView):
model = Post
template = ''
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['categories_list'] = Category.objects.all()
return context
然后在您的模板中:
{% for category in categories_list %}
{{ category }}
{% endfor %}