Django如何写DRY视图

时间:2015-12-29 19:29:11

标签: django django-views

我有很多观点,每次调用相同的函数,我想知道在我采用这种方法之前,如果不管怎么说我可以让它更干。

例如,我在网站上有很多页面,左侧菜单上有相同文章和照片的列表。因此,在我的每个观点中,我都会执行以下操作:

context_dict = {'articles': get_articles(blogger.id), 'photos': get_photos(blogger.id)}

return render_to_response('...', context_dict, context)

它必须存在一种方式,我不必每次都重复自己,因为它们在90%的页面上都是必需的。

3 个答案:

答案 0 :(得分:2)

重复查看功能的问题是许多人喜欢基于类的视图的原因之一。您可以实现一个方法,将这些变量添加到基类,然后让其他视图从该类继承,或者提供标准化的“渲染”方法。例如:

class BaseView(View):
    template = 'public/base_template.html'

    def get(self, *args, **options):
         return render_to_response(self.template, self.render_view())

    def render_view(self, *args, **options):
         context = {"photos": Photo.objects.all()}
         return context

class OtherView(BaseView):
    template = 'public/other_template.html'

    def render_view(self, *args, **options):
        context = super(OtherView, self).render_view(*args, **options)
        context['additional_context'] = True
        return context

......或类似的东西。然后,您不必担心使用已包含的变量调用render。

我可以通过基于函数的视图来思考一些方法来实现这一点,但我认为基于类的方法非常适合DRY原则,所以我认为我会传播福音:)

https://docs.djangoproject.com/en/1.9/topics/class-based-views/intro/

答案 1 :(得分:1)

你的意思是

def get_extra_context(blog_id):
    return {'articles': get_articles(blogger.id), 'photos': get_photos(blogger.id)}

当然,必须在每个视图中调用get_extra_context

答案 2 :(得分:1)

正如Robert Townley所说,基于阶级的观点对于遵守DRY原则非常有帮助。我经常使用一些简单的mixins在不同的视图之间共享一些逻辑。然后,如果基于类的视图需要此功能,则可以从此mixin继承。例如:

class BloggerMixin(object):
    articles_context_name = 'articles' 
    photos_context_name = 'photos'

    def get_blogger(self):
        """ I'm just assumming your blogger is the current user for simplicity.    
        (And I'm assuming they're logged in already)"""
        return self.request.user

    def get_articles(self):
        return Article.objects.filter(blogger=self.get_blogger())

    def get_photos(self):
        return Photo.objects.filter(blogger=self.get_blogger())

    def get_context_data(self, **kwargs):
        context = super(BloggerMixin, self).get_context_data(**kwargs)
        context[self.articles_context_name] = self.get_articles()
        context[self.photos_context_name] = self.get_photos()
        return context

这将允许您在需要它的基于类的视图上继承此额外功能:

class ExampleView(BloggerMixin, ListView):
    model = SomeOtherModel

我们非常简单的ExampleView类现在将在其上下文中包含Article,Photo和SomeOtherModel的列表。