Source code for permission.decorators.functionbase

# coding=utf-8
"""
permission_required decorator for generic function view
"""
import copy
from functools import wraps

from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404

from permission.decorators.utils import redirect_to_login


[docs]def permission_required(perm, queryset=None, login_url=None, raise_exception=False): """ Permission check decorator for function-base generic view This decorator works as function decorator Parameters ---------- perm : string A permission string queryset : queryset or model A queryset or model for finding object. With classbased generic view, ``None`` for using view default queryset. When the view does not define ``get_queryset``, ``queryset``, ``get_object``, or ``object`` then ``obj=None`` is used to check permission. With functional generic view, ``None`` for using passed queryset. When non queryset was passed then ``obj=None`` is used to check permission. Examples -------- >>> @permission_required('auth.change_user') >>> def update_auth_user(request, *args, **kwargs): ... pass """ def wrapper(view_func): @wraps(view_func) def inner(request, *args, **kwargs): _kwargs = copy.copy(kwargs) # overwrite queryset if specified if queryset: _kwargs["queryset"] = queryset # get object from view if "date_field" in _kwargs: fn = get_object_from_date_based_view else: fn = get_object_from_list_detail_view if fn.validate(request, *args, **_kwargs): obj = fn(request, *args, **_kwargs) else: # required arguments is not passed obj = None if not request.user.has_perm(perm, obj=obj): if raise_exception: raise PermissionDenied else: return redirect_to_login(request, login_url) return view_func(request, *args, **_kwargs) return inner return wrapper
[docs]def get_object_from_list_detail_view(request, *args, **kwargs): """ Get object from generic list_detail.detail view Parameters ---------- request : instance An instance of HttpRequest Returns ------- instance An instance of model object or None """ queryset = kwargs["queryset"] object_id = kwargs.get("object_id", None) slug = kwargs.get("slug", None) slug_field = kwargs.get("slug_field", "slug") if object_id: obj = get_object_or_404(queryset, pk=object_id) elif slug and slug_field: obj = get_object_or_404(queryset, **{slug_field: slug}) else: raise AttributeError( "Generic detail view must be called with either an " "object_id or a slug/slug_field." ) return obj
def _get_object_from_list_detail_view_validation(request, *args, **kwargs): if "queryset" not in kwargs: return False elif "object_id" not in kwargs and "slug" not in kwargs: return False return True get_object_from_list_detail_view.validate = _get_object_from_list_detail_view_validation
[docs]def get_object_from_date_based_view(request, *args, **kwargs): # noqa """ Get object from generic date_based.detail view Parameters ---------- request : instance An instance of HttpRequest Returns ------- instance An instance of model object or None """ import datetime import time from django.db.models.fields import DateTimeField from django.http import Http404 try: from django.utils import timezone datetime_now = timezone.now except ImportError: datetime_now = datetime.datetime.now year, month, day = kwargs["year"], kwargs["month"], kwargs["day"] month_format = kwargs.get("month_format", "%b") day_format = kwargs.get("day_format", "%d") date_field = kwargs["date_field"] queryset = kwargs["queryset"] object_id = kwargs.get("object_id", None) slug = kwargs.get("slug", None) slug_field = kwargs.get("slug_field", "slug") try: tt = time.strptime( "%s-%s-%s" % (year, month, day), "%s-%s-%s" % ("%Y", month_format, day_format), ) date = datetime.date(*tt[:3]) except ValueError: raise Http404 model = queryset.model if isinstance(model._meta.get_field(date_field), DateTimeField): lookup_kwargs = { "%s__range" % date_field: ( datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max), ) } else: lookup_kwargs = {date_field: date} now = datetime_now() if date >= now.date() and not kwargs.get("allow_future", False): lookup_kwargs["%s__lte" % date_field] = now if object_id: lookup_kwargs["pk"] = object_id elif slug and slug_field: lookup_kwargs["%s__exact" % slug_field] = slug else: raise AttributeError( "Generic detail view must be called with either an " "object_id or a slug/slug_field." ) return get_object_or_404(queryset, **lookup_kwargs)
def _get_object_from_date_based_view_validation(request, *args, **kwargs): if "queryset" not in kwargs: return False elif "year" not in kwargs or "month" not in kwargs or "day" not in kwargs: return False elif "object_id" not in kwargs and "slug" not in kwargs: return False return True get_object_from_date_based_view.validate = _get_object_from_date_based_view_validation