Reputation: 1304
I have a Django project with multiple applications (say, two), and both need different versions of MEDIA_ROOT and MEDIA_URL.
The documentation does specify how to modify a specific setting, but here is what I did.
I created a project1/settings.py,
# project1/settings.py,
from django.conf import settings
settings.MEDIA_URL = 'foo'
settings.MEDIA_ROOT = 'bar'
Then I modified the init module of that application to only load the module:
# project1/__init__.py
import settings
It works! The specialized settings file happily overwrites the global one, selectively. What I like about this is that the project settings file is in a logical location.
My question is - does this approach have any caveats, and what is the best practices way to achieve this?
Upvotes: 1
Views: 4516
Reputation: 12803
Jarret is right. Best case scenario: this will work if you run a very simple test after restarting the server. Just about anything else will break it.
If you're just using MEDIA_* as constants, I'd recommend using some other constant. If you really are using them for default upload settings for file fields, it sounds like your project is going to require you to specify the path. That shouldn't be too hard.
There are two problems you need to overcome that your current scheme doesn't address:
1 is best accomplished through custom MiddleWare, probably with a process_request method. What you want to avoid, however, is the
settings.MEDIA_URL = 'foo'
global variable abuse. That will bring up problem 2. Since process_request lets you pass around an HttpRequest object, I recommend putting the variable information there:
class MyMiddleWare:
def process_request(self,request):
media_root = #some logic to parse request.path
request.media_root = media_root
Your static links will then have to make refer to request.media_root.
Upvotes: 4
Reputation: 98022
I'm a bit confused by how this is supposed to work. How will you use the settings in each application's code?
# project1/view.py
import settings
print settings.MEDIA_URL
or
# project1/view.py
from django.conf import settings
print settings.MEDIA_URL
In first case, that probably won't work since the settings you're importing is project1.settings, which itself has no MEDIA_URL
attribute.
In the second case, won't you end up with a race condition? Whichever application was loaded last will have last overwritten the attribute in the global settings
object. This may work in some cases where you are just running locally and you start the server, then go immediately to a view in one or other of the applications, but in a long running server like Apache which keeps several child processes bootstrapped and running, re-using them from request-to-request, the values in your settings will be unpredictable. Remember that the code in your init will be processed only when it is imported for the first time... subsequent imports do not cause the code to re-run.
Maybe I'm missing something in your description.
If you have application-specific settings, you'll need to have your own app-specific settings and code your logic to use them as appropriate.
Upvotes: 2