7. Models

7.1. Model Fields

7.1.1. Text fields

  • CharField

  • TextField

  • SlugField

  • URLField

7.1.2. Numeric fields

  • DecimalField

  • IntegerField

  • PositiveIntegerField

  • PositiveSmallIntegerField

7.1.3. Logic fields

  • BooleanField

7.1.4. Date and time fields

  • DateField

  • DateTimeField

  • DurationField

  • TimeField

7.1.5. File fields

  • FileField

  • ImageField

7.1.6. Relations

  • ForeignKeyField

  • ManyToManyField

7.2. Model field arguments

7.2.1. All

  • verbose_name

  • max_length

  • choices

  • validators

  • help_text

  • null

  • blank

  • default

  • db_index

7.2.2. Relations

  • to (ForeignKey, ManyToManyField)

  • related_name (ForeignKey, ManyToManyField)

  • on_delete (ForeignKey, ManyToManyField)

7.2.3. Date and time

  • auto_add (DateField, DateTimeField)

  • auto_add_now (DateField, DateTimeField)

7.2.4. Numeric

  • decimal_places (DecimalField)

  • max_digits (DecimalField)

7.3. Abstract Models

class Meta:
    abstract = True

7.4. Architecture

  • Fat model architecture

7.5. Single File vs. Models per file

7.6. Reverse engineering database

  • python manage.py inspectdb

7.7. Database schema migration

7.7.1. Makemigrations

$ python manage.py makemigrations
Migrations for 'contact':
  addressbook/contact/migrations/0001_initial.py
    - Create model Contact

7.7.2. Migrate

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, contact, sessions
Running migrations:
  Applying contact.0001_initial... OK

7.8. Example Model

Code Listing 7.67. Example Model
import datetime

from django.db import models
from django.utils.translation import ugettext_lazy as _


class Contact(models.Model):
    STATUS_BEST_FRIEND = 'best-friend'
    STATUS_FRIEND = 'friend'
    STATUS_ACQUAINTANCE = 'acquaintance'
    STATUS_OTHER = 'other'
    STATUS_CHOICES = [
        (STATUS_BEST_FRIEND, _('Best Friend')),
        (STATUS_FRIEND, _('Friend')),
        (STATUS_ACQUAINTANCE, _('Acquaintance')),
        (STATUS_OTHER, _('Other'))]

    GENDER_MALE = 'male'
    GENDER_FEMALE = 'female'
    GENDER_OTHER = None
    GENDER_CHOICES = [
        (GENDER_MALE, _('Male')),
        (GENDER_FEMALE, _('Female')),
        (GENDER_OTHER, _('Undisclosed'))]

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    reporter = models.ForeignKey(verbose_name=_('Reporter'), to='auth.User', on_delete=models.CASCADE, null=True, default=None)
    is_deleted = models.BooleanField(verbose_name=_('Is deleted?'), default=False)

    first_name = models.CharField(verbose_name=_('First Name'), max_length=30)
    last_name = models.CharField(verbose_name=_('Last Name'), max_length=30, db_index=True)
    date_of_birth = models.DateField(verbose_name=_('Date of birth'), null=True, blank=True, default=None)
    email = models.EmailField(verbose_name=_('Email'), null=True, blank=True, default=None)
    bio = models.TextField(verbose_name=_('Bio'), null=True, blank=True, default=None)
    image = models.ImageField(verbose_name=_('Image'), null=True, blank=True, default=None)
    status = models.CharField(verbose_name=_('Status'), max_length=30, choices=STATUS_CHOICES, null=True, blank=True, default=None)
    gender = models.CharField(verbose_name=_('Gender'), max_length=30, choices=GENDER_CHOICES, null=True, blank=True, default=None)
    friends = models.ManyToManyField(verbose_name=_('Friends'), to='contact.Contact', blank=True, default=None)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

    def get_age(self):
        if not self.date_of_birth:
            return None

        today = datetime.date.today()
        return today.year - self.date_of_birth.year


    def save(self, *args, **kwargs):
        # ... execute at Model.save()
        return super().save(*args, **kwargs)

    class Meta:
        verbose_name = _('Contact')
        verbose_name_plural = _('Contacts')
        unique_together = ['first_name', 'last_name']

7.9. Assignments

7.9.1. Address Book

  • Lines of code to write: 50 lines

  • Estimated time of completion: 30 min

  1. Stwórz projekt addressbook

  2. Stwórz apkę contact

  3. Stwórz model Address z polami:

    • Typ (do wyboru typ: domowy, praca, komórka)

    • Ulica

    • Numer bloku

    • Numer mieszkania

    • Kod pocztowy

    • Miasto

    • Region

    • Kraj

  4. Stwórz model Person z polami:

    • Imię

    • Nazwisko

    • Data Urodzenia

    • Zdjęcie

    • Telefon (do wyboru typ: domowy, praca, komórka)

    • Email (do wyboru typ: domowy, praca, komórka)

    • Adres

  5. Osoba może mieć wiele adresów, telefonów i emaili

  6. Wygeneruj panel administracyjny

  7. Moża wylistować kontakty i na głównym ekranie widoczne są podstawowe pola osoby

  8. Dodaj wyszukiwarkę po nazwisku

  9. Dodaj filtrowanie po dacie urodzenia

The whys and wherefores
  • Umiejętność modelowania obiektów świata rzeczywistego

  • Umiejętność obsługi plików i obrazków

  • Umiejętność generowania paneli administracyjnych w Django