对所有视图使用args不重复django

时间:2016-08-25 23:19:34

标签: django views

我在django视图中遇到过一个问题。我正在为我的菜单获取类别,例如:

args['categs'] = ArticleCategory.objects.filter(category_language=4).order_by('id')

所以,让我们说,我有

  1. 主页查看
  2. 文章列表视图
  3. 文章视图
  4. 等等......

    问题是我必须写:

    args['categs'] = ArticleCategory.objects.filter(category_language=4).order_by('id')
    

    对于所有视图,如果我从此列表中排除某些类别,那么我必须对所有视图进行更改

    如何为所有视图使用args一次?

3 个答案:

答案 0 :(得分:1)

如果您想在模板中提供类别,那么我建议您使用ContextProcessor:参见Dajgno Documention

但是,如果您希望仅出于其他原因将它们包含在所有视图中,那么我会使用mixin。见Django Documentation again

以下是我在所有观点中继承的示例mixin:

class BlogPostMixin(View):
    """
    A mixin that renders BlogPost form on GET request and processes it on POST request.
    """

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        """ this is fired up first regardless of what http method is used """
        return super(BlogPostMixin, self).dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        #context = RequestContext(self.request)
        context = super(BlogPostMixin, self).get_context_data(**kwargs)
        try:
            context['form'] = kwargs['form']
            context['attachment_form'] = kwargs['attachments_formset']
            context['attachment_helper'] = AttachmentFormsetHelper()
        except Exception as e:
            pass
        return context

我在我看来使用这个mixin:

class BlogPostUpdateView(BlogPostMixin, UpdateView):
    """
    A view that updates existing blogposts. The form_valid and form_invalid methods
    are handled in in BlogPostMixin because that code is shared between this view and
    the CreateView for blogpost.
    """
    model = BlogPost
    form_class = BlogPostForm
    template_name = 'blog/blogpost_form.html'

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(BlogPostUpdateView, self).get(request, *args, **kwargs)

答案 1 :(得分:0)

因为这与数据库中的过滤类别有关,所以您可以扩展ArticleCategory模型管理器:

from django.db import models


class ArticleCategoryManager(models.Manager):
    def for_menu(self, model):
        return self.filter(category_language=4).order_by('id')


class ArticleCategory(models.Model):        
    objects = ArticleCategoryManager()

然后你只需要写:

args['categs'] = ArticleCategory.objects.for_menu()

并不关心它们是如何被实际检索的。如果你需要改变获取它们的逻辑 - 你只能在一个地方改变它 - 用经理的方法。

关于重复的参数 - 我没有看到它的问题,因为只有一个参数和三个视图,如果更大的数量使用mixin或helper方法来获取那组参数。

P.S。一点建议 - 不要使用硬编码的幻数,比如4,而是使用常量。

答案 2 :(得分:0)

相信,有三件事可以改进:

  • 避免在视图中重复相同的代码。您必须实施Mixin以向视图添加适当的功能
  • 将filter()逻辑移动到相应的Manager方法:

    class ArticleCategoryManager(models.Manager):
        def menu_categories(self, model, language = 4):
            return self.filter(category_language=language).order_by('id')
    
    class ArticleCategory(models.Model):
        object = ArticleCategoryManager()
    

使用默认语言ID:

args['categs'] = ArticleCategory.objects.menu_categories()

明确设置语言:

args['categs'] = ArticleCategory.objects.menu_categories(language=4)
  • 用常数替换4:难以阅读此类代码&你必须花一些时间来理解这个价值的含义。

    实施示例:

    class ArticleCategoryLanguage(object):
        GERMAN = 3
        ENGLISH = 4
    
        LANGUAGES = (
            (GERMAN, 'German'),
            (ENGLISH, 'English')
        )
    

    用法:

    args['categs'] = ArticleCategory.objects.menu_categories(language=ArticleCategoryLanguage.ENGLISH)