11š
It seems to me that the method you outlined in your code should work. Itās really no different than any other protected resource: your views can serve files from disks, records from databases, rendered templates or anything. Just as the login_required decorator prevents unauthorized access to other views, it will prevent such access to your view serving protected media.
Am I missing something from your question here? Please clarify if thatās the case.
EDIT: With regard to the django doc link in your comment: thatās the method for simply serving any request file from a particular directory. So, in that example URLS like /site_media/foo.jpg
, /site_media/somefolder/bar.jpg
will automatically look for files foo.jpg
and somefolder/bar.jpg
under document_root
. Basically, every thing under document_root
will be publicly available. Thatās obviously insecure. So you avoid that with your method.
Itās also considered inefficient because django is just adding a lot of unnecessary overhead when all you need is something like Apache to take a URL request and map it to a file on the hard drive. (You donāt need django sessions, request processing, etc.)
In your case, this may not be such a big concern. First, youāve secured the view. Second, it depends on your usage patterns. How many requests do you anticipate for these files? Youāre only using django for authentication ā does that justify other overhead? If not, you can look into serving those files with Apache and using an authentication provider. For more on this, see the mod_wsgi
documentation:
- http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms
- see the section āApache Authentication Providerā and search for django
There are similar mechanisms available under mod_python
I believe. (Update: just noticed the other answer. Please see Andreās answer for the mod_python
method.)
EDIT 2: With regard to the code for serving a file, please see this snippet:
The send_file
method uses a FileWrapper which is good for sending large static files back (it doesnāt read the entire file into memory). You would need to change the content_type
depending on the type of file youāre sending (pdf, jpg, etc).
5š
Read this Django ticket for more info. Start at the bottom to save yourself some time. Looks like it just missed getting into Django 1.2, and I assume also isnāt in 1.3.
For Nginx, I found this Django snippet that takes advantage of the X-Accel-Redirect header, but havenāt tried it yet.
- [Django]-Cannot import name _uuid_generate_random in heroku django
- [Django]-Django import error ā No module named core.management
- [Django]-How to render HTML in string with Javascript?
3š
If I understand your question correctly you want to restrict access to files that are not being served by Django, for example, with an Apache server?
What you would then require is some way for this Apache server to use Django as an authentication source.
This django snippet describes such a method. It creates an access handler in Django which is used by Apache when a request for a static file comes in that needs to be protected:
<Location "/protected/location">
PythonPath "['/path/to/proj/'] + sys.path"
PythonOption DJANGO_SETTINGS_MODULE myproj.settings
PythonOption DjangoPermissionName '<permission.codename>'
PythonAccessHandler my_proj.modpython #this should point to accesshandler
SetHandler None
</Location>
Hope this helps, the snippet was posted a while ago, so things might have changed between Django versions š
- [Django]-Django ā Where are the params stored on a PUT/DELETE request?
- [Django]-Django.db.utils.ProgrammingError: relation already exists
- [Django]-How does it work, the naming convention for Django INSTALLED_APPS?
3š
More efficient serving of static files through Django is being looked at currently as part of Google SOC project. For WSGI this will use wsgi.file_wrapper extensions for WSGI if available, as it is for mod_wsgi, and req.sendfile() if using mod_python. It will also support returning of headers such as āLocationā, āX-Accel-Redirectā and others, which different web hosting mechanisms and proxy front ends accept as a means of serving up static files where location is defined by a backend web application, which isnāt as effecient as front end for serving static files.
I am not sure if there is a project page for this in Django wiki somewhere or not, but the code changes are being committed into the branches/soc2009/http-wsgi-improvements branch of Django source code repository.
You neednāt strictly wait for that stuff. It is just putting a clean and portable interface in place across the different mechanisms. If using nginx as front end in front of Apache/mod_wsgi, you could use X-Accel-Redirect now. If using Apache/mod_wsgi 3.0 and daemon mode, you could use Location now, but do need to ensure you set up Apache correct. Alternatively, you could implement your own WSGI middleware wrapper around the Django application which looks for some response header of your own to indicate file to be returned and which uses wsgi.file_wrapper to return that instead of actual response returned from Django.
BTW, the authentication hook mechanisms listed for both mod_python and mod_wsgi by others would use HTTP basic authentication, which isnāt what you wanted. This is presuming you want files to be protected by Django form based login mechanism using cookies and backend sessions.
- [Django]-Django: How to pre-populate FormView with dynamic (non-model) data?
- [Django]-Django switching, for a block of code, switch the language so translations are done in one language
- [Django]-Django model: NULLable field