Welcome to the updated web development in Python with the Django web framework tutorial series. In these tutorials, we will be covering everything you should need to get started and become familiar with the Django web framework. To do this, we're going to create a PythonProgramming.net-like website, which allows us to to cover topics like:
...and much more!
Django is a very "high-level" (handles many things for you) and fully-featured web frame-work aimed at allowing you to achieve rapid development while also preparing you from the start to create websites that will scale in time, both in terms of speed and code bloat as well.
A "web framework" is anything that provides some scaffolding to help you make a web application.
Before you begin
I suggest you are familiar with the Python 3 basics.
In this tutorial, I will be using Python 3.7 and Django 2.1.4. To get Django, you just do:
pip install django
Make sure you're pointing to pip for python 3. Throughout this tutorial, I am going to mainly be using the syntax that you'll find useful on Linux. For example, to reference Python 3 on Linux, you would say
python3. On Windows, you would instead do something like
py -3.7, which would reference Python 3.7 specifically. Eventually, you are almost certain to launch your website on a Linux server. For this reason, I am going to use the Linux syntax, but it's highly common to develop locally first, and you can use any operating system for this.
You may find that, if you're viewing this tutorial long after I have covered it, things have changed with Django. You can either check the comments section of the videos, or grab the same version of Django that I am using, by doing:
pip install django==2.1.4
I would only do that for learning purposes, however. You should always try to use the latest version since it will include important changes, like security fixes.
I will be using sublime-text 3 as my editor, but you can use whatever editor you want. You can also use whatever operating system you want. I have developed with Django on Windows, Mac, and Linux. They all work just fine.
Alright, assuming you have Django installed, let's get started! With your installation of Django, you should now have a command line keyword:
django-admin. You can use this to start a new
project. Django considers all websites to be a collection of apps. Consider a website that has a forum, a shop, and a blog. Each of those three things would be considered its own "app." A collection of these apps is your project. So, let's start a project. In your terminal/cmd.exe, do:
django-admin startproject mysite
You can call the
mysite bit whatever you want to call your project, but it seems to be a pretty consistent convention to call your project
mysite, so I will stick with that.
startproject command will create a new directory called whatever you called your project, In our case, that's called
Your project's directory is called
mysite and your primary app is also called
mysite. The only real role of this "primary app" as I am going to call it is to link your other apps. You shouldn't really be doing much in there besides managing settings and urls mostly.
Django is meant to be highly modular. When you develop an app like some forums for one website, you should be able to easily take your forum app to another website seemlessly and implement it nearly immediately.
Okay, so with this in mind, let's add our first actual app to our project. To do this, we will use
manage.py. This is a helper python script that will allow you to do things within your project. First, we'll use it to create another app. In your terminal/command line, navigate to the dir where this
manage.py file is, then do:
python3 manage.py startapp main
You should see that a new directory has been created called
main. So now the top levels of your project's structure are something like:
main -main (directory, your "primary" app) -mysite (directory, this is your new app) -manage.py (helper python script)
Okay great. Let's go ahead and run our server now. We will do this with
manage.py. You should probably open a separate terminal/command prompt to run the server within. We will keep the server running through much of the development.
To run the server, do:
python3 manage.py runserver
You should see something like:
python3 manage.py runserver Performing system checks... System check identified no issues (0 silenced). You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. January 10, 2019 - 18:50:09 Django version 2.1.5, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.
For now, we can ignore the migrations thing, we'll talk about that later on. We can see that our development server is now running at
http://127.0.0.1:8000. Open a browser and head to that address. You should see something like:
This is just the default "working" message that you will see if you're not handling for the home page yourself yet. Let's replace this with something of our own! I will leave the server running in a separate terminal from now on.
Django uses what's called a Model View Controller paradigm. Every page you visit on a Django application is likely using these three things to serve you data.
While we call it an MVC (model, view, controller), you can imagine it moreso working in reverse. A user will visit a URL, your controller (urls.py) will point to a specific view (views.py). That view can then (it doesn't actually HAVE to) interface with your models.
We can simplify this slightly, however, and just have the controller point to your view, and the view can jsut return a string, just so we can get a feel for how things connect.
When first starting out with something like Django, all these connections and things we need to do in order to do seemingly simple things can seem daunting, and like it's not worth it. With other frameworks, displaying some simple text can be done in moments, and doesn't require all this fiddling about. Where Django shines is not with simple websites. It shines when you've got a website that has grown in time, and you keep wanting to add features...etc, but then you've got a huge mess of code. Django helps you to keep things organized, and forces you to immediately follow good practices which will scale over time. This is annoying at first, but worth it long term. I like to share the following comic:
We always start projects with the best of intentions, but, we tend to have poor foresight. The best thing Django can do for you is the very thing that you may find annoying initially: Abstraction. Over time if you wanted to add more attributes to your users? It would be super simple with Django. Say you wanted to add more functionality like a more advanced nav bar? How about search bar? How about a full redesign? Through Django, this would all be trivial.
Okay, so let's display some simple text at the homepage. To do this, we don't need a model, but we do need the view (which will dictate the text we want to display) and the controller to point to the view, based on the URL. Because I think of things in the order of the user, I would first start with the controller. So we need to tell Django that homepage should return some view. Django begins in your "primary" app when looking for URLs. So first, let's go to:
from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
So we've only got one URL here, and that's apparently to some administration page, which isn't our focus right now. So, what we need to do is point this URL to a view. That said, Django sees websites as a collection of apps. So actually the
urls.py file inside your "primary" app is usually just going to point to your apps. How do we point to an app? We just point to that app's
urls.py file! So let's just add that:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path("", include('main.urls')), path('admin/', admin.site.urls), ]
Aside from adding the extra path, don't forget to also import "include" from
Okay, so now django knows that, when the path is basically empty (the homepage), to look inside of the
main app at its
urls.py file to see if that file (the controller) points to a
view, which would be some function inside of that app's
We have yet to modify our
urls.py file, and we also have not made any view. Let's do both! Let's navigate into our
mysite/main app. We can see that there are already various things here...but there's no
urls.py! Let's add that now:
from django.urls import path from . import views app_name = 'main' # here for namespacing of urls. urlpatterns = [ path("", views.homepage, name="homepage"), ]
We import path the same as before. We locally import our view. We specify the app name (this isn't required, but you might as well just get in the habit of doing it. Later it will become very useful when we want to dynamically reference URLs). Like I said, Django is highly modular, and even if you wanted to change URL paths, or use someone else's application, but maybe not the same URL paths, you can easily do it. This is also why we give a
name as a parameter of the
path. Okay, great! We've got the controller all set. When someone visits the homepage, Django looks first at the
mysite/mysite/urls.py, seeing that it points to
mysite/main/urls.py, which then points to views.homepage (so, a function called homepage inside of
views.py). Do we have that? Nope. Let's do it.
views.py does already exist here, however, so open that up to edit it. It should look like:
from django.shortcuts import render # Create your views here.
Normally, these views will render some HTML template and pass some variables, but we're just going to make it super simple and return a straight HTTP response. To do this, we need to import it:
from django.http import HttpResponse
urls.py to look for a
homepage function, so let's define that:
def homepage(request): return HttpResponse("pythonprogramming.net homepage! Wow so #amaze.")
Note that we pass
request. You will always pass this to your views.
views.py should now be:
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def homepage(request): return HttpResponse("pythonprogramming.net homepage! Wow so #amaze.")
Now, go back to your browser and refresh. If you fiddled at all up to this point, you probably hit an error, and you will need to re-run the server since you will have stopped on an error most likely. Now, at the homepage, you should see:
We'll stop here, and what I suggest you do is make sure you can do all of the above, without the use of a tutorial. So, start a fresh project, add an app, configure the url.py files to point the homepage to a view, and have that view return a simple string. Things will only become more complicated from here, so it's essential you understand these basics up to this point. If you're fuzzy on anything, I strongly advise you to ask questions or Google it until you're solid on everything up to this point.
As we progress, I would suggest that you continue doing this. At the end of each tutorial, save the project. Then at the next tutorial, make a copy of the project, follow the tutorial, then try to do it to the copy without needing to consult the tutorial. You might forget import paths or function names, that's fine. What you want to make sure is that you actually understand what connections need to be made.
Alternatively, you could also work on a side-project that isn't the same as what we're doing here. As you follow along here, apply it to your own project. The most important thing is that you don't gloss over some concept that you don't understand. Join us on Discord and ask for help in the #help channel if you can't figure something out.