Simple App From Scratch and Upload File with Django Framework

Tariqul Islam
11 min readJun 25, 2021

--

Django web framework is a repid web application development framework. I have been using this framework in different project since 2 years. So I will dicusss about way of uploading document, image to server through Django framework and build the site from scratch.

Prequeresite

  1. Python Version ≥ 3.6
  2. Django Framework
  3. Python venv library

Setup the python virtual environment and django framework

First create folder named “django_file_upload” and go to that folder and run the following command below to create virtual environment using “venv” in python version 3. venv is build-in library come with python version 3.

> python -m venv venv

Activate the virtual environment

In Windows need to ‘Administrator’ user permission to activate the virtual environment. For windows user should open the terminal with administrator access. In Terminal:

For Mac OS X
> source venv/bin/activate
For Windows
> venv\Scripts\activate

I am using the visual studio code for my development environment. You can use your feboruite IDE for development purpose. All you have to do to activate virtual environment for development purpose. I am opening the VSCode into Mac OS x.

Install Django

We need to use pip and requirment.txt file to install Django Latest framework. To order to do that, first create the requirment.txt files at the root of the application folder.

# requirement.txt 
# Django Latest version
Django==3.2.4

Run the following pip command will installed the django and django related package to that virtual environment.

> pip install -r requirement.txt

Create and Setup the application

Django has its own CLI to develop and maintain the application, we can use “django-admin” to generate the project and “manage.py” to manage the application. Following below command will create project named “django_file_upload_example”

> django-admin startproject django_file_upload_example

Go to “django_file_upload_example” folder and then run the following command to generate module name “product” for fileupload.

For Windows $ python manage.py startapp productMac OS X$./manage.py startapp product

Then create the forms.py and urls.py in product app directory

(1) Contains the upload and list form and code for file upload

(2) Contains the urls to navigate the upload and list view

(3) Models which contains database design and difination and upload file path configuration record.

(4) Control the view and connect through the template and views and models of the application to handle html template data

(5) Using for declare the urls or routes and connect throught modules urls for “product” module

(6) Application “Settings” files. Developer can declare modules and declare different configuration related to application such as media folder setting , template settings, database setting etc.

Create the model which is actully used for save the data into database

from django.db import modelsclass FileUpload(models.Model):
title = models.CharField(max_length=100)
doc_file = models.FileField(upload_to="documents/")
image_file = models.ImageField(upload_to="images/")

doc_file and image_file both field contains ‘upload_to’ attribute, which will used for image and other files saves into “media/<upload_to>” directory.

Create the form which is used to render the Form in template view

from django import forms
from django.forms import fields
from .models import FileUpload
class UploadForm(forms.ModelForm):
title = forms.CharField(max_length=100)
doc_file = forms.FileField()
image_file = forms.ImageField()

class Meta:
model = FileUpload
fields = ['title', 'doc_file', 'image_file']

I composit the “ModelForm”, which is a Django Built-In Form class to support model wise form design, Inner class “Meta” i have declare “model” and “fields” attributes otherwise “ModelForm” will no be working in application runtime.

In the Form class single field like “title” or “doc_file” will generate the input or file field into template in runtime of application. we can also define the “label” in every field. max_length does two things, It puts a maxlength="100" on the HTML <input> (so the browser should prevent the user from entering more than that number of characters in the first place). It also means that when Django receives the form back from the browser, it will validate the length of the data.

Configure the templates directory into django project

Create the “templates/product” folder in root of the application. add the “index.html” file, which contains upload form

In index.html file that files contains the following codes snippets

Django ships with an easy-to-use protection against Cross Site Request Forgeries. When submitting a form via POST with CSRF protection enabled you must use the csrf_token template tag as in the preceding example. However, since CSRF protection is not directly tied to forms in templates, this tag is omitted from the following examples in this document.

All the form’s fields and their attributes will be unpacked into HTML markup from that {{ form }} by Django’s template language.

There are other output options though for the <label>/<input> pairs:

  • {{ form.as_table }} will render them as table cells wrapped in <tr> tags
  • {{ form.as_p }} will render them wrapped in <p> tags
  • {{ form.as_ul }} will render them wrapped in <li> tags

Configure the Template folder

Then activate the template folder we to have specify in “settings.py”(1) “TEMPLATES” section in “DIRS” attribute. For this project it will be “templates” directory. so we can add BASE_DIR / ‘templates’ as value in “DIRS” Attributes(2).

Configure the Media directory to save the file to media directory

Then add the media folder at the root of the application, where we will stored the upload file in a application

Then we need to set or declare the MEDIA_URL (2)and MEDIA_ROOT (3)in project’s settings.py(1) file.

Also setup the context_processors in templates for media directory into settings.py (1) as “django.template.context_processors.media” (2) value.

The media context processor is enabled, now every RequestContext or view will contain a variable MEDIA_URL.

To access the Url into routes during browsing to client , we need to add “MEDIA_ROOT” into urlpatterns in “urls.py” file into “django_file_upload_exmple” project folder.

Now Browser will access the files in browser and any template URL like bellow example

<p><img src="{{ MEDIA_URL }}/image_001.jpeg"/></p>

Design the view for application

Create the View using “FileUploadForm”, which will use to integrated “html template” and “Form Class” of the application

(1) open the views.py file in “product” app folder

