有哪些更改Django / python模块行为的选项?

时间:2016-08-11 16:35:10

标签: python django django-models wagtail

我希望在不重新实现模块的大部分的情况下更改类方法的行为。我有什么选择呢?

我在当前项目中使用wagtail_blog模块。为Blog和BlogIndexPage创建单独的模型。 BlogIndexPage返回所有相关博客页面的列表。我想介绍一种方法来按类别限制返回的页面,这就是我的问题所在 - 这样做的最佳选择是什么?

  • 我可以创建一个新的应用程序(MyBlog),继承原始类, 并覆盖get_context()。这个问题是我会 还需要重新实现代码的其他部分作为对象名称 现在会有所不同。

  • 我可以分叉原始仓库,添加我的更改,然后使用它 我的项目。同样,很多工作都需要进行一些小改动。

  • 你聪明的人可以建议更优雅。

其他人如何正常处理这种情况?

为了完整性,这是我正在处理的代码:

def get_blog_context(context):
    """ Get context data useful on all blog related pages """
    context['authors'] = get_user_model().objects.filter(
        owned_pages__live=True,
        owned_pages__content_type__model='blogpage'
    ).annotate(Count('owned_pages')).order_by('-owned_pages__count')
    context['all_categories'] = BlogCategory.objects.all()
    context['root_categories'] = BlogCategory.objects.filter(
        parent=None,
    ).prefetch_related(
        'children',
    ).annotate(
        blog_count=Count('blogpage'),
    )
    return context


class BlogIndexPage(Page):
    @property
    def blogs(self):
        # Get list of blog pages that are descendants of this page
        blogs = BlogPage.objects.descendant_of(self).live()
        blogs = blogs.order_by(
            '-date'
        ).select_related('owner').prefetch_related(
            'tagged_items__tag',
            'categories',
            'categories__category',
        )
        return blogs

    def get_context(self, request, tag=None, category=None, author=None, *args,
                    **kwargs):
        context = super(BlogIndexPage, self).get_context(
            request, *args, **kwargs)
        blogs = self.blogs

        if tag is None:
            tag = request.GET.get('tag')
        if tag:
            blogs = blogs.filter(tags__slug=tag)
        if category is None:  # Not coming from category_view in views.py
            if request.GET.get('category'):
                category = get_object_or_404(
                    BlogCategory, slug=request.GET.get('category'))
        if category:
            if not request.GET.get('category'):
                category = get_object_or_404(BlogCategory, slug=category)
            blogs = blogs.filter(categories__category__name=category)
        if author:
            if isinstance(author, str) and not author.isdigit():
                blogs = blogs.filter(author__username=author)
            else:
                blogs = blogs.filter(author_id=author)

        # Pagination
        page = request.GET.get('page')
        page_size = 10
        if hasattr(settings, 'BLOG_PAGINATION_PER_PAGE'):
            page_size = settings.BLOG_PAGINATION_PER_PAGE

        if page_size is not None:
            paginator = Paginator(blogs, page_size)  # Show 10 blogs per page
            try:
                blogs = paginator.page(page)
            except PageNotAnInteger:
                blogs = paginator.page(1)
            except EmptyPage:
                blogs = paginator.page(paginator.num_pages)

        context['blogs'] = blogs
        context['category'] = category
        context['tag'] = tag
        context['author'] = author
        context['COMMENTS_APP'] = COMMENTS_APP
        context = get_blog_context(context)

        return context

    class Meta:
        verbose_name = _('Blog index')
    subpage_types = ['blog.BlogPage']

1 个答案:

答案 0 :(得分:0)

我不熟悉wagtail CMS,但我想你可以这样做:

class MyBlogIndexPage(BlogIndexPage):
    def get_context(self, *args, **kwargs):
        context = super(MyBlogIndexPage, self).get_context(*args, **kwargs)
        #do context changes
        return context

现在覆盖使用旧view/views的{​​{1}}。 (我再次对wagtail系统不熟悉,只看到BlogIndexPage正在使用BlogIndexPage。)

def my_tag_view(request, tag):
    index = MyBlogIndexPage.objects.first()
    return index.serve(request, tag=tag)

最后覆盖url以使用您的view

url(r'^tag/(?P<tag>[-\w]+)/', views.my_tag_view, name="tag"),