[Fixed]-Django DRY class based view

1👍

Override the dispatch method, and fetch the blog there. Set it as an attribute self.blog. Then, you can access the self.blog attribute in your get_context_data and get_initial views.

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

0👍

You can write a class and extend it in your view:

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 {}

Then in your view:

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
👤Gocht

0👍

Ok after re-reading the documentation I found the correct way to do this :

  1. fetch the blog instance in get_initial and store in in self.blog
  2. add self.blog to the context in get_context_data

get_initial is ran before get_context_data so do not fetch the blog instance in get_context_data otherwise you’ll get an error like I did :

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

Leave a comment