In our last tutorial we covered setting up a basic Django project. By now you should have a directory that looks like this:
0to100├── CHANGELOG.rst├── .gitignore├── .git│ └── HEAD│ ...├── README.rst├── docs├── requirements│ └── base.txt├── setup.py└── tutorial├── manage.py└── tutorial├── __init__.py├── settings.py├── urls.py└── wsgi.py
4 directories, 9 files
The Django Project’s tutorial goes over creating your first app pretty well, but they skip out on a few important concepts. Instead of explaining everything along the way the tutorial, a lot is skipped for the purposes of being concise and quick. Before we start building an app, what exactly is an app?
The first thing to understand is what exactly an app is. Unlike most MVC (or MTV) frameworks, Django forces you to break your code into separate “apps.” These apps should be totally self-contained, reusable, and plug-able. This is incredibly helpful because it means you can share functionality across multiple projects.
For instance suppose you have a blog app and a photo gallery app. Now a common piece of functionality you might want to add to both of those is the ability to add “tags” to photos and blog posts. Now you could write that functionality into both apps and end up having a bunch of duplicate code that does the exact same thing. Django’s preferred method is to add a new app called “tags.” This app would contain all of the data and logic concerned with adding, removing, and editing tags from other apps.
This ability to be self contained also means you can share your code with others and they can also use it. For instance if you didn’t want to write your own tagging library you could just run pip install taggit
and now you have a self contained tagging library that someone else wrote. Because of the way taggit was written it can be use with any other apps.
This is probably the single biggest question new Django developers face. How do you know when certain functionality should be split up. Due to the nature of programming there isn’t a hard rule on this. The idea I ususally follow is: “If you can’t explain what your app does in one sentence, it should be more than one app” and so far that has served me pretty well.
So enough prose and theory, let’s actually write some code! To start an app in Django, make sure you are in the first “tutorial” folder. I will refer to this as your ‘django project folder’ from here on (the one with manage.py
). This folder will be where all of your apps live. Now run:
$ python manage.py startapp polls$ ls
Now as you can see we now have new folder called polls
. While it may seem like startapp does some kind of magical thing to create this app, it actually doesn’t. All that happens is a folder is created with the name provided (i.e. polls), a few files are copied in, and one config file is added (apps.py). In fact you could create your own app in the terminal or in your file explorer just by creating 1 folder and 2 files. All that is required for an app folder is the folder, an __init__.py
, and an apps.py
.
So what does startapp
actually create? Let’s take a look and breakdown every file:
$ tree pollspolls├── admin.py├── apps.py├── __init__.py├── migrations│ └── __init__.py├── models.py├── tests.py└── views.py
First there is the admin.py file. This file is where you generally put all of your configuration regarding Djangos builtin admin.
Next is apps.py, this file is used in Djangos internal app registery and is mainly used to store meta data. For the most part you won’t be modifying this much.
Then we have the __init__.py file. This file is actually Pythons convention for determining modules. When you try to run import library
or from library import x
Python will search all folders in the Python Path. If a folder has an __init__.py file, Python will also search inside of that folder, otherwise it is ignored. So if we want to be able to import code from our polls
app we need __init__.py.
Now we have the migrations folder. Migrations are how Django builds your database. We will get into this later, but you will see “migrations” added to this folder as we start working with models.
Then we have the models.py this file is where you should store all of your models related to this app. Models are how Django understands your database and how you want data stored.
Next we have tests.py. Sometimes you will see this as a tests folder instead. This file/folder is for adding unit and integration tests. This is something we will cover in much greater detail later on, but basically a test is code you write to make sure your code is running how you expected.
Finally we have views.py. This is the file where all of our business logic is stored. We will define all of our views related to this app, both Class-Based and Function, in this file. In other frameworks, you would probably call Djangos views “Controllers”.
If you’ve worked with Django or other MVC frameworks before you may notice something is missing. There isn’t anywhere to store static files or templates (views in other frameworks). By default startapp
doesn’t create these, but you can by running:
$ mkdir static templates$ lsadmin.py apps.py __init__.py migrations models.py static templates tests.py views.py
That works perfectly fine and now Django will automatically start looking for static files in polls/static
and looking for templates in polls/templates
.
You can also add more files just for the sake of organization too! I’ll review a few other files that are relatively common:
Additionally a lot of third-apps use separate files similar to api.py to store configuration on a per app basis.
So now you’ve created an app, you know what everything does, but Django still does not know about your app! To make Django aware of your app you need to edit the tutorial/settings.py
file. Once you have it open search for INSTALLED_APPS
, you should see a section that looks like this:
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',]
This is a list of all of the apps that Django will use when you start up. To make Django aware of your amazing new polls app, just add 'polls',
to the end of the list:
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','polls',]
That’s it. You have officially created a brand new app and made it compatible with Django! It doesn’t do a whole lot yet, but we will start to fix that in the next tutorial.