Django DRY基于类的视图

时间:2016-03-23 16:06:50

标签: python django dry django-class-based-views

我在我的django应用程序中使用CBV,并想知道如何在我的get_context_data和我的get_initial函数中获取实例而不重复代码。

示例:

class PostCreate(CreateView):
model = Post

def get_context_data(self, **kwargs):
    context = super(VariationCreate, self).get_context_data(**kwargs)
    blog_pk = self.kwargs.get('product_pk', None)
    blog = None
    if blog_pk:
        try:
            blog = Blog.objects.get(pk=blog_pk)
        except Blog.DoesNotExist:
            pass
    context['blog'] = blog
    return context

def get_initial(self, **kwargs):
    context = self.get_context_data(**kwargs)
    blog_pk = self.kwargs.get('product_pk', None)
    blog = None
    if blog_pk:
        try:
            blog = Blog.objects.get(pk=blog_pk)
            return {"blog": blog}
        except Blog.DoesNotExist:
            return {}

此处的目标是仅获取博客实例一次

3 个答案:

答案 0 :(得分:1)

覆盖dispatch方法,然后在那里获取博客。将其设置为属性self.blog。然后,您可以访问self.blogget_context_data视图中的get_initial属性。

class PostCreate(CreateView):

    def dispatch(self, *args, **kwargs):
        # code that fetches the blog and sets self.blog
        return super(PostCreate, self).dispatch(*args, **kwargs)

    def get_initial(self, **kwargs):
        initial = super(PostCreate, self).get_initial(**kwargs)
        if self.blog is not None:
            initial['blog'] = self.blog
        return initial

    def get_context_data(self, **kwargs):
        context = super(PostCreate, self).get_context_data(**kwargs)
        if self.blog is not None:
            context['blog'] = self.blog
        return context

答案 1 :(得分:0)

您可以编写一个类并在视图中扩展它:

CustomClass(object):

    def get_context_data(self, **kwargs):
        context = super(CustomClass, self).get_context_data(**kwargs)
        blog_pk = self.kwargs.get('product_pk', None)
        blog = None
        if blog_pk:
            try:
                blog = Blog.objects.get(pk=blog_pk)
            except Blog.DoesNotExist:
                pass
        context['product'] = product
        return context

    def get_initial(self, **kwargs):
        context = self.get_context_data(**kwargs)
        blog_pk = self.kwargs.get('product_pk', None)
        blog = None
        if blog_pk:
            try:
                blog = Blog.objects.get(pk=blog_pk)
                return {"blog": blog}
            except Blog.DoesNotExist:
                return {}

然后在你看来:

class PostCreate(CreateView, CustomClass):
    model = Post

    def get_context_data(self, *args, **kwargs):
        context = super(PostCreate, self).get_context_data(*args, **kwargs)
        # add something else if needed
        return context

答案 2 :(得分:0)

在重新阅读文档后,我找到了正确的方法:

  1. 在get_initial中获取博客实例并存储在self.blog
  2. 将self.blog添加到get_context_data
  3. 中的上下文 <_> get_initial在get_context_data之前运行,所以不要在get_context_data中获取博客实例,否则你会得到像我一样的错误:

    class PostCreate(CreateView):
    model = Post
    
    def get_initial(self, **kwargs):
        context = self.get_context_data(**kwargs)
        blog_pk = self.kwargs.get('product_pk', None)
        self.blog = None
        if blog_pk:
            try:
                self.blog = Blog.objects.get(pk=blog_pk)
                return {"blog": self.blog}
            except Blog.DoesNotExist:
                return {}
    
    def get_context_data(self, **kwargs):
        context = super(VariationCreate, self).get_context_data(**kwargs)
        context['blog'] = self.blog
        return context