2

I'm attempting to create Django middleware that modifies the request object by adding additional data. I want to package this middleware so that it only requires the following steps for setup:

  1. Install via PIP
  2. Add route to MIDDLEWARE in settings.py.
  3. Read custom user settings from some config file.

I've been searching for ways to do this but have not found any. There are guides for creating middleware packages, but not for properly packaging them for distribution. So I have the following questions.

  1. Is it possible to install middleware via PIP?
  2. If this is possible, is there a good cookiecutter-like example to base it off of? I tried (https://github.com/pydanny/cookiecutter-djangopackage), but this assumes the package is a stand-alone app, which seems like overkill for a package that consists of a single class.
  3. What's the best way to allow a user to customize the behavior of the middleware object? Ideally, I'd like the user to pass in a callable with the custom behavior, but I'm not sure where a user can define custom settings/functionality that gets passed into the middleware upon instantiation.

Thanks in advance.

jtimmins
  • 367
  • 3
  • 13
  • 1
    Why "some config file"? You can add your customs settings to `settings.py` and use Django's own configuration machinery to read them – yorodm Aug 30 '18 at 19:05
  • Just a few examples: https://pypi.org/search/?q=Django+middleware – phd Aug 30 '18 at 20:07

1 Answers1

1

Of course it's possible to install middleware via pip. A middleware class is just that - a standard Python class - and it can be located anywhere at all as long as it's on the Python path, which an installed library would be.

You don't need any kind of cookiecutter here; that's for apps and projects.

The best place to put settings is in the standard project settings file, where they can be read like any other settings from django.conf.settings.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Ah ok, I think I assumed more 'magic' was involved than there really is. If I want the user to define custom functionality with a callable, I assume they shouldn't actually write functioning code in the settings.py file. How would you handle having the user define that function and then referencing it via the settings.py file? – jtimmins Aug 30 '18 at 19:16
  • Can you give an example of the "callable"? – Daniel Roseman Aug 30 '18 at 19:23
  • Basically, I only want to modify certain requests. There will be a default `filter` method that determines which requests to modify, and I want to allow the user to pass in their own method that gets called instead to customize what gets filtered. Just something that returns True if it should be modified, and False if it shouldn’t. – jtimmins Aug 30 '18 at 19:33
  • I'm doing this. I don't need a callable, but I've added an attribute to the request object for users to update when they want stuff. I was also planning for the middleware to look in settings for certain configuration values that would otherwise default. I was king of looking for something explicit, where the user can explicitly configure the middleware, perhaps by a call, so of course you could make a call available in the middleware for the user to set configuration but that's what `settings` is for I suppose, so I'd use that. – NeilG Jun 09 '22 at 23:38