Custom Middleware Issue with Mezzanine/Cartridge

138 views
Skip to first unread message

Aaron Wright

unread,
Dec 28, 2017, 11:45:01 AM12/28/17
to Mezzanine Users
Hello!
Thanks in advance for any help on this issue!  I'm attempting to build a Mezzanine/Cartridge site for a distillery that needs to verify their users age, and I believe middleware is the place to do it. I'm trying to write my own middleware and am running into several issues with the "old style" vs "new style" middleware, I believe the new middleware was introduced in django 1.10, which is what Mezzanine is currently using. 


Note* I had this working on a Mezzanine project just fine, but it seems to be having issues now that Cartridge is also installed. 


My middleware code: 

class VerifyAgeMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.
    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        cookie = request.COOKIES.get('age', None)
        if (request.path == '/verify-age/') or (request.path == '/admin/') or (request.path =='/admin/login/'):
            pass
        else:
            if (cookie):
                response = self.get_response(request)
                return response
            else:
                return redirect('/verify-age')

        response = self.get_response(request)
        # Code to be executed for each request/response after
        # the view is called.

        return response


With this code, I'm getting the error: "TypeError: __init__() missing 1 required positional argument: 'get_response'", but obviously get_response is in my init function above. 

I read elsewhere online, people suggested this is because of the switch to the "new style" of middleware, and in my settings.py file, I should change "MIDDLEWARE_CLASSES" to just "MIDDLEWARE". 

So, when I do that, I get this error: TypeError: __init__() takes 1 positional argument but 2 were given 

After some messing around, I removed my custom middleware and was still getting the error, and found out that this error wasn't referring to my own middleware, but it looks like it's having an issue with the "cartridge.shop.middleware.ShopMiddleware" middleware. 


So I tried switching to the function-based middleware from the django docs: https://docs.djangoproject.com/en/1.10/topics/http/middleware/

When I do that, I get this weird error that I can't find much about online: AttributeError: 'function' object has no attribute '__mro__' 

but seems like it's expecting a class-based middleware instead of a function. 



So what are my current options for writing a custom middleware within a Mezzanine/Cartridge site? 

Thanks again for any help! 





Aaron Wright

unread,
Dec 28, 2017, 3:08:35 PM12/28/17
to Mezzanine Users
Responding to my own post because I fixed the problem. Leaving this here in case someone wants to discuss how middleware is currently implemented in Mezzanine & Cartridge and/or in case it may help someone with the same issue in the future. 

I basically fixed this by copying how "cartridge.shop.middleware.ShopMiddleware" is implemented here: https://github.com/stephenmcd/cartridge/blob/master/cartridge/shop/middleware.py

Changed my code to: 


class VerifyAgeMiddleware(object):
    def __init__(self):
        pass
        # One-time configuration and initialization.
    def process_request(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        cookie = request.COOKIES.get('age', None)
        if (request.path == '/verify-age/') or (request.path == '/admin/') or (request.path =='/admin/login/'):
            pass
        else:
            if (cookie):
                pass
            else:
                return redirect('/verify-age')


I'm guessing this is the "old" way of implementing middleware in Django? If so, I'd love to take a shot at updating Cartridge's middleware to the "new" way that the Django docs suggest, if there is any interest in updating that stuff. 
Reply all
Reply to author
Forward
0 new messages