我一直在確保自己已經嘗試了各種可能的途徑,然後纔來到這裏尋求建議。W Multi的多級分類
這就是說,這是我目前正在掙扎的;創建多級/嵌套類別。順便說一句,如果w core核心開發人員可以實現創建多級別類別的簡單方法,而不需要爲它編寫一些vanilla-django破解程序,那將會很不錯。
我一直在這個應用程序工作了幾個星期,一切運行順利,除了現在,有一個嵌套類別的業務決策實施。
我的初始M.O是創建一個ServiceCategoryIndex頁面,一個ServiceCategoryPage然後使ServiceIndex頁面作爲ServiceCategoryPage的ServiceCategoryIndex頁面的後代或可訂購,這只是不正確。
經過幾次迭代後,我回到了我的默認模型,然後嘗試使用視圖和url類似vanilla-django的類別的URL,問題是,我無法查詢與外鍵通過關係模板,所以我仍然無法獲得服務頁面的內容作爲列表查詢集呈現出來。
這裏是我的模型代碼,任何建議或解決此問題將是絕對有用的。 P.S:我幾乎是在用vanilla-django重寫整個項目的時候,因爲在接下來的幾天裏我找不到解決方案。
def get_service_context(context):
context['all_categories'] = ServiceCategory.objects.all()
context['root_categories'] = ServiceCategory.objects.filter(
parent=None,
).prefetch_related(
'children',
).annotate(
service_count=Count('servicepage'),
)
return context
class ServiceIndexPage(Page):
header_image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
heading = models.CharField(max_length=500, null=True, blank=True)
sub_heading = models.CharField(max_length=500, null=True, blank=True)
body = RichTextField(null=True, blank=True)
def get_context(self, request, category=None, *args, **kwargs):
context = super(ServiceIndexPage, self).get_context(request, *args, **kwargs)
services = ServicePage.objects.child_of(self).live().order_by('-first_published_at').prefetch_related('categories', 'categories__category')
if category is None:
if request.GET.get('category'):
category = get_object_or_404(ServiceCategory, slug=request.GET.get('category'))
if category:
if not request.GET.get('category'):
category = get_object_or_404(ServiceCategory, slug=category)
services = services.filter(categories__category__name=category)
# Pagination
page = request.GET.get('page')
page_size = 10
if hasattr(settings, 'SERVICE_PAGINATION_PER_PAGE'):
page_size = settings.SERVICE_PAGINATION_PER_PAGE
if page_size is not None:
paginator = Paginator(services, page_size) # Show 10 services per page
try:
services = paginator.page(page)
except PageNotAnInteger:
services = paginator.page(1)
except EmptyPage:
services = paginator.page(paginator.num_pages)
context['services'] = services
context['category'] = category
context = get_service_context(context)
return context
@register_snippet
class ServiceCategory(models.Model):
name = models.CharField(max_length=250, unique=True, verbose_name=_('Category Name'))
slug = models.SlugField(unique=True, max_length=250)
parent = models.ForeignKey('self', blank=True, null=True, related_name="children")
date = models.DateField(auto_now_add=True, auto_now=False, null=True, blank=True)
description = RichTextField(blank=True)
class Meta:
ordering = ['-date']
verbose_name = _("Service Category")
verbose_name_plural = _("Service Categories")
panels = [
FieldPanel('name'),
FieldPanel('parent'),
FieldPanel('description'),
]
def __str__(self):
return self.name
def clean(self):
if self.parent:
parent = self.parent
if self.parent == self:
raise ValidationError('Parent category cannot be self.')
if parent.parent and parent.parent == self:
raise ValidationError('Cannot have circular Parents.')
def save(self, *args, **kwargs):
if not self.slug:
slug = slugify(self.name)
count = ServiceCategory.objects.filter(slug=slug).count()
if count > 0:
slug = '{}-{}'.format(slug, count)
self.slug = slug
return super(ServiceCategory, self).save(*args, **kwargs)
class ServiceCategoryServicePage(models.Model):
category = models.ForeignKey(ServiceCategory, related_name="+", verbose_name=_('Category'))
page = ParentalKey('ServicePage', related_name='categories')
panels = [
FieldPanel('category'),
]
class ServicePage(Page):
header_image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
verbose_name=_('Header image')
)
service_title = models.CharField(max_length=300, null=True, blank=True)
body = StreamField([
('h1', CharBlock(icon="title", classanme="title")),
('h2', CharBlock(icon="title", classanme="title")),
('h3', CharBlock(icon="title", classanme="title")),
('h4', CharBlock(icon="title", classanme="title")),
('h5', CharBlock(icon="title", classanme="title")),
('h6', CharBlock(icon="title", classanme="title")),
('paragraph', RichTextBlock(icon="pilcrow")),
('aligned_image', ImageBlock(label="Aligned image", icon="image")),
('pullquote', PullQuoteBlock()),
('raw_html', RawHTMLBlock(label='Raw HTML', icon="code")),
('embed', EmbedBlock(icon="code")),
])
date = models.DateField("Post date")
service_categories = models.ManyToManyField(ServiceCategory, through=ServiceCategoryServicePage, blank=True)
feed_image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
verbose_name=_('Feed image')
)
search_fields = Page.search_fields + [
index.SearchField('body'),
index.SearchField('service_title'),
index.SearchField('title'),]
def get_absolute_url(self):
return self.url
def get_service_index(self):
# Find closest ancestor which is a service index
return self.get_ancestors().type(ServiceIndexPage).last()
def get_context(self, request, *args, **kwargs):
context = super(ServicePage, self).get_context(request, *args, **kwargs)
context['services'] = self.get_service_index().serviceindexpage
context = get_service_context(context)
return context
class Meta:
verbose_name = _('Service page')
verbose_name_plural = _('Services pages')
parent_page_types = ['services.ServiceIndexPage']
ServicePage.content_panels = [
FieldPanel('title', classname="full title"),
FieldPanel('service_title'),
ImageChooserPanel('header_image'),
FieldPanel('date'),
InlinePanel('categories', label=_("Categories")),
StreamFieldPanel('body'),
ImageChooserPanel('feed_image'),
]
您需要多少層次的嵌套?另外,您是否需要選擇「組」類別還是僅選擇最低級別的「類別」? –
理想情況下,嵌套的級別應儘可能多,但2將會很好。並且是類別組。 –