Sunday, 3 May 2015

Django - Creating Models

To build familiarity with Models and ORM (Object relational mapping) offered by Django, we are going to use a bollywood relational structure depicted in the following ERD.


We will express the above entities, their attributes and relationships as Django models. 

Module - django.db.models

Actor

class Actor(models.Model):
    gender_choices = (
        ('M', 'Male'),
        ('F', 'Female')
    )

    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30, null=True, blank=True)
    gender = models.CharField(max_length=1, choices=gender_choices),
    dob = models.DateField()
    is_active = models.BooleanField(default=True)
    rec_created_date = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now = True)
    base_salary = models.DecimalField(max_digits=8, decimal_places=2, default=1000)
    introduced_by = models.ForeignKey('self', related_name='introduced', null=True, on_delete=models.SET_NULL)

Key points to focus -
  • You must always specify max_length with models.CharField
  • blank determines whether the field should be validated as required or not in forms. False means the form will generate an error if not provide, while True means empty values are allowed.
  • null determines whether the field should be set as NULL or NOT NULL at the DB level. This has nothing to do with form validation.
  • auto_now_add sets the value when record is created.
  • auto_now updates the value when any part of the record is updated.
  • Self referential foreign key can be created by using keyword 'self'

ProductionHouse

class ProductionHouse(models.Model):
    banner = models.CharField(max_length=50, unique=True)
    start_date = models.DateField()

Movie

class Movie(models.Model):
    title = models.CharField(max_length=50, unique_for_date='release_date')
    release_date = models.DateField()
    actors = models.ManyToManyField('Actor', through='MovieActor')
    production_house = models.ForeignKey('ProductionHouse')
    release_country = models.ManyToManyField('Country')

    class Meta:
        get_latest_by = 'release_date'
        ordering = ('title',)

    def __str__(self):
        return self.title

Key points to focus -
  • unique_for_date refers to a model.DateField and adds a constraint that the title should be unique for a particular release_date
  • If the model to be referenced is not already defined then its name must be given in quotes. E.g. 'Country'
  • When a many-to-many relation has other attributes then the relation goes through another model specified by through='MovieActor'
  • The __str__ function returns a friendly name to be printed when the object is accessed via console.

MovieActor

class MovieActor(models.Model):
    actor = models.ForeignKey('Actor')
    movie = models.ForeignKey('Movie')
    charges = models.DecimalField(max_digits=9, decimal_places=2)

    class Meta:
        unique_together = ('actor', 'movie')

    def __str__(self):
        return "{} - {}".format(self.actor, self.movie)

Key points to focus -
  • This is a through model. It must have foreign keys. While creating database columns for this table, foreign key fields are appended with _id. E.g. actor becomes actor_id
  • This model also illustrates unique_together constraint.

Country

class Country(models.Model):
    name = models.CharField(max_length=50)
    
    def __str__(self):
        return self.name

Finally to move these models to database,

>>> python manage.py makemigrations
>>> python manage.py migrate

We have learned about creating models. In the upcoming posts we will discuss CRUD operations via Django ORM. Click Here to go to next article.

No comments:

Post a Comment

Your comments are very much valuable for us. Thanks for giving your precious time.