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.4. 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

  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

About:
  • Lines of code to write: 50 lines
  • Estimated time of completion: 30 min
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