Models
We're playing the role of a cheese enthusiast
who wants to build a site to:
We created three views + templates:
Remember this?
The class is not the thing. It's a blueprint for making the thing.
Or making many things.
A class is a blueprint for mapping a database table
to a Python object.
It's a bidirectional mapping:
A database consists of tables
SELECT slug, last_updated, description
FROM catalog_cheese
WHERE fat_content >= 20
AND country_of_origin IN ('France', 'Italy')
How do we tell a model class how
to map to a database table's columns?
We define columns as properties of
the class of the Field
type.
from django.db import models
class Cheese(models.Model):
name = models.CharField(max_length=200)
country_of_origin = models.CharField(max_length=200)
fat_content = models.FloatField()
last_updated = models.DateField()
Django has many field types:
Field Subclass | Database Type | Python Type |
---|---|---|
BooleanField | boolean | bool() |
CharField | text | str() |
DateField | date | datetime.date() |
FloatField | float | float() |
IntegerField | integer | int() |
Python Concept | Database Concept |
---|---|
class | table |
property (if Field ) | column |
instance | row |
from django.db import models
class Cheese(models.Model):
name = models.CharField(max_length=200)
country_of_origin = models.CharField(max_length=200)
fat_content = models.FloatField()
last_updated = models.DateField()
class Cheese(models.Model):
name = models.CharField(max_length=200)
country_of_origin = models.CharField(max_length=200)
fat_content = models.FloatField()
last_updated = models.DateField()
↑ Notice the model doesn't have an "id" column
but the database does ↓
id = models.AutoField(primary_key=True)
primary_key=True
on a column of your model if you want to supply your own primary key.
from django.db import models
class Cheese(models.Model):
slug = models.SlugField(primary_key=True, max_length=200)
name = models.CharField(unique=True, max_length=200)
country_of_origin = models.CharField(max_length=200)
fat_content = models.FloatField(null=True)
last_updated = models.DateField(auto_now=True)
from django.db import models
class Cheese(models.Model):
slug = models.SlugField(primary_key=True, max_length=200)
name = models.CharField(unique=True, max_length=200)
country_of_origin = models.CharField(max_length=200)
fat_content = models.FloatField(null=True)
last_updated = models.DateField(auto_now=True)
def __str__(self):
return self.name
def is_high_fat(self):
if self.fat_content is None:
return False
return self.fat_content >= 0.5
# Get a list of every cheese in the table.
Cheese.objects.all()
# Get a specific cheese
Cheese.objects.get(slug="brie")
# Get a cheese that may or may not exist
try:
cheese = Cheese.objects.get(slug="apple")
except Cheese.DoesNotExist:
cheese = None
try:
result = numerator / denominator
except ZeroDivisionError:
print("Cannot divide by zero.")
try:
with open("nonexistent_file.txt", "r") as fh:
content = fh.read()
except FileNotFoundError:
content = None
# Get a cheese that may or may not exist
try:
cheese = Cheese.objects.get(slug="apple")
except Cheese.DoesNotExist:
cheese = None
# Same thing, but makes 2 DB queries
cheese_exists = Cheese.objects.filter(slug="apple").exists()
if cheese_exists:
cheese = Cheese.objects.get(slug="apple")
else:
cheese = None
.filter()
__lt
, __gt
, __lte
, __gte
, which are <, >, <= and >=__in
: is the column value in a list?__startswith
/__istartswith
: Does a column value start with a string?__range
: is a value between a start and end value?
# From cheeses from a list of countries
Cheese.objects.filter(
country_of_origin__in=["France", "Greece", "Italy"]
)
# Cheeses whose name starts with "Brie"
Cheese.objects.filter(name__startswith="Brie")
# High-fat cheeses that are not from France.
Cheese.objects
.filter(fat_content__gte=0.5)
.exclude(country_of_origin="France")
Meta
Meta
Example
from django.db import models
class Cheese(models.Model):
slug = models.SlugField(primary_key=True, max_length=200)
name = models.CharField(unique=True, max_length=200)
country_of_origin = models.CharField(max_length=200)
fat_content = models.FloatField(null=True)
last_updated = models.DateField(auto_now=True)
class Meta
ordering = ["name"]
get_latest_by = "last_updated"
Meta
Usage
# Will be alphabetically ordered by the cheese name.
Cheese.objects.all()
# The cheese with the most
# recent "last_updated" date.
Cheese.objects.latest()
# The cheese with the
# earliest "last_updated" date.
Cheese.objects.earliest()