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:
I katalogen
fixtures
för varje installerad applikationI en katalog som anges i inställningen
FIXTURE_DIRS
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
.