6 лучших декораторов Django

Spread the love

Перевод: Pablo IglesiasTop 6 Django Decorators

Что такое декоратор?

Декоратор – это название одного из самых популярных шаблонов проектирования, используемых в настоящее время, хотя часто мы используем его, не зная, что это именно шаблон проектирования. А что такого особенного в этом шаблоне? Как мы можем прочитать в Python Wiki, это способ явно изменить поведение объекта, заключив его в декорируемый объект с аналогичным интерфейсом. Вы можете почитать больше о дизайне паттернов здесь.

Почему я должен использовать декораторы в своем веб-приложении?

Декораторы динамически изменяют функциональность функции, метода или класса без необходимости создавать подклассы или изменять исходный код декорированного класса. Благодаря этому наш код будет более чистым, более читаемым, удобным в обслуживании (что немаловажно), что позволит нам добавлять функциональность к нескольким классам с помощью одного метода.

Хороший пример важности и простоты использования этих декораторов можно увидеть в декораторе @login_required, который предоставляет django, и который вы, вероятно, использовали, если у вас есть некоторый опыт работы с нашим любимым фреймворком. Это всего лишь фрагмент кода, в котором мы проверяем, аутентифицирован ли пользователь, и перенаправляем его если нет на URL-адрес логирования.

Декораторы используются следующим образом:

from django.contrib.auth.decorators import login_required


@login_required
def my_view(request)
    …

Каждый раз, когда пользователь пытается получить доступ к my_view, запускается код внутри login_required.

Некоторые из наших любимых декораторов

В этой статье мы расскажем о некоторых декораторах, которые мы считаем наиболее полезными или которые мы когда-либо использовали с положительными результатами, имейте в виду, что многие из них можно настроить в соответствии с вашими потребностями.

Group Required

Иногда нам нужно защитить некоторые представления, чтобы позволить определенной группе пользователей получить к ним доступ. Вместо того, чтобы проверять, принадлежит ли пользователь к этой группе/группам, мы можем использовать следующий декоратор

from django.contrib.auth.decorators import user_passes_test


def group_required(*group_names):
   """Requires user membership in at least one of the groups passed in."""

   def in_groups(u):
       if u.is_authenticated():
           if bool(u.groups.filter(name__in=group_names)) | u.is_superuser:
               return True
       return False
   return user_passes_test(in_groups)


# The way to use this decorator is:
@group_required(‘admins’, ‘seller’)
def my_view(request, pk)
    ...

Вы можете прочитать о нем более подробно здесь.

Anonymous required

Этот декоратор основан на декораторе login_required Django, но используется в противоположном случае, когда пользователь является анонимным, в противном случае пользователь перенаправляется на веб-сайт, определенный в нашем settings.py, и может быть полезен, когда мы хотим защитить зарегистрированные просмотры пользователей. , например, вьюхи логирования или регистрации

def anonymous_required(function=None, redirect_url=None):

   if not redirect_url:
       redirect_url = settings.LOGIN_REDIRECT_URL

   actual_decorator = user_passes_test(
       lambda u: u.is_anonymous(),
       login_url=redirect_url
   )

   if function:
       return actual_decorator(function)
   return actual_decorator


# The way to use this decorator is:
@anonymous_required
def my_view(request, pk)
    ...

Вы можете почитать о нем здесь.

Superuser required

Это тот же случай, когда мы хотим разрешить определенным группам доступ к представлению, но в этом случае только суперпользователи могут посещать его.

from django.core.exceptions import PermissionDenied


def superuser_only(function):
  """Limit view to superusers only."""

   def _inner(request, *args, **kwargs):
       if not request.user.is_superuser:
           raise PermissionDenied           
       return function(request, *args, **kwargs)
   return _inner


# The way to use this decorator is:
@superuser_only
def my_view(request):
    ...

Вы можете почитать более подробно здесь.

Ajax required

Этот декоратор проверяет, является ли запрос запросом AJAX. Этот декоратор, используется когда мы работаем с Javascript фреймворками такими как jQuery.

from django.http import HttpResponseBadRequest


def ajax_required(f):
   """
   AJAX request required decorator
   use it in your views:

   @ajax_required
   def my_view(request):
       ....

   """   

   def wrap(request, *args, **kwargs):
       if not request.is_ajax():
           return HttpResponseBadRequest()
       return f(request, *args, **kwargs)

   wrap.__doc__=f.__doc__
   wrap.__name__=f.__name__
   return wrap


# The way to use this decorator is:
@ajax_required
def my_view(request):
    ...

Вы можете почитать более подробно здесь.

Time it

Этот декоратор очень полезен, если вам нужно улучшить время отклика одного из наших представлений или если вы просто хотите знать, сколько времени требуется для его выполнения.

def timeit(method):

   def timed(*args, **kw):
       ts = time.time()
       result = method(*args, **kw)
       te = time.time()
       print('%r (%r, %r) %2.2f sec' % (method.__name__, args, kw, te - ts))
       return result

   return timed


# The way to use this decorator is:
@timeit
def my_view(request):
    ...

Вы можете почитать более подробно здесь.

Пользовательские функции

Следующий декоратор – это просто пример того, как вы можете легко и на 100% настраивать некоторые разрешения или проверки.

Представьте, что у вас есть блог, магазин, форум … Если пользователям нужно набрать определенное количество баллов, чтобы написать отзыв, например, что бы избежать спама. Мы создадим декоратор, чтобы проверить, что пользователь вошел в систему и набрал более 10 баллов, чтобы он мог написать отзыв, в противном случае мы поднимем Forbidden

from django.http import HttpResponseForbidden


logger = logging.getLogger(__name__)


def user_can_write_a_review(func):
   """View decorator that checks a user is allowed to write a review, in negative case the decorator return Forbidden"""

   @functools.wraps(func)
   def wrapper(request, *args, **kwargs):
       if request.user.is_authenticated() and request.user.points < 10:
           logger.warning('The {} user has tried to write a review, but does not have enough points to do so'.format( request.user.pk))
           return HttpResponseForbidden()

       return func(request, *args, **kwargs)

   return wrapper

Вы можете получить дополнительную информацию об этом, спросив меня, по адресу piglesias@emergya.com или через twitter @pypiglesias. Я очень надеюсь, что вы нашли этот пост интересным или, по крайней мере, любопытным. В BeDjango мы хотели бы предложить вам поделиться своими декораторами, идеями или вопросами, а также интересными темами для будущих публикаций.

Была ли вам полезна эта статья?
[7 / 3.3]

Spread the love
Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments