Fixturer

En fixture är en samling filer som innehåller det serialiserade innehållet i databasen. Varje fixtur har ett unikt namn och filerna som fixturen består av kan distribueras över flera kataloger i flera applikationer.

Hur man tillverkar en fixtur

Fixturer kan genereras med manage.py dumpdata. Det är också möjligt att generera anpassade fixturer genom att direkt använda serialiseringsverktyg eller till och med genom att skriva dem för hand.

Hur man använder en fixtur

Fixturer kan användas för att i förväg fylla på databasen med data för tester:

class MyTestCase(TestCase):
    fixtures = ["fixture-label"]

eller för att tillhandahålla några initial data med kommandot loaddata:

django-admin loaddata <fixture label>

Hur fixturer upptäcks

Django kommer att söka efter fixturer på dessa platser:

  1. I katalogen fixtures för varje installerad applikation

  2. I en katalog som anges i inställningen FIXTURE_DIRS

  3. I den bokstavliga sökvägen som anges av fixturen

Django kommer att ladda alla fixturer som den hittar på dessa platser och som matchar de angivna fixturnamnen. Om den namngivna fixturen har ett filtillägg kommer endast fixturer av den typen att laddas. Till exempel:

django-admin loaddata mydata.json

skulle bara ladda JSON-fixturer som heter mydata. Fixturtillägget måste motsvara det registrerade namnet på en :ref:serializer <serialization-formats> (t.ex. json eller xml).

Om du utelämnar tilläggen kommer Django att söka efter en matchande fixtur i alla tillgängliga fixturtyper. Till exempel:

django-admin loaddata mydata

letar efter alla fixturer av alla fixturtyper som heter mydata. Om en fixturkatalog innehåller mydata.json laddas den fixturen som en JSON-fixtur.

De namngivna fixturerna kan innehålla katalogkomponenter. Dessa kataloger kommer att inkluderas i sökvägen. Ett exempel:

django-admin loaddata foo/bar/mydata.json

söker efter <app_label>/fixtures/foo/bar/mydata.json för varje installerat program, <dirname>/foo/bar/mydata.json för varje katalog i FIXTURE_DIRS, och den bokstavliga sökvägen foo/bar/mydata.json.

Lastningsordning för fixturer

Flera fixturer kan anges i samma anrop. Till exempel:

django-admin loaddata mammals birds insects

eller i en testfallsklass:

class AnimalTestCase(TestCase):
    fixtures = ["mammals", "birds", "insects"]

Den ordning i vilken fixturerna laddas följer den ordning i vilken de listas, oavsett om det är när du använder management-kommandot eller när du listar dem i testfallsklassen enligt ovan.

I dessa exempel laddas först alla fixturer med namnet mammals från alla program (i den ordning som programmen definieras i INSTALLED_APPS). Därefter laddas alla fixturer med namnet fåglar, följt av alla fixturer med namnet insekter.

Tänk på att om databasens backend stöder begränsningar på radnivå kommer dessa begränsningar att kontrolleras i slutet av transaktionen. Alla relationer över fixturer kan resultera i ett laddningsfel om databaskonfigurationen inte stöder uppskjuten begränsningskontroll (se MySQL-dokumenten för ett exempel).

Hur fixturer sparas i databasen

När fixturfiler bearbetas sparas data i databasen som de är. Modelldefinierade save()-metoder anropas inte, och alla pre_save- eller post_save-signaler anropas med raw=True eftersom instansen endast innehåller attribut som är lokala för modellen. Du kan till exempel vilja inaktivera hanterare som kommer åt relaterade fält som inte finns under fixturladdning och som annars skulle ge upphov till ett undantag:

from django.db.models.signals import post_save
from .models import MyModel


def my_handler(**kwargs):
    # disable the handler during fixture loading
    if kwargs["raw"]:
        return
    ...


post_save.connect(my_handler, sender=MyModel)

Du kan också skriva en dekorator för att kapsla in denna logik:

from functools import wraps


def disable_for_loaddata(signal_handler):
    """
    Decorator that turns off signal handlers when loading fixture data.
    """

    @wraps(signal_handler)
    def wrapper(*args, **kwargs):
        if kwargs["raw"]:
            return
        signal_handler(*args, **kwargs)

    return wrapper


@disable_for_loaddata
def my_handler(**kwargs): ...

Tänk bara på att den här logiken kommer att inaktivera signalerna när fixturerna deserialiseras, inte bara under loaddata.

Komprimerade armaturer

Fixturer kan komprimeras i formaten zip, gz, bz2, lzma eller xz. Till exempel:

django-admin loaddata mydata.json

letar efter något av följande: mydata.json, mydata.json.zip, mydata.json.gz, mydata.json.bz2, mydata.json.lzma eller mydata.json.xz. Den första filen i ett komprimerat arkiv används.

Observera att om två fixturer med samma namn men olika fixturtyp upptäcks (t.ex. om mydata.json och mydata.xml.gz hittades i samma fixturkatalog), kommer fixturinstallationen att avbrytas och alla data som installerats i anropet till loaddata kommer att tas bort från databasen.

MySQL med MyISAM och fixturer

MyISAM-lagringsmotorn i MySQL stöder inte transaktioner eller begränsningar, så om du använder MyISAM får du inte validering av fixturdata eller en rollback om flera transaktionsfiler hittas.

Databasspecifika fixturer

Om du har flera databaser kan det hända att du har fixturdata som du vill ladda i en databas, men inte i en annan. I den här situationen kan du lägga till en databasidentifierare i namnen på dina fixturer.

Om inställningen DATABASER till exempel har en databas med namnet users definierad, namnge fixturen mydata.users.json eller mydata.users.json.gz och fixturen laddas endast när du anger att du vill ladda data till databasen users.