I will post the code here. It does not work with fixtures for me but might work for others and it seems to be a better solution for testing so here it is. I have some print calls to show me the progress.
- As described in management command docs I created the reset_data.py file in the App1/management/commands folder.
- Deleted all the files (db and migrations)
- Migrated all again
- filled the database again. (fixtures seems the best way but fails for me so I show two solutions).
The code:
from django.contrib.auth.models import User
from App1.models import *
from App2.models import * #etc
For folder and file manipulation
import os
from os.path import exists
from pathlib import Path
import shutil
For the commands
from django.core import management
from django.core.management.commands import migrate
from django.core.management.base import BaseCommand
class Command(BaseCommand):
args = ‘<foo bar …>’
help = ‘our help string comes here’
def handle(self, *args, **options):
self._reset_migrations()
self._migrate_apps()
#This works but is not supported for testing so ignore this code if you can
self._create_user()
self._create_data()
#For me this fails but it seems nice.
self._populate_db_from_fixtures()
def _reset_migrations(self):
cwd = os.getcwd()
# This is the code for sqlite db file deletion. Change for other databases.
db_file = cwd + '\db.sqlite3'
if(Path(db_file).is_file() ):
os.remove(db_file)
i = 0
for subdir, dirs, files in os.walk(cwd):
if(os.path.basename(os.path.normpath(subdir)) == "migrations"):
i = i+1
shutil.rmtree(subdir)
print('%i migration folders found and deleted' %(i))
def _migrate_apps(self):
print('\nmigrate all apps.')
print('Initial migration for the basics')
management.call_command('migrate')
For dependencies you might need to migrate apps separately.
print(‘\nmigrate Account’)
management.call_command(‘makemigrations’, ‘Account’)
management.call_command(‘migrate’)
# Or in bulk...call makemigrations for each app because the migrations directory does not excist
print('\nmigrate all other apps')
management.call_command('makemigrations', 'App1')
management.call_command('makemigrations', 'App2')
management.call_command(‘migrate’)
#THE TWO SOLUTIONS for filling the database
#OPTION 1: This is a beauty if it works (How to provide initial data for models | Django documentation | Django)
def _populate_db_from_fixtures(self):
# Load the data from fixture files
management.call_command(‘loaddata’, ‘data.json’)
#OPTION 2: This is the working solution for myself.
def _create_user(self):
print(‘Create user’)
u = User.objects.create_superuser(username=‘admin’, email=None, password=None)
u.set_password(‘Myfantasticpassword1234#%$IalwaysFORGET’)
u.save()
def _create_data(self):
print(‘Fill database’)
A1 = App1(title='A perfect title')
A1.save()
S1 = App2(name='The name', parent=A1)
S1.save()
I missed this sentence 100 times but …As described in the documentation “To add migrations to an app that doesn’t have a migrations directory, run makemigrations with the app’s app_label” So after deleting the all migration folders I have to call makemigrations per app. Reading is hard
With fixtures I have a few problems and things that feel over-complicated (passwords etc); or I just dont understand them
I started with a database filled with data. I used the command for dumpdata to create the fixture file (in the root app): python manage.py dumpdata > data.json; sorry forgot where to place the file afterwards) When using this file I got a UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xff in position 0: invalid start byte; Beside some more problems I decided to use my current trusted solution for filling the database.
I hope this is usefull for someone.
(edit to make it look a bit better)