M
M
Maxim2017-08-28 09:54:55
Django
Maxim, 2017-08-28 09:54:55

How to write a decorator in django?

Hello, how does decorator work in django?
There is a certain function

@csrf_exempt
@ratelimit
def user_login(request):
    if request.method == 'POST':
        data = req_data(request)

Option number 1
def ratelimit(func):

    def wrapper():
        print('Code before func')
        func()
        print('Code after func')
    return wrapper

Internal Server Error: /api/v1/user/login
Traceback (most recent call last):
  File "/home/maxim/buzz/lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/maxim/buzz/lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/maxim/buzz/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
TypeError: wrapper() takes 0 positional arguments but 1 was given

Option number 2
def ratelimit(func):

    def wrapper(*args):
        print(args)
        print('Code before func')
        func()
        print('Code after func')
    return wrapper

Request passed but now another error occurs
(<WSGIRequest: POST '/api/v1/user/login'>,)
Code before func
Internal Server Error: /api/v1/user/login
Traceback (most recent call last):
  File "/home/maxim/buzz/lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/maxim/buzz/lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/maxim/buzz/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/maxim/PycharmProjects/back_new/app/back/api/utils/ratelimit.py", line 6, in wrapper
    func()
TypeError: user_login() missing 1 required positional argument: 'request'
[28/Aug/2017 06:51:19] "POST /api/v1/user/login HTTP/1.1" 500 72325

What exactly is wrong in this example?
Second mistake
(<WSGIRequest: POST '/api/v1/user/login'>,)
Code before func
Code after func
Internal Server Error: /api/v1/user/login
Traceback (most recent call last):
  File "/home/maxim/buzz/lib/python3.5/site-packages/django/core/handlers/base.py", line 158, in get_response
    % (callback.__module__, view_name))
ValueError: The view api.utils.ratelimit.wrapper didn't return an HttpResponse object. It returned None instead.
[28/Aug/2017 07:00:33] "POST /api/v1/user/login HTTP/1.1" 500 59845

For example, I do not need the decorator to give a response, and then the user_login function continues to be executed, what should I do in such cases?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
Neyury, 2017-08-28
@maximkv25

You funcdidn't pass in the parameters that are passed to the wrapper function.

def decor(func):
    def inner(*args, **kwargs):
        print('start')
        func(*args, **kwargs)
        print('end')
    return inner

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question