In this article I will show you how to easily get dummy data going for your Django project and I promise it is easier than you might expect!
I will be assuming the following is true:
As you might know from my testing django with managed and unmanaged models article I am a big fan of the factory_boy library. It does such a great job of giving us realistic data for our models without a lot of hassle - and once again, we'll lean on that library here for our dummy data.
This all gets broken down into three main sections: creating the factories, creating the commands and running the commands.
Let's get to it!
Open your Django project in your favorite IDE/editor (I prefer VSCode, if you like something else - leave a comment!)
Open your console and navigate to your Django project directory
With the assumption that you have a working application with existing models - let's add factory_boy
to the mix so we can get some dummy data generated for us as needed.
STEP 1: From console run pip install factory_boy
I prefer to add factory_boy
to my requirements-dev.txt
file at this point - to make it easy on myself in the future. If you're not using requirements files - perhaps read my article on what are requirements files.
STEP 2: Create a factories.py
file (important: ensure it is located in your app directory)
This file will give us all the control we need so our dummy data is realistic and randomized, just like it would be in the real world.
STEP 3: Create our "factories" (examples below of a Django model and the corresponding factory)
models.py
):class Thing(models.Model): last_login = models.DateTimeField(null=True) end_year = models.IntegerField() first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) username = models.CharField(max_length=30) email = models.CharField(max_length=75) active = models.BooleanField(default=False)
factories.py
):class ThingFactory(factory.django.DjangoModelFactory): class Meta: model = yourapp.models.Thing last_login = factory.fuzzy.FuzzyDateTime(timezone.now()) end_year = 2021 first_name = factory.Faker("first_name") last_name = factory.Faker("last_name") username = factory.LazyAttribute( lambda a: "{0}.{1}".format(a.first_name, a.last_name).lower() ) email = factory.LazyAttribute( lambda a: "{0}.{1}@test.com".format(a.first_name, a.last_name).lower() ) active = True
Now when we call the factory like ThingFactory()
it will generate a Thing
model for us with random data. It can generate almost any random data you would want - check out the The factory_boy docs for more information and examples on how it generates that data.
Generating our own custom management commands is easy in Django! I am going to create a command we can call with python manage.py create_app_data
STEP 1: In your app directory create the following directories
Directory structure:
your_app_dir/management/commands/
STEP 2: Inside the commands
directory create the following two files:
create_app_data.py
delete_app_data.py
Now we have added two commands to our project - so now we can write what they will do!
Our create_app_data.py
should contain something like this:
from your_project.settings import is_debug from your_app.factories import ThingFactory class Command(BaseCommand): help="Creates dummy Things for our app" @transaction.atomic def handle(self, *args, **kwargs): # Check to ensure we are in an environment # where debug is True to avoid adding data # in a production environment if is_debug(os.environ.get("DJANGO_DEBUG")): # Create new Things for our app self.stdout.write("Creating the new Things for our app") for i in range(10): ThingFactory() else: self.stdout.write( """ !!!We will not create the app data because DEBUG is set to False which may indicate a production environment!!! """ )
Our delete_app_data.py
should contain something like this:
from your_project.settings import is_debug from your_app.models import Thing class Command(BaseCommand): help="Deletes dummy Things for our app" # Using this decorator ensures that the SQL is bundled up and the commands are # ran together - speeding up the process @transaction.atomic def handle(self, *args, **kwargs): # Check to ensure we are in an environment # where debug is True to avoid deleting data # from a production environment if is_debug(os.environ.get("DJANGO_DEBUG")): # Delete Things from our app self.stdout.write("Deleting Things from our app") models = [Thing] for m in models: m.objects.all().delete() else: self.stdout.write( """ !!!We will not delete the app data because DEBUG is set to False which may indicate a production environment!!! """ )
A few additional notes about these commands:
settings.py
file called is_debug
that checks for an environment variable we pass to it - which in our case is DJANGO_DEBUG; we check that in our commands to hopefully prevent these commands from ever being ran in a production environment.The is_debug
setting looks like this:
def is_debug(environment_variable): """ Returns boolean for the string environment variable """ return environment_variable.lower() in ["true", "True"]
delete_app_data.py
file, I create a list of models so that in cases where we have created mulitple models worth of data in our create command, we can add the models there to delete those same models data.At this point we have all the pieces in place to create some dummy data!
In your console (at the project level) you can run the following to create some dummy data:
python manage.py create_app_data
If you want to delete the dummy data you can run:
python manage.py delete_app_data
This is a great starting point to creating dummy data. If you wanted to use these commands in testing? You could!
# imports at the top of the file from django.core import management class YourTestCase(TestCase): def setUp(self): # This creates the dummy data for the test management.call_command( "create_app_data", verbosity=0 )
You could also call the delete_app_data
command from within the create_app_data
command so it would essentially "reset" the data when you called create_app_data
, a nice feature!
By using this method of creating dummy data, it allows for a lot of customization/flexibility and sets up your app with a lot of dummy data that will be useful when developing features locally.
I hope you have found this article helpful in understaning how to quickly/easily get dummy data setup for your Django Application!
I would love to hear from you in the comments below!
Cheers!