If you want to get the currently logged-in user
and use it—e.g at the top of every template, in class-based view it could be hard to achieve.
However there is an easy and pythonic/djangoic way to accomplish that: just use a Mixin
. Actually Django
framework consists of very wide range of Mixins
such as SingleObjectMixin
or TemplateResponseMixin
. For more detail: Django Class-based Mixins.
So now we can write our very own Mixin
to do the job:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.views.generic.base import ContextMixin
class UserContextMixin(ContextMixin):
"""Get current `User` from request and add it to context"""
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
user = self.request.user
context['user'] = user
return context
Above we inherit our Mixin
from built-in
ContextMixin
class which can be examined below:
class ContextMixin:
"""
A default context mixin that passes the keyword arguments received by
get_context_data() as the template context.
"""
extra_context = None
def get_context_data(self, **kwargs):
if 'view' not in kwargs:
kwargs['view'] = self
if self.extra_context is not None:
kwargs.update(self.extra_context)
return kwargs
Then you can inherit it in your Class-based view
like below:
from .utils.views import UserContextMixin
class OrderCreateView(UserContextMixin, CreateView):
template_name = "template.html"
success_url = reverse_lazy("product:order")
form_class = OrderModelForm
extra_context = {'some_detail': 'Some Other Info'}
…
So now you can use your user context
in your view's other attributes. Also you can access it in your templates such as below:
{% extends "app/base_site.html" %}
{% load staticfiles %}
{% block title %} Order {% endblock title %}
{% block content %}
…
User : {{ user }}
User Name : {{ user.name }}
…
{% endblock content %}
Pro Tip: Always inherit your Mixin
before Class-based View
classes.
All done!
Top comments (0)