(2) Import all the dependency and class related to build the FileUploadView Form. We compose built-in form class named “FormView”. Import the product model and UploadForm Class.

(3) In line 8 to 10, adding the html template name where upload from will be render using UploadForm class.

Override the get function of “FormView” Django Class to render the Form in to browser or client. Add the form_class and pass through the render function, “django.shortcuts” ‘s “render” function takes “form request” and “html template name” and “form class as variable” which is then use into html template to render the form.

(4) Override the “FormView” “post” function, which used for handle the “post” request of the form and process the data and contains the files and post data information. We can use it to process the data and submit into database form this class.

In line 19…22 … process the input and file of post data, process and insert into “upload form class”.

In line 24… check the form data is valid or not by “is_valid” function of “Form” Django class, then in line 25 call the “UploadForm” save function to save the data database and upload files to media directory.

Then in line 27 render the same form after saving of posting the data.

Configure the Product app to “django_file_upload_example” main project.

(1) For Django you need to add the module or other app name into “INSTALLED_APPS”, into “setting.py” file other wise created module or app will not serve with Main project, database migration will not works. So we have to add “product” module into that setting.py file.

Database Cofiguration

(1) select on setting.py file

(2) we are using by default django configured “sqlite” database

We are using the defalt database and configuration which is generated by Django.

ENGINE contians the information about which database driver used for saving the information from django to database

For SQLite database “NAME” contains the directory path name of the database.

Database Migration

Run the following command below

In Mac OS X
> ./manage.py makemigrations
In windows > python manage.py makemigrations

The following error will be occured, It means Model.imagefile needs the packages named pillow, without it you will get that error after running the database migration command.

To solve this error just install the pillow package(1) into application by adding dependency into “requirement.txt”

Run the command “pip install -r requirement.txt”. it will add the package to application

Then run the command “python manage.py makemigrations” again. it will generate the “0001_initial.py” file into product project.

Automatically create the migration file (1) named 0001_initial.py. You can also create the migration manually, but for this example or article, you do not use manual migration.

(2) operation contains the defination and mapping of the database and model.

Configuring the Routing

Then in “product” app directory add following url route to “urls.py” file. If “urls.py” file is not exists into “product” app. just create it and then add the following route below.

(1) import the path library from “django.url” to serve the route or navigation of the application

(2) Import the “FileUplaodView” from product module “view” folder. (.) means this module using import other class and library from same module

(3) urlpatterns is default array variable, so django will search this array in application runtime for load the urls and url pattern inside it.

Path used for load the “route” or navigation of View class or View function.

1. First argument contains any “url or path or pattern” in string,2. Second argument used for declare the view and view function,3. Third one contains name name of the “route”,given name is the navigation of  specific route.

To sync and connect with main project urls or routes, you have to specify the apps or modules urls.py or routes files to main project url. so we have to add the urls to “django_file_upload_example” urls.py file.

(2) From “django.urls.conf” library add “include” , which will help the path function to add the “product” module “urls.py” Files route list into main application.

(3) Include the all routes from “product” app by calling the include function.

Then run the migration command command by followting below

For windows in virutal environment> python manage.py migrateFor Mac OS x virtual environment> ./manage.py migrate

(1) Django Authentication and session and setup related data migration for first time.

(2) Product model also migrated successfully

Then run following command to start the development server in local development environment

For Windows in virtual environment$ python manage.py runserver 0.0.0.0:8080For Mac OS x in virtual environment$ ./manage.py runserver 0.0.0.0:8080

Go to Product upload route in browser, you will get the following below windows in browser

Show The image in listview

Add the Template View class to views.py file in product/views.py app file

(1) Import the dependency and class which is needed for render the ListView and override the Generic list view class. Most of the library are datetime related and django ListView built-in Class.

(2) ListView need to have html template name, we will create the list view html template later in to application, to link through the ListView class need add into “template_name” properties.

model: This properties is to load the which model data we can show into list view.

paginate_by: using the pagination of model data, we will get every time 100 data by each pagination into list.

(3) 17….21, override the default function list view named “get_context_data” and add some additional time related field into result and using for render into list view.

Add the routes to urlpatterns into product/url.py file

(1) Import the FileListView Class from views files for product app directory.

(2) urlpattern used for create the route during application is running into server and serve into browser and clients

empty (“ ”) argument for path will server when any one want to access the product module in browser using that type of pattern below “http://localhost/products/”, We add the “FileListView” as view into, give the name of the navigation as “product_list” so we can access the routing url by that name into class and template.

Add the html template list into template directory product folder

(1) Create the list view html template file under “template/product” folder

(2) Run the django template for loop to render the list view the syntax will be

{% for <Object> in <List> %} # start the loop
....statement....
{% empty %} # check the list is empty or list length is 0 and enter into this block
.... empty statement ....
{% endfor %} # end for loop

To render the image into html

<img height="100px"
width="100px"
src="{{product.doc_file.url}}" />
# {{ }} are is called as template expression, you can declare the python variable inside the expression, i use to show the product image url by following "product.doct_file.url" python variable in it

Browser output for Product List view after Browsing into “http://localhost:8080/products/” urls

You can download full source code from below github repository

--

--

Tariqul Islam

Tariqul Islam have 9+ years of software development experience. He knows Python, Node Js and Java, C# , PHP.