We all had visited many websites where we can’t view some media or pdf files without logging in. So how do they restrict it? how do they validate the file? how do they secure the media files in Django?. So all this we will learn here, yes you are reading it correctly it is possible in Django to secure your media. We will be using the login required decorator, File Response, File Extension Validator, and get_object_or_404 objects in our project. Let’s Understand the meaning of each term stated above.
File Response
FileResponse accepts any file-like object with binary content, the file will be closed automatically, so there is no need to open it with a context manager.
Get_object_or_404
Get_object_or_404 is used to raise http404 error.

FileExtensionValidator
FileExtensionValidator raises an error if the file extension is not the same as provided.
Login Required Decorator
login_required() decorator does the following things:-
- Execute normally the view if the user is logged in.
- Redirect the user to the login_url path if the user is not logged in.
Django REST Framework is a robust and flexible toolkit for building Web APIs. Django provides the user to work at their ease. So let’s get started with this beautiful framework and understand the step-by-step procedure about how to secure media files in Django.
Step 1. Create Django Project
We are first going to create a Django project, an app inside that project by following the below steps:-
- Create a Django project by running the given command in the cmd or terminal.
django admin startproject bloglogindecorator
- Create app in that django-project.
python manage.py startapp logindecorator
- Add your app name in installed apps.
Settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'logindecorator' ]
Step 2. Add files and Folder to the Django Project
We need to create a template folder in the Django folder and a urls.py file in the app folder. In addition to this, we also need to create a media room so that we can provide a path to the uploaded media files in our project
- Create a new folder in the Django folder(here, bloglogindecorator) save it with the name template.
- Add the path for this template folder in bloglogindecorator> settings.py.
Settings.py
import os TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR,'template')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
3. Create a new file in the app folder(here, login decorator) save it with the name urls.py.
4. Add the path for this url.py file in bloglogindecorator > urls.py.
Urls.py
from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('',include('logindecorator.urls')) ]
5. Provide a new folder where you are going to store all media files uploaded by the user or uploaded to the database, by adding the following command in the respective files.
Settings.py
STATIC_URL = '/static/' MEDIA_URL='/media/' MEDIA_ROOT=os.path.join(BASE_DIR,'media/')
Urls.py
from django.contrib import admin from django.urls import path,include from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('',include('logindecorator.urls')) ] urlpatterns+=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Step 3. Secure media
We are first going to add our database to our project. In settings.py add the below code according to your database in DATABASES.
- Add database
Settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'bloglogindecorator', 'USER': 'postgres', 'PASSWORD':"2320", 'HOST': 'localhost' } }
2. Create a model in-app folder > models.py with the fields of your choice, here I had used FileExtensionValidator which helps me to collect only those files which have .pdf extension.
Models.py
from django.db import models from django.core.validators import FileExtensionValidator # Create your models here. class mediafiles(models.Model): title=models.CharField(max_length=50) pdf=models.FileField(upload_to='path/',validators=[FileExtensionValidator(['pdf'])])
3. Migrate the Model by, running the below code to migrate your model into your database.
python manage.py makemigrations python manage.py migrate
4. Add function in app folder >views.py
Get_object_or_404 is used to raise http404 error.
FileResponse accepts any file-like object with binary content, the file will be closed automatically, so there is no need to open it with a context manager.
Here the function blogsecuremodel is just to render the HTML page and provide model content on the HTML page.
The function secure will first check whether the person is authorized or not with the help of a login decorator and if the person is authorized it will just open the pdf file otherwise it will give an http404 error to the user.
Views.py
#from django.http.response import FileResponse from django.shortcuts import get_object_or_404, render from .models import mediafiles from django.http import FileResponse from django.contrib.auth.decorators import login_required import os def blogsecuremodel(request): object=mediafiles.objects.all() return render(request,'blogsecuremedia.html',{'object':object}) @login_required def secure(request,file): document=get_object_or_404(mediafiles,path="path/"+file) path,file_name=os.path.split(file) response=FileResponse(document.pdf) return response
5. Create Url path for the function in logindecorator(your_app_name)>urls.py.
Urls.py
from django.urls import path from . import views urlpatterns = [ path('blogsecuremodel',views.blogsecuremodel,name="blogsecuremodel"), path('media/path/<str:file>',views.secure,name="secure") ]
6. Create an HTML file here, there is an anchor (<a>) tag that passes the URL of the pdf file, so that when a user clicks this link he will be redirected to the secure function in views.py.
Blogsecuremodel.html
<html> <head> <title>BlogSecureMedia</title> </head> <body> <h1>Blog Secure Model</h1> {% for i in object %} <h1>Title:</h1> <p>{{object.title}}</p><br> <h1>pdf file:</h1><button><a href="{{i.pdf.url}}">Click to view</a></button><br> {% endfor %} </body> </html>
Output :-


Quick Revision:-
- Create your Django project folder.
- Create an app folder in the Django project folder.
- Add template folder in the Django folder and provide its path in django_folder > settings.py .
- Add a file named urls.py in the app folder and provide its path in django_project > urls.py.
- Provide a media folder path
- Add the function in app_folder > views.py.
- Provide the URL path in app> urls.py to the functions created in views.py.
- Add restriction to pages in html code in django_project > template > blogsecuremodel.html.
Conclusion:-
Hope you find this blog useful and able to understand each and every step. I hope I am able to clear all your doubts. Best of luck and Thank You.