Exploring Django:  A Guide to the Python Web Framework

In the early 2000s, there were several web frameworks in the market which offered different features to developers like Zope (also written in Python), it offered a lot of freedom to developers by letting them customize the framework to tailor their needs, on the other hand frameworks like Ruby on Rails followed a more structured approach like default structure for database, web page and web services which let developers focus on their building core functionalities of their project.

Django aimed to make its mark by enhancing the features provided by other frameworks and build upon them in several key areas like emphasis on rapid programming and pragmatic design.

Key Features

Django has many features that allures web developers, for example:

Ease of Development

Django comes with a lot of built-in features out of the box, including things like user authentication, templating, database interaction, and an admin panel. Django follows the DRY (Don’t Repeat Yourself) principle which encourages code reusability and hence saves development time. Reusable apps also make development quick as they can be used in multiple projects and hence save time and effort for developers.

Versatility

Django applications can handle a small user base or grow to accommodate massive traffic. It can be used to build a variety of applications and excels at building robust APIs. While having a well-defined structure Django also leaves room for customizability so that developers can tailor the framework to their needs.

Ecosystem

The Python Package Index (PyPI) has over 10,000 Django specific packages. These pre-built address various functionalities and helps the developers in their process. Django also boosts a large and active community of developers which fosters a culture of innovation and experimentation, they constantly create new packages and tools to help other developers.

Security

Out of the box, Django provides numerous security measures to combat common web vulnerabilities:

  1. CSRF protection: Protects against Cross-Site Request Forgery attacks that trick users into performing unintended actions.
  2. Input validation and sanitization: Helps prevent SQL injection and other attacks by ensuring user-submitted data is handled securely.
  3. Secure password hashing: Django stores passwords securely using industry-standard hashing algorithms.
  4. HTTPS enforcement: Django can be configured to redirect all traffic to HTTPS, encrypting communication and protecting sensitive data.

File Structure

Whenever we create a new Django project using the command line, Django automatically creates several files and directories for us to use.

[projectname]/
|── [projectname]/
|      |── __init__.py
|      |── settings.py
|      |── urls.py
|      |── wsgi.py
|── manage.py

Django creates a directory for your project with manage.py and another directory inside with the same name and several important files like settings.py, urls.py and __init__.py which are used for tasks like database setting, URL configuration and application settings.

1. manage.py
It is a python script that is used for various tasks like running the development server, making database migrations, etc.
2. __init__.py
This file is empty and serves as an indicator that this directory should be treated as a python package.
3. settings.py
It contains essential configurations for our Django project, such as database settings, installed apps, and middleware.
4. urls.py
This files URL patterns of our project mapping URLs to views i.e., telling which view to serve at what URL.
5. wsgi.py
It defines the entry point for the WSGI (Web Server Gateway Interface) interface, which acts as a standard way for web servers and web applications to communicate in Python.

Basic Django Application

Below is a flowchart describing how a typical Django app works:

• Client is our end user who interacts with the web application through a web browser.
• URL Dispatcher is responsible for routing the HTTP Request from the client to the appropriate view function based on the URL patterns defined inside urls.py file.
• View functions are responsible for processing the request, fetching data from database and then populate the HTML templates with this data to be sent back to the client.
• Models.py file contains the definitions of Python classes that map to database tables. Each class represents a table in our database and each attribute represent a column of that table.
• Templates are dynamic HTML files used to render web pages which can include dynamic content populated by data from views.py

Now let’s see how a basic Django app works, in the below example we have created a project named ‘myproject’ and an app called ‘myapp’ which displays Posts for a forum stored in our database.

models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()

    def __str__(self):
        return self.title

In our models.py file, we have created a class called Post to represent post data in our database. This class inherits models from models. Model, making it a Django model class. It includes two fields:

title: a CharField with maximum length of 200 characters, used to store the title of the post.

content: a TextField that can store a variable amount of data, used for the post’s content.

These fields represent columns of a table called Post in our database.
We should also define a __str__ method in our model to show a string representation of the model instance, which is particularly useful for displaying readable names in the Django admin panel. In this case, it returns the post’s title.

urls.py

In urls.py file, we define the URL patterns for our Django app. We import path from django.urls to define these patterns, and we import views from the current directory to link URL patterns to view functions.

The url patterns list contains a single URL pattern:    

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('form/', views.form, name='form')
]

