Loading dummy data for your Django app using management commands
I’m at a point in my project now, GlucoseTracker, a web application for keeping tracking of blood sugar levels, where I’m starting to work on reporting and statistics. I need some dummy data automatically loaded in the database to work on this part and I need to refresh the data every few days or so.
It would be too much work to do this manually so I wrote a simple script that would be ran as amanagement command in Django. Using management commands is a good way to run the scripts that depend on the Django ORM and other Django features as the settings and paths will already be set for you.
To do this, all you have to do is a create a management.commands package in your application package and place your Python script there. For example, I have a script called load_random_glucose_data.py, so I’d put it here in my project:
glucosetracker\ glucoses\ management\ commands\ load_random_glucose_data.py
And here’s the content of my script:
import sys import random from datetime import date, timedelta from django.core.management.base import BaseCommand from django.db.models.base import ObjectDoesNotExist from django.contrib.auth.models import User from core.models import UserSettings from ...models import Glucose, Category from ...tests.factories import GlucoseFactory class Command(BaseCommand): args = 'username...' help = 'Populate glucose table with random dummy data.' def handle(self, *args, **options): if len(args) == 0: sys.stdout.write('You must specify a username.\n') sys.exit(1) try: user = User.objects.get(username=args[0]) except ObjectDoesNotExist: user = User.objects.create(username=args[0]) user.first_name = 'John' user.last_name = 'Smith' user.email = 'test@glucosetracker.net' user.set_password('demo') user.save() # Create an entry for the User Settings. UserSettings.objects.create(user=user).save() # Delete existing data. Glucose.objects.filter(user=user).delete() end_date = date.today() start_date = end_date - timedelta(days=90) for i in self.get_date_list(start_date, end_date): for _ in range(4): GlucoseFactory( user=user, category=random.choice(Category.objects.all()), record_date=i ) @classmethod def get_date_list(cls, start, end): delta = end - start return [(start + timedelta(days=i)) for i in range(delta.days+1)]
To run this script, I would type:
python manage.py load_random_glucose_data jsmith –settings=settings.local
The script basically takes a username as an argument and creates that user if it doesn’t exist. It will then delete all glucose data records for that user and re-populate it with dummy data for the past 90 days, 4 records per day, with random values and category.
I created a factory class called GlucoseFactory using Factory Boy inside my test package which takes care of the creation of glucose objects.
Now in my app, I can view these randomly generated data and it gives me an idea of what a user might see after he had entered enough data.
For example:
The app displays low and high blood glucose levels in red, the target range in green, and the rest in blue. Later on, I will have a page or dashboard that will give the user a summary of his/her stats, like the last average glucose level the past 7 days, how may highs and lows were there, how many are within his/her target range, average value for each category, etc. I need to refresh the data from time to time because they’re date-sensitive and being able to just run one simple command to do this is a big time saver.
I also have my project set-up on GitHub to use Travis for continuous integration. So every time I push new code to the master branch it would auto-deploy the new code to my Heroku instance which I use to demo my app and the command to load the data also runs as part of the deployment.
If you have an app that relies on having fresh data loaded regularly, then having a command to auto-generate them would really help and save a lot of time during development.