# 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) ```