Fixtures w bazach danych Django

Gdy tworzycie aplikację Django, która będzie rozrzucona po kilku serwerach, czasami checie by pewne dane były od razu wrzucone do bazy danych, ponieważ są wymagane do poprawnego działania aplikacji. Do tego typu danych możemy zaliczyć kategorie, stany oraz inne rzeczy tego typu. Django nam pomaga z tzw. Fixtures i dzisiaj przedstawię jak ich użyć do stworzenia danych dla prostego modelu odpowiedzialnego za kategorie.

Model Category

Zaczniemy od stworzenia prostego modelu Category:

from django.db import models

class Category(models.Model):
    name = models.CharField(
        unique=True,
        db_index=True,
        max_length=32,
        primary_key=True,
    )
    description = models.CharField(
        max_lenght=256,
    )

Jak możecie zauważyć, model przechowuje informacje o dwóch rzeczach: nazwie kategorii oraz krótkim opisie. Pole name będzie również kluczem głównym naszej tabeli.

Tworzymy Fixtures dla naszej bazy

Django daje nam dwa sposoby na stworzenie fixtures:

Dane mogą być dostarczone w jednym z trzech formatów: json, xml oraz yaml. Dla naszego przykładu stworzymy plik json, ponieważ jest to format bardzo popularny w aplikacjach internetowych. Zakładając, że nasza aplikacja Django nazywa się notes:

[
  {
    "model": "notes.category",
    "fields": {
      "name": "personal",
      "description": "Category to keep personal notes."
    }
  },
  {
    "model": "notes.category",
    "fields": {
      "name": "work",
      "description": "Category to keep work notes."
    }
  }
]

Jak możecie zauważyć, jest to dość proste. Pole model przechowuje informacje z jakiej aplikacji i jaki model są opisywane, a pole fields opisuje każde pole z naszego modelu. Jak już ustaliliśmy wcześniej, nasz klucz publiczny opiera się na polu name, więc nie musimy dodawać nic więcej.

Gdzie umieścić Fixture?

Mamy już stworzony kod odpowiedzialny za fixtures, ale gdzie właściwie go umieścić? Domyślna (i moim zdaniem najlepsza, ponieważ trzyma się standardów) lokacja to folder fixtures w głównym folderze aplikacji. Nazwijcie to jakoś sensownie. Dla naszego przykładu może to być:

Jak załadować Fixture?

Jeżeli umieściliście plik tak jak opisałem wyżej, to możecie wywołać następującą komendę, by załadować dane:

Używanie fixtures w pytest

Ten przykład nie byłby pełny, gdybyśmy nie porozmawiali o testach. Jak już mówiłem w poprzednich wpisach (i będę to powtarzać), testowanie aplikacji jest bardzo ważne w procesie wytwarzania oprogramowania. Dlatego też, musimy znaleźć sposób aby wczytać nasze dane dla każdego testu, tak aby cały system działał jak trzeba. Użyjemy tzw. pytest fixture (nie mylić z database fixture) w następujący sposób:

from django.core.management import call_command

@pytest.fixture(autouse=True)
@pytest.mark.django_db
def load_fixtures():
    call_command('loaddata', 'category_fixtures.json')

No i to by było na tyle.