我必须为手风琴菜单制作一个无序列表,其中树的最后一个“叶子”必须有一个特定的URL。
这些数据将从“类别”模型中获取:
class Category(models.Model):
name = models.CharField(max_length=50)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
所以,正如你在这里看到的,我们有一个“父母”和一个“孩子”。 如果某个类别没有父母,则为“无”,对于孩子也是如此(如果没有孩子,则为“无”)。
基于这个模型,我必须“创建”一个无序列表并将其显示为手风琴。
种类:
<ul>
<li>
<a>Category 1</a>
<ul>
<li>
<a>SubCategory 1</a>
<ul>
<li>
<a href="foo/">SubSubCategory 1</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a>Category 2</a>
<ul>
<li>
<a href="foo/">SubCategory 2</a>
</li>
</ul>
</li>
</ul>
我读过unordered-list,但似乎不是我需要的东西,所以我试着自己做点什么。
class ProductsListView(ListView):
template_name = 'main/products.html'
paginate_by = 9
model = Product
context_object_name = 'items'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['brands'] = Brand.objects.all()
self.html = ''
self.make_accordion(Category.objects.all())
context['html'] = self.html
return context
def make_accordion(self, categories, parent=None):
for category in [cat for cat in categories if cat.parent == parent]:
is_children = category.children.exists()
if not is_children:
self.html += '<li><a href="/products/category/{}">{}</a>'.format(
category.id, category.name
)
else:
self.html += '<li><a>{}</a>'.format(category.name)
if is_children:
self.html += '<ul>'
self.make_accordion(categories, category)
if is_children:
self.html += '</ul>'
self.html += '</li>'
此代码需要花费太多时间,比如显示页面前10秒。有没有办法做我真正需要做的事情?
编辑:
class ProductsListView(ListView):
template_name = 'main/products.html'
paginate_by = 1
model = Product
context_object_name = 'items'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['brands'] = Brand.objects.all()
self.html = ''
# Get each category, by making a list of tuples
self.categories = Category.objects.values_list('pk', 'name', 'parent__pk')
self.make_unordered_list()
context['html'] = self.html
return context
def get_children(self, parent):
for pk, name, parent_pk in self.categories:
if parent_pk == parent:
yield (pk, name, parent_pk)
def make_unordered_list(self, parent=None):
for pk, name, parent_pk in self.get_children(parent):
self.make_unordered_list(pk)