[Django]-How to inject same context in many different Django views?

8👍

Mixins don’t need to be views, but it helps IDE’s if they have the methods they’re overriding.

Contexts are handled by django.views.generic.base.ContextMixin (details on this very handy site), So the class-based views way of things would be this:

from django.views import generic

class WebsiteCommonMixin(generic.base.ContextMixin):
    page_title = ''
    active_menu = None

    def get_context_data(self, **kwargs):
        context = super(WebsiteCommonMixin, self).get_context_data(**kwargs)
        context.update(dict(page_title=self.page_title, active_menu=self.active_menu))
        return context

class NewsListView(WebsiteCommonMixin, ListView):
    page_title = 'News list'
    active_menu = 'News'
    model = News
    paginate_by = 12

I do this for many projects and the simple views you have to create anyway, are fully declarative. And by simple, I mean that they can consist of mulitple mixins, all doing the hard stuff in either get_queryset, get_context_data or form_valid. More elaborate example, straight from a project:

class FeedbackMixin(object):
    message = 'Well Done!'

    def __init__(self):
        self._message_kwargs = {}
        super().__init__()

    def add_message_kwarg(self, name, value) -> None:
        self._message_kwargs[name] = value

    def format_message(self, kwargs) -> str:
        return self.message.format(**kwargs)

    def generate_message(self) -> None:
        msg = self.format_message(self._message_kwargs)
        messages.success(getattr(self, 'request'), msg)


class ModelFeedbackMixin(FeedbackMixin, generic.edit.ModelFormMixin):
    success_view_name = None
    success_url_kwargs = None

    def get_success_url_kwargs(self):
        return self.success_url_kwargs

    def get_success_url(self) -> str:
        success_url_kwargs = self.get_success_url_kwargs()
        if not self.success_view_name:
            url = super().get_success_url()
        elif success_url_kwargs is not None:
            url = reverse(self.success_view_name, kwargs=success_url_kwargs)
        else:
            if hasattr(self.object, 'slug'):
                url_kwargs = {'slug': self.object.slug}
            else:
                url_kwargs = {'pk': self.object.pk}
            url = reverse(self.success_view_name, kwargs=url_kwargs)
        return url

    def form_valid(self, form):
        response = super().form_valid(form)
        self.generate_message()
        return response

0👍

Maybe this way could be easier to read…

def add_context(func):
# this is a wrapper function
    def wrapper(*args, **kwargs):
        context_data = func(*args, **kwargs)
        context_data['some_object'] = SomeObjects.objects.get(pk=1)
        return context_data
return wrapper


class UpdateAnotherObjectView(BaseObjectInfo, UpdateView):
    template_name = 'create_object.html'
    form_class = AnotherObjectForm
    model = AnotherObjects

    @add_context
    def get_context_data(self, **kwargs):
        kwargs['all_another_objects'] = AnotherObjects.objects.all()
        return kwargs
👤renzop

Leave a comment