The first argument in the path function is an empty string (”), which matches the root URL (i.e., the homepage).
The second argument is views.home, which specifies that the home view function from the views module should be called when this URL is accessed.
The third argument is an optional name parameter, which assigns a name to this URL pattern. This name can be used to refer to this URL pattern elsewhere in the project, making URL management easier.
Similarly, we define a pattern for our form page.

Additionally, to ensure that requests to our app are properly routed, we must include this URL pattern in the project’s main urls.py file, typically located in the myproject directory. We use the include function to reference the app’s urls.py file:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',   include('myapp.urls'))
]

By default, Django sets up the admin panel accessible at the /admin/ path. This panel allows us to create, edit, and delete data for your application defined in models.py. (You need to register models defined to be made accessible in admin panel.)

views.py
from django.shortcuts import render, redirect
from .models import Post
def home(request):
    posts = Post.objects.all()
    context = {'posts':posts}
    return render(request,'myapp/index.html',context)

def form(req):
    if req.method == 'GET':
        return render(req,'myapp/form.html')
    if req.method == 'POST':
        title = req.POST['title']
        content = req.POST['content']
        Post.objects.create(title=title,content=content)
        return redirect('home')

In our views.py file we import Post from our models.py file and render function from django.shortcuts module to render HTML templates with data .

We have defined a function ‘home’ which accepts a request parameter (HTTPRequest Object) from the URL patterns defined earlier.

This function retrieves all the posts data saved in our database using the objects.all() method and creates a dictionary named context to pass data to our HTML file.

We return an HttpResponse object with the rendered HTML content by calling the render function which takes three arguments:

First argument is the request object used to gain access to information about the current HTTP request like session data. (Not required if no such need.)

Second argument specifies the path to the HTML template file to be rendered and processed with context data. These HTML files are to be stored in a templates folder in our app directory like so ‘/myapp/templates/myapp/index.html ’.

Third argument is used to pass data (context) from our view function to the HTML template for dynamic population which is a Python dictionary where keys represent variable names and values represent the data to be made available to the template.

We also define a form function which checks the type of HTTP Request received using method attribute of request object to render our form.html file if request is of type GET.

If the request of type POST we grab the title and content received from request object which we send via a form and then save that data to our database using objects.create() method on Post model and finally redirect user to home page using the redirect function.

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>Posts</h1>
    <ul>
      {% for post in posts %}
      <li>
        <h2>{{post.title}}</h2>
        <p>{{post.content}}</p>
      </li>
      {% endfor %}
    </ul>
  </body>
</html>

In our home.html template we loop through the context dictionary, using for loop, passed by the render function from our view and display each post in a list item. We use Django’s templating language to achieve this.

Form.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form action="{% url 'form' %}" method="POST">
      {% csrf_token %}
      <label for="title">Post Title</label>
      <input type="text" name="title" />
      <br /><br />
      <label for="content">Post content</label>
      <textarea name="content" id="content" rows="5" cols="50"></textarea>
      <br /><br />
      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

In our form.html template we define a form to send post’s title and content. The name attribute of these elements is used to access their values. Form’s action attribute is set to ‘form’ to send the request to form URL pattern defined earlier and the method is set to post. Django requires us to provide ‘{% csrf_token %}’ in any template that uses a POST form which provides additional security. (Note that CSRF token should not be provided if the target of the form is an external URL as this will leak the CSRF token)

Applications

Content Management System (CMS)

Django is a great choice for building CMS applications because of its inbuilt functionalities like authentication, authorization and admin interface for managing data. Also, Django’s ecosystem provides third party libraries that can extend the functionality of CMS applications like image galleries and social media integration.

Scalable Web Applications

Django’s caching mechanism helps in handling high traffic situations and improve performance. Asynchronous task handling also helps in maintaining performance by offloading tasks like processing files, sending emails to background workers. Django’s built in ORM (Object-Relational Mapping) and database migrations also make it a viable option for building highly scalable applications.

AI Web Applications

Python’s dominance in AI and ML domains is indisputable, with a rich ecosystem of libraries and frameworks like TensorFlow, Scikit-learn, NumPy and Pandas. Django being a Python framework makes integrations with these AI libraries seamless and along with the key features of Django discussed before makes it a solid choice for AI web applications.

Conclusion

Django has proven itself as a powerful and versatile framework for web development, particularly for building dynamic and feature-rich websites. Whether you’re a beginner or a seasoned developer, Django offers a robust foundation with clear conventions and a supportive community built around it .
If you’re ready to embark on your web development journey with Django, head over to their official website for all the resources you’ll need to get started.

By – Pulkit Khandelwal

Leave a Comment

Your email address will not be published.