1

I use class-based view to update my model:

class BlogUpdateView(UpdateView):
    model=Blog

    def get_context_data(self, **kwargs):
        context = super(BlogUpdateView, self).get_context_data(**kwargs)
        context['author'] = get_object_or_404(User,
            username__iexact=self.kwargs['username'])
        return context

I want to follow the DRY principle and avoid repeating get_context_data in every view function. The question is nearly the same as this one. Relying on the answer given by @Jj I suppose my class to look like this:

class BlogMixin(object):
    def get_author(self):
      # How to get author?
      return author

    def get_context_data(self, **kwargs):
      context = super(BlogMixin, self).get_context_data(**kwargs)
      context['author'] = self.get_author()
      return context

My question is: How can I access object in mixin class?

UPDATE

Answer is given in mongoose_za comment. I can get author with this line:

author = User.objects.get(username__iexact=self.kwargs['username'])
Community
  • 1
  • 1
Vlad T.
  • 2,568
  • 3
  • 26
  • 40

1 Answers1

2

Your will land up something like this:

class BlogMixin(object):
    def get_author(self):
      # How to get author?
      # Assuming user is logged in. If not you must create him
      author = self.request.user
      return author

class BlogUpdateView(BlogMixin, UpdateView):
    model=Blog

    def get_context_data(self, **kwargs):
        context = super(BlogUpdateView, self).get_context_data(**kwargs)
        context['author'] = self.get_author()
        return context

When you do context = super(BlogUpdateView, self).get_context_data(**kwargs) then context will be your object.


First you add your mixin into the class constructor.

As you see here:

class BlogUpdateView(BlogMixin, UpdateView):

Now the base def get_context_data(self, **kwargs): will be overridden by your def get_context_data(self, **kwargs): from the BlogMixin mixin.

BUT you have also specified a def get_context_data(self, **kwargs): in your class BlogUpdateView(UpdateView): and in the end this is the get_context_data that will take effect.

Mixins are tricky to get the hang of. I feel it's best to learn by viewing other peoples examples. Take a look here

Edit: Realised that perhaps I didn't answer your question properly. If you want to have access to an object within your mixin you have to pass it in. For example I'll pass the context object to the mixin:

class BlogMixin(object):
    def get_author(self, context):
      # This is how to get author object
      author = User.objects.get(username__iexact=self.kwargs['username'])
      return context

class BlogUpdateView(BlogMixin, UpdateView):
    model=Blog

    def get_context_data(self, **kwargs):
        context = super(BlogUpdateView, self).get_context_data(**kwargs)
        return self.get_author(context)

The code isn't tested but the idea should be right

Vlad T.
  • 2,568
  • 3
  • 26
  • 40
darren
  • 18,845
  • 17
  • 60
  • 79
  • mongoose_za, thanks for the answer! The problem with getting object is that author is not the same as `request.user`, e.g when admin updates other user's blog entry. We have to get author out of `username` key, that is passed via GET (in url). – Vlad T. Jun 28 '12 at 12:23
  • 1
    OK. In that case you just change this line `context['author'] = self.request.user` and find the user however you want. Probably something like `context['author'] = User.objects.get(username__iexact=self.kwargs['username'])`. – darren Jun 28 '12 at 12:29
  • mongoose_za, I'm aware of how to use mixins, I just couldn't retrieve objects within mixin, and this was my question. Your last suggestion is working, thank you for that! – Vlad T. Jun 28 '12 at 12:41
  • @VladT. sorry if my answer was verbose. at least the last suggestion helped :) – darren Jun 28 '12 at 12:42
  • @VladT. If it did answer your question please tick the answer so the question can be marked as resolved. Thanks – darren Jun 28 '12 at 12:54