Last active
December 20, 2019 06:16
-
-
Save nmfzone/f3e7a54671374094a4068533360d4122 to your computer and use it in GitHub Desktop.
Django Database Seeder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import factory | |
from django.contrib.auth import get_user_model | |
from django.contrib.auth.hashers import make_password | |
User = get_user_model() | |
class UserFactory(factory.django.DjangoModelFactory): | |
class Meta: | |
model = User | |
name = factory.Faker('name') | |
username = factory.Faker('user_name') | |
email = factory.Faker('email') | |
password = make_password('12345678') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import factory | |
from django.apps import apps | |
from django.apps.config import AppConfig | |
from django.conf import settings | |
from django.core.management.base import BaseCommand, CommandError | |
from importlib import import_module | |
class Command(BaseCommand): | |
help = 'Run Database seeders' | |
args = "[appname ...]" | |
missing_args_message = None | |
def add_arguments(self, parser): | |
parser.add_argument('args', default=[], metavar='app_label', nargs='*', help='One or more application label.') | |
@factory.Faker.override_default_locale(getattr(settings, 'FAKER_LOCALE', 'en_US')) | |
def handle(self, *app_labels, **options): | |
try: | |
if app_labels and len(app_labels) > 0: | |
app_configs = [apps.get_app_config(app_label) for app_label in app_labels] | |
else: | |
app_configs = [AppConfig.create(app_label) for app_label in settings.INSTALLED_APPS] | |
except (LookupError, ImportError) as e: | |
raise CommandError("%s. Are you sure your INSTALLED_APPS setting is correct?" % e) | |
seeders = [] | |
for app_config in app_configs: | |
try: | |
module_seeders = import_module('%s.%s' % (app_config.name, 'seeders')) | |
except ImportError: | |
continue | |
if callable(getattr(module_seeders, 'handle', None)): | |
seeders.append({ | |
'order': getattr(module_seeders, 'order', 0), | |
'handle': module_seeders.handle | |
}) | |
else: | |
raise AttributeError("You should define 'handle' method in %s." % (app_config.name + '.seeders')) | |
seeders.sort(key=lambda item: item['order']) | |
for seeder in seeders: | |
seeder['handle'](self) | |
self.stdout.write(self.style.SUCCESS('Database seeding completed successfully.')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from .factories import UserFactory | |
order = 0 | |
def handle(command): | |
UserFactory(name='John Doe') | |
UserFactory.create_batch(size=10) |
You can specify order of the seeders. It's useful when you have some applications, then you need to run seeder from app A before seeder from app B.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dependency:
You just need to place that code something like this.
---- app
--------
__init__.py
-------- management
------------
__init__.py
------------ commands
----------------
__init__.py
---------------- seed.py
---- users
--------
__init__.py
-------- factories.py
-------- seeders.py
Then, you can run it using command
python manage.py seed
Tested in Django 2.2