# Django Models
###### tags: `mobile-development` `backend`
When we say a model in django, it simply means a `table` in the database.
So to define our database tables in django, we simply create a `Model` for each table. Django models itself has tons of varietyand you should defeinitely check out their documentation at [This link first](https://docs.djangoproject.com/en/4.1/topics/db/models/) and then go to see the different types of fields in [Here](https://docs.djangoproject.com/en/4.1/ref/models/fields/#model-field-types).
We will be building a very simple (not perfectly designed to avoid difficulties for students with less experience) movies app, where people can see movies (or series) details, news, trailers and actors.
Here is the code for the models:
```python=
from django.core.validators import MinValueValidator
from django.db import models
import uuid
class Category(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Movie(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
title = models.CharField(max_length=150)
release_date = models.DateField(db_column='date')
description = models.TextField()
rating = models.DecimalField(max_digits=2, decimal_places=1)
is_for_adults = models.BooleanField(default=False)
trailer_url = models.URLField(null=True, blank=True)
is_featured = models.BooleanField(default=False)
length = models.CharField(max_length=6)
categories = models.ManyToManyField(Category, related_name='movies', blank=True)
image = models.URLField(null=True, blank=True)
thumbnail = models.URLField(null=True, editable=False)
def __str__(self):
return self.title
@property
def actors(self):
return self.actors.all()
class Serial(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
title = models.CharField(max_length=150)
release_date = models.DateField(db_column='date')
description = models.TextField()
rating = models.DecimalField(max_digits=2, decimal_places=1)
is_for_adults = models.BooleanField(default=False)
trailer_url = models.URLField(null=True, blank=True)
is_featured = models.BooleanField(default=False)
categories = models.ManyToManyField(Category, related_name='series')
image = models.URLField(null=True)
thumbnail = models.URLField(null=True, editable=False)
def __str__(self):
return self.title
@property
def actors(self):
return self.actors.all()
@property
def seasons(self):
return self.seasons.all()
class Season(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
number = models.PositiveIntegerField(
validators=[MinValueValidator(1, message='Minimum season for any series is 1')])
serial = models.ForeignKey(Serial, on_delete=models.CASCADE, related_name='seasons')
def __str__(self):
return f'{self.serial.title} || Season {self.number}'
class Episode(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
title = models.CharField(max_length=150)
release_date = models.DateField(db_column='date')
description = models.TextField()
rating = models.DecimalField(max_digits=2, decimal_places=1)
is_for_adults = models.BooleanField(default=False)
trailer_url = models.URLField(null=True, blank=True)
number = models.PositiveIntegerField(
validators=[MinValueValidator(1, message='Minimum season for any episode is 1')])
season = models.ForeignKey(Season, on_delete=models.CASCADE, related_name='episodes')
length = models.CharField(max_length=6)
def __str__(self):
return f'{self.season} || {self.title}'
@property
def actors(self):
return self.season.serial.actors.all() + self.actors.all()
@property
def image(self):
return self.season.serial.image
class New(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
title = models.CharField(max_length=255)
description = models.TextField()
date = models.DateField(db_column='date')
image = models.URLField(unique=True, null=True)
def __str__(self):
return self.title
class Actor(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
name = models.CharField(max_length=50)
image = models.URLField(null=True)
movies = models.ManyToManyField(Movie, related_name='actors', blank=True)
series = models.ManyToManyField(Serial, related_name='actors', blank=True)
episodes = models.ManyToManyField(Episode, related_name='guest_actors', blank=True)
```
----
## Refactoring
----
We can refactor a little bit from the above code to make it a bit more succinct, as follows:
```python=
from django.core.validators import MinValueValidator
from django.db import models
import uuid
class Entity(models.Model):
class Meta:
abstract = True
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True, null=False, db_column='created_at')
updated = models.DateTimeField(auto_now=True, null=False, db_column='updated_at')
class Category(Entity):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class CommonDetail(Entity):
class Meta:
abstract = True
title = models.CharField(max_length=150)
release_date = models.DateField(db_column='date')
description = models.TextField()
rating = models.DecimalField(max_digits=2, decimal_places=1)
is_for_adults = models.BooleanField(default=False)
trailer_url = models.URLField(null=True, blank=True)
class Movie(CommonDetail):
is_featured = models.BooleanField(default=False)
length = models.CharField(max_length=6)
categories = models.ManyToManyField(Category, related_name='movies')
image = models.URLField(null=True)
thumbnail = models.URLField(null=True, editable=False)
def __str__(self):
return self.title
@property
def actors(self):
return self.actors.all()
class Serial(CommonDetail):
is_featured = models.BooleanField(default=False)
categories = models.ManyToManyField(Category, related_name='series')
image = models.URLField(null=True)
thumbnail = models.URLField(null=True, editable=False)
def __str__(self):
return self.title
@property
def actors(self):
return self.actors.all()
@property
def seasons(self):
return self.seasons.all()
class Season(Entity):
number = models.PositiveIntegerField(
validators=[MinValueValidator(1, message='Minimum season for any series is 1')])
serial = models.ForeignKey(Serial, on_delete=models.CASCADE, related_name='seasons')
def __str__(self):
return f'{self.serial.title} || Season {self.number}'
class Episode(CommonDetail):
number = models.PositiveIntegerField(
validators=[MinValueValidator(1, message='Minimum season for any episode is 1')])
season = models.ForeignKey(Season, on_delete=models.CASCADE, related_name='episodes')
length = models.CharField(max_length=6)
def __str__(self):
return f'{self.season} || {self.title}'
@property
def actors(self):
return self.season.serial.actors.all() + self.actors.all()
@property
def image(self):
return self.season.serial.image
class New(Entity):
title = models.CharField(max_length=255)
description = models.TextField()
date = models.DateField(db_column='date')
image = models.URLField(unique=True, null=True)
def __str__(self):
return self.title
class Actor(Entity):
name = models.CharField(max_length=50)
image = models.URLField(null=True)
movies = models.ManyToManyField(Movie, related_name='actors', blank=True)
series = models.ManyToManyField(Serial, related_name='actors', blank=True)
episodes = models.ManyToManyField(Episode, related_name='guest_actors', blank=True)
```