Django web applications access and manage data through Python objects referred to as models. Models define the structure of stored data, including the field types and possibly also their maximum size, default values, selection list options, help text for documentation, label text for forms, etc.
Always think about what data we need to store in the models.
Think of what information you'd store about books: (title, summary, author, written language, category, ISBN) and if you have multiple copies of that book: globally unique id, availability status, etc.
You might also want to use models to represent selection-list options (e.g. like a drop down list of choices), rather than hard coding the choices into the website itself — this is recommended when all the options aren't known up front or may change.
Define the relationships, Django allows you to define relationships that are one to one (OneToOneField), one to many (ForeignKey) and many to many (ManyToManyField).
Some things to notice, in the BookInstance it does have a status feild showing if the book is available.
Models are usually stored in the models.py file here is a typical model:
from django.db import models
class MyModelName(models.Model):
"""A typical class defining a model, derived from the Model class."""
# Fields
my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')
...
# Metadata
class Meta:
ordering = ['-my_field_name']
# Methods
def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName."""
return reverse('model-detail-view', args=[str(self.id)])
def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.)."""
return self.my_field_name
Models have fields, and can have any amount of fields of any type. Each will represent a column of data we want to store in our database.
Some common field types:
- CharField
- TextField,
- IntegerField
- DateField
- EmailField
- FileField
- AuotField
- ForeignField
- ManyToManyField
What is model-level metadata?
One of the most useful features of this metadata is to control the default ordering of records returned when you query the model type.
class Meta:
ordering = ['title', '-pubdate']
With the above meta class used on a books database it would order by title (A to Z) and published date (Newest to oldest).
You can create and modify records as you go by storing the model in a variable and using .save() on that variable.
Much like SQL you can search the records with methods like, .all() to get all objects, filter() and sepecify if the object contains a certain thing.
from django.db import models
from django.urls import reverse # Used to generate URLs by reversing the URL patterns
class Book(models.Model):
"""Model representing a book (but not a specific copy of a book)."""
title = models.CharField(max_length=200)
# Foreign Key used because book can only have one author, but authors can have multiple books
# Author as a string rather than object because it hasn't been declared yet in the file
author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book')
isbn = models.CharField('ISBN', max_length=13, unique=True,
help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>')
# ManyToManyField used because genre can contain many books. Books can cover many genres.
# Genre class has already been defined so we can specify the object above.
genre = models.ManyToManyField(Genre, help_text='Select a genre for this book')
def __str__(self):
"""String for representing the Model object."""
return self.title
def get_absolute_url(self):
"""Returns the url to access a detail record for this book."""
return reverse('book-detail', args=[str(self.id)])
class Genre(models.Model):
"""Model representing a book genre."""
name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
def __str__(self):
"""String for representing the Model object."""
return self.name
class Author(models.Model):
"""Model representing an author."""
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField('Died', null=True, blank=True)
class Meta:
ordering = ['last_name', 'first_name']
def get_absolute_url(self):
"""Returns the url to access a particular author instance."""
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
"""String for representing the Model object."""
return f'{self.last_name}, {self.first_name}'
We have now created a Book, Genre and Author model for our book model.
python3 manage.py makemigrations
python3 manage.py migrate
By using the above commands you have now added the models to your database.
The Django admin application can use your models to automatically build a site area that you can use to create, view, update, and delete records.
Let's register the models,
Start by opening admin.py
from django.contrib import admin
from .models import Author, Genre, Book, BookInstance
admin.site.register(Book)
admin.site.register(Author)
admin.site.register(Genre)
admin.site.register(BookInstance)
We need to create a user account with Staff status enabled. To do this we must make a "superuser".
Within the same directory of manage.py:
python3 manage.py createsuperuser
Type in the username, email address, and strong password.
Next restart the dev server:
python3 manage.py createsuperuser
Now go to your site but add /admin/ after the url and you can get to the admin section.