0

I was using some custom middleware to check auth of users. This was working great but I don't want to run this middleware on every url.

Suggestions point towards using @decorator_from_middleware before each view that you want middleware to run, this would be ideal. Some of my view should be global, others behind auth.

I cant seem to import the middleware to call it in the views file.

My views.py:

from myapp.middleware import *

@decorator_from_middleware(AuthCheckMiddleware)
def index(request):
    return render(request, "index.html")

My myapp.middleware.authCheck.py:

class AuthCheckMiddleware(object):
def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    #CHECK AUTH HERE
    response = self.get_response(request)
    return response

def process_exception(self, request, exception): 
    return None

The error I get:

  File "/vagrant/myapp/django-project/isadmin/web/views.py", line 93, in <module>
@decorator_from_middleware(AuthCheckMiddleware)
NameError: name 'AuthCheckMiddleware' is not defined
Dan Walters
  • 1,218
  • 1
  • 18
  • 30

1 Answers1

2

This is standard Python behaviour. Unless you explicitly import AuthCheckMiddleware in the __init__.py of myapp.middleware, it won't be imported by from myapp.middleware import *.

But really you should never be doing this anyway. There's very rarely a good reason to do import *; always import the things you need explicitly.

from myapp.middleware.authCheck import AuthCheckMiddleware

Also note, Python style is for modules to have lower_case_with_underscore names: it should be auth_check.py.

Also also note, Python does not require or expect each class to be in a separate file, so you could have myapp/middleware.py containing several classes including AuthCheckMiddleware. Then your original code would have worked (although it's still not a good idea to use import *).

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • thanks Daniel, I can now import the class. Tips appreciated. I now have another problem, `TypeError: __init__() missing 1 required positional argument: 'get_response`. I'm using the new MIDDLEWARE setting in settings.py I copied the class structure from the Django Doc `class AuthCheckMiddleware(object): def __init__(self, get_response): self.get_response = get_response` – Dan Walters Oct 22 '18 at 10:55
  • 1
    Can you explain why you don't use one of the [existing auth decorators](https://docs.djangoproject.com/en/2.1/topics/auth/default/#limiting-access-to-logged-in-users) like `login_required` or `user_passes_test`? – Daniel Roseman Oct 22 '18 at 11:23
  • I didn't use `login_required` because I didnt want all sso users to be able to access some pages. But user_passes_test sounds like it could potentially solve my problem without using middleware. I'll just have to call it on every view i want to restrict. thx – Dan Walters Oct 22 '18 at 12:30
  • Daniel Roseman, you answer helps me to find another problem, I coulnd't import middleware, cause I was using pytz in there. – Sergo Aug 07 '22 at 06:56