An overview of the Django Web Framework

Django is a python web framework. A way to make amazing websites. It allows for a fast, but also safe development process. I find it a joy to work with. This website was written in Django, it took me a long time to make but that's because it was my first project. I gained a lot of knowledge that I can easily apply to other projects I might make.

I'm going to go over the very basics of making a Django website. Hopefully it will show you just how easy Django is to use, or maybe it will put you off; oh well.

Django is a MVT framework: Model, View, Template1.

Django also handles URL routing(and so many more things that are out of scope for this post).

Basic flow of a request

An example of the complete flow of a Request to Django goes something like this:

This example request will be for my blog index page which is at the following url https://mark.mcnally.je/blog/

  1. Django sees the "/blog/" part of this messages.

  2. It finds what view to route this message to

  3. The view code runs, and returns a http response, it will also tell Django what template (if any) to display. It can provide variables to this template.

Inside the view code you can basically write any python code you want, including the usage of Djangos ORM for querying the database. So for the "/blog/" request I run an ORM query that asks the database for a list of posts in reverse date order. Then that list of posts gets passed to the template as an array. You can then loop over this. I get the posts name, and then wrap it in html to make it a link. I then find the authors name of that post and wrap that in a link as well.

One more thing before we can see some actual code is that Django has the concept of "apps" 1 Django project can have many apps. This website only has 1 custom app which is the "blog" app. However, I can easily take the blog app out of this Django project and install it in a new Django project. A lot of addons that you might use in Django are in the form of apps, for example on this website I use an addon to give me a proper markdown editor(django-pagedown if you wanted to know)

Examples

Models

Before showing you the flow of a message in examples it's important to understand how Django reads and writes data.

Django uses the models framework to do this. Advantages of this method instead of using raw sql are:

The below example model is for a generic blog post. Every time you create a new blog post a new instance of this model is created. When you first start a Django application, the ORM will take the below model and turn it into an database table.

class Post(models.Model):
    title = models.CharField(max_length=150, unique=True)
    text = models.TextField()
    published_date = models.DateTimeField(default=timezone.now)
    last_modified = models.DateTimeField(auto_now=True)

This model is pretty easy to understand, Django provides many different types of fields that you can use. These are similar to ones that you might use when writing SQL to create a table in a database.

Urls

A viewer visits a post on this site, for example mark.mcnally.je/blog/post/my-post the url conf below picks this up. Blog is its own separate app so it has its own urls file.

# urls.py

path('blog/', include('blog.urls')),

Here comes the clever part. The url is structured like "/blog/post/name-of-post"

Django looks for /post/a-string inside the blog application. The below url will pick that up.

# blog/urls.py
app_name = 'blog'

path('post/<str:post>', views.post, name='post'),

The <str:post> part of this url means "assign whatever string appears after "/blog/post/" to the variable named post. views.post means send this request to the view named post.

Views

Here is our post view that the above url config sent the request and the variable named post to.

Remember a view takes a http request and returns a http response.

# blog/views.py
def post(request, post):
 post_to_display = get_object_or_404(Post, title=post)
 if not post_to_display.is_post_published():
        raise Http404("This blog post does not exist")

    context = {'post': post_to_display}

    return render(request, 'blog/post.html', context)

The above code does the following:

The get_object_or_404(Post, title=post) line is key. This method will try and find the field in the "Post" model (which is basically just a database table) with the title of whatever is in the post variable. If it does not find this field then it will 404.

Templates

Templates are the frontend. Basically, they are html pages with special template tags that Django will dynamically fill in for you

I think the template system is great, you can do all sorts of fancy stuff with it but these examples are just showing you basic functionality.

Remember that in the above view we called this template blog/post.html and we also passed it some context - the blog post that we wish to display.

<!-- blog/post.html !-->
<h1> {{ post.title }} </h1>

The above will display whatever the title of our post is! You can display variables in Django templates by wrapping them in "{{ }}": {{ Something_Dynamic }}

Another example, is displaying the actual post text (the very text you are reading right now was rendered using this method)

{{ post.text|markdown }} 

The above gets the post text and runs it through the "markdown" filter. Markdown is the markup language that I use to write posts in. You can create custom filters to do whatever you want to the text. The markdown filter converts markdown to html so it can be displayed by a web browser.

Besides displaying and filtering, you can also write conditional statements.

{% if post.has_post_been_modified %}

    <p><i><sub>Last modified on {{ post.last_modified }}</sub></i></p>

{% endif %}

The above uses an if statement to display the modified date if the post has been modified (post.has_post_been_modified is a method of the post model) . This example is simple, but this can be used for other things like displaying certain things to a user if they are logged in or not.

Lastly, templates can extend on another. I have a template named base.html that contains the nav bar and other things that I want in every page. To use that on another template I would write the following:

{% extends "blog/base.html" %}

That ends the very brief overview of Django. There is so much that I have not talked about but the above is hopefully a good example of Django's core functions.

If you like what you see then go learn Django! Follow the official tutorial then make something! Maybe you could make a blog like I did!

I do intend to write a post to help people bridge the gap between following the tutorial and building a Django application. You can of course figure this out yourself but I hope what I intend to write will be helpful anyway.

If you need some help feel free to reach out to me by email. (mark AT mcnally DOT je)


  1. Most other webframeworks are MVC frameworks, I have not used one of those before so I am in no right place to explain it, but as far as I know Django seems to be the only MVT framework, or at least it's the only one that calls itself that. 


Last modified on Oct. 2, 2020, 9:55 a.m.

Published on Oct. 1, 2020, 7 p.m.