Defining many-to-one relationships with models.ForeignKey

Now, we will create the models that we will use to represent and persist the drone categories, drones, pilots, and competitions, and their relationships. Open the drones/models.py file and replace its contents with the following code. The lines that declare fields related to other models are highlighted in the code listing. The code file for the sample is included in the hillar_django_restful_06_01 folder, in the restful01/drones/models.py file.

from django.db import models 


class DroneCategory(models.Model):
name = models.CharField(max_length=250)

class Meta:
ordering = ('name',)

def __str__(self):
return self.name


class Drone(models.Model):
name = models.CharField(max_length=250)
drone_category = models.ForeignKey(
DroneCategory,
related_name='drones',
on_delete=models.CASCADE)
manufacturing_date = models.DateTimeField()
has_it_competed = models.BooleanField(default=False)
inserted_timestamp = models.DateTimeField(auto_now_add=True)

class Meta:
ordering = ('name',)

def __str__(self):
return self.name


class Pilot(models.Model):
MALE = 'M'
FEMALE = 'F'
GENDER_CHOICES = (
(MALE, 'Male'),
(FEMALE, 'Female'),
)
name = models.CharField(max_length=150, blank=False, default='')
gender = models.CharField(
max_length=2,
choices=GENDER_CHOICES,
default=MALE,
)
races_count = models.IntegerField()
inserted_timestamp = models.DateTimeField(auto_now_add=True)

class Meta:
ordering = ('name',)

def __str__(self):
return self.name


class Competition(models.Model):
pilot = models.ForeignKey(
Pilot,
related_name='competitions',
on_delete=models.CASCADE)
drone = models.ForeignKey(
Drone,
on_delete=models.CASCADE)
distance_in_feet = models.IntegerField()
distance_achievement_date = models.DateTimeField()

class Meta:
# Order by distance in descending order
ordering = ('-distance_in_feet',)

The code declares the following four models, specifically, four classes that are subclasses of the django.db.models.Model class:

  • DroneCategory
  • Drone
  • Pilot
  • Competition

Django automatically adds an auto-increment integer primary key column named id when it creates the database table related to each model. We specify the field types, maximum lengths, and defaults for many attributes.

Each class declares a Meta inner class that declares an ordering attribute. The Meta inner class declared within the Competition class specifies '-distance_in_feet' as the value of the ordering tuple, with a dash as a prefix of the field name to order by distance_in_feet in descending order, instead of the default ascending order.

The DroneCategory, Drone, and Pilot classes declare a __str__ method that returns the contents of the name attribute that provides the name or title for each of these models. This way, whenever Django needs to provide a human readable representation for the model, it will call this method and return its result.

The Drone model declares the drone_category field with the following line:

drone_category = models.ForeignKey( 
    DroneCategory,  
    related_name='drones',  
    on_delete=models.CASCADE) 

The previous line uses the django.db.models.ForeignKey class to provide a many-to-one relationship to the DroneCategory model. The 'drones' value specified for the related_name argument creates a backwards relation from the DroneCategory model to the Drone model. This value indicates the name to use for the relation from the related DroneCategory object back to a Drone object.

This way, we will be able to easily access all the drones that belong to a specific drone category. Whenever we delete a drone category, we want all the drones that belong to this category to be deleted, too, and therefore, we specified the models.CASCADE value for the on_delete argument.

The Competition model declares the pilot field with the following line:

pilot = models.ForeignKey( 
    Pilot,  
    related_name='competitions',  
    on_delete=models.CASCADE) 

The previous line uses the django.db.models.ForeignKey class to provide a many-to-one relationship to the Pilot model. The 'competitions' value specified for the related_name argument creates a backwards relation from the Pilot model to the Competition model. This value indicates the name to use for the relation from the related Pilot object back to a Competition object.

This way, we will be able to easily access all the competitions in which a specific pilot participated with his drone. Whenever we delete a pilot, we want all the competitions in which this pilot participated to be deleted, too, and therefore, we specified the models.CASCADE value for the on_delete argument.

The Competition model declares the drone field with the following line:

drone = models.ForeignKey( 
    Drone,  
    on_delete=models.CASCADE) 

The previous line uses the django.db.models.ForeignKey class to provide a many-to-one relationship to the Drone model. In this case, we don't create a backwards relation because we don't need it. Thus, we don't specify a value for the related_name argument. Whenever we delete a drone, we want all the competitions in which the drone participated to be deleted too, and therefore, we specified the models.CASCADE value for the on_delete argument.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset