What we want to create now is something that will store all the posts in our blog. But to be able to do that we need to talk a little bit about things called
There is a concept in programming called
object-oriented programming. The idea is that instead of writing everything as a boring sequence of programming instructions, we can model things and define how they interact with each other.
So what is an object? It is a collection of properties and actions. It sounds weird, but we will give you an example.
If we want to model a cat, we will create an object
Cat that has some properties such as
mood (like good, bad, or sleepy ;)), and
owner (which could be assigned a
Person object – or maybe, in case of a stray cat, this property could be empty).
Cat has some actions:
feed (in which case, we will give the cat some
CatFood, which could be a separate object with properties, like
Cat -------- color age mood owner purr() scratch() feed(cat_food)
CatFood -------- taste
So basically the idea is to describe real things in code with properties (called
object properties) and actions (called
How will we model blog posts then? We want to build a blog, right?
We need to answer the question: What is a blog post? What properties should it have?
Well, for sure our blog post needs some text with its content and a title, right? It would be also nice to know who wrote it – so we need an author. Finally, we want to know when the post was created and published.
Post -------- title text author created_date published_date
What kind of things could be done with a blog post? It would be nice to have some
method that publishes the post, right?
So we will need a
Since we already know what we want to achieve, let’s start modeling it in Django!
Knowing what an object is, we can create a Django model for our blog post.
A model in Django is a special kind of object – it is saved in the
database. A database is a collection of data. This is a place in which you will store information about users, your blog posts, etc. We will be using a SQLite database to store our data. This is the default Django database adapter – it’ll be enough for us right now.
You can think of a model in the database as a spreadsheet with columns (fields) and rows (data).
To keep everything tidy, we will create a separate application inside our project. It is very nice to have everything organized from the very beginning. To create an application we need to run the following command in the console (from
myblog directory where
manage.py file is):
(myvenv) ~/myblog$ python manage.py startapp blog
(myvenv) C:\Users\Name\myblog> python manage.py startapp blog
You will notice that a new
blog directory is created and it contains a number of files now. The directories and files in our project should look like this:
myblog ├── blog │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── db.sqlite3 ├── manage.py └── mysite ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
After creating an application, we also need to tell Django that it should use it. We do that in the file
mysite/settings.py. We need to find the
INSTALLED_APPS setting and add a line containing
'blog', just above the close of the list (
]). So the final product should look like this:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', ]
blog/models.py file we define all objects called
Models – this is a place in which we will define our blog post.
blog/models.py, remove everything from it, and write code like this:
from django.db import models from django.utils import timezone class Post(models.Model): author = models.ForeignKey('auth.User', on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField( default=timezone.now) published_date = models.DateTimeField( blank=True, null=True) def publish(self): self.published_date = timezone.now() self.save() def __str__(self): return self.title
Double-check that you use two underscore characters (
_) on each side of
str. This convention is used frequently in Python and sometimes we also call them “dunder” (short for “double-underscore”).
It looks scary, right? But don’t worry – we will explain what these lines mean!
All lines starting with
import are lines that add some bits from other files. So instead of copying and pasting the same things in every file, we can include some parts with
from ... import ....
class Post(models.Model): – this line defines our model (it is an
classis a special keyword that indicates that we are defining an Class.
Postis the name of our model. We can give it a different name (but we must avoid special characters and whitespace). Always start a class name with an uppercase letter.
models.Modelmeans that the Post is a Django Model, so Django knows that it should be saved in the database.
Now we define the properties we were talking about:
author. To do that we need to define the type of each field (Is it text? A number? A date? A relation to another object, like a User?)
models.CharField– this is how you define text with a limited number of characters.
models.TextField– this is for long text without a limit. Sounds ideal for blog post content, right?
models.DateTimeField– this is a date and time.
models.ForeignKey– this is a link to another model.
We will not explain every bit of code here since it would take too much time. You should take a look at Django’s documentation if you want to know more about Model fields and how to define things other than those described above (https://docs.djangoproject.com/en/2.0/ref/models/fields/#field-types).
For Django 1.11, use the following link instead: https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types).
def publish(self):? This is exactly the
publish method we were talking about before.
def means that this is a function/method and
publish is the name of the method. You can change the name of the method if you want. The naming rule is that we use lowercase and underscores instead of spaces. For example, a method that calculates average price could be called
return something. There is an example of that in the
__str__ method. In this scenario, when we call
__str__() we will get a text (string) with a Post title.
Also notice that both
def publish(self): and
def __str__(self): are indented inside our class. Because Python is sensitive to whitespace, we need to indent our methods inside the class. Otherwise, the methods won’t belong to the class, and you can get some unexpected behavior.
We know it is complicated, especially when you learn what objects and functions are at the same time. But hopefully it looks slightly less magic for you now!
The last step here is to add our new model to our database. First we have to make Django know that we have some changes in our model. (We have just created it!) Go to your console window and type
python manage.py makemigrations blog. It will look like this:
(myvenv) ~/myblog$ python manage.py makemigrations blog Migrations for 'blog': blog/migrations/0001_initial.py: - Create model Post
Note: Remember to save the files you edit. Otherwise, your computer will execute the previous version which might give you unexpected error messages.
Django prepared a migration file for us that we now have to apply to our database. Type
python manage.py migrate blog and the output should be as follows:
(myvenv) ~/myblog$ python manage.py migrate blog Operations to perform: Apply all migrations: blog Running migrations: Rendering model states... DONE Applying blog.0001_initial... OK
Hurray! Our Post model is now in our database! It would be nice to see it, right? Let’s do a few questions to check your understand and then we’ll jump to the next tutorial to see what your Post looks like!