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.
- The Model is basically your database
- The view is a function that takes a http request as input. Runs whatever python code you like and then returns a http response
- The Templates are what the user sees on the frontend, the view can populate these templates with variables. The view also chooses what template to display to the user.
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/
-
Django sees the "/blog/" part of this messages.
-
It finds what view to route this message to
-
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:
- It's database agnostic, for this project I used sqlite for development and postgresql for deployment. I did not have to change any code.
- You can use the ORM to query the database instead of direct SQL. This is generally quicker to write and, if like me you are not amazing at SQL it's probably better then you 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:
- Checks to see if a blog post named whatever was in the
post
variable exists - Checks if that post is published. If it is not it does not let the user see it
- If it passes that test then the user should be able to see that post. So it
loads the post into the
context
and passes that data into the"blog/post.html"
template.
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)
-
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. ↩