Django allows us to program internal commands, which can be useful for all kinds of administrative tasks such as massively inserting data into the database, performing certain checks, quickly registering users, the limit is our imagination. In this article, I will explain how to massively insert exercises by reading them from a text file, this will save us a lot of time since we will not have to insert them one by one from the administration interface.
Before starting, it is recommended to read the previous articles on Django as they are the previous steps to this article:
- Django: Venv under FreeBSD
- Django: MVT, Apps and URLs
- Django: Database Models
- Django: Administration Interface
- Django: DTL(Django Template Language)
- Django: Debug Toolbar
- Django: User Registration and Authentication
- Django: Webpack
- Django: Bootstrap with WebPack
- Django: Project in Production
- Django: Translations
As always, we activate the project’s venv:
source bin/activate
cd rxWodProject/
In a previous article , we programmed a Django command that we left crontabbed to check for users who were left in the database halfway through registration. At that time, the command was called delete_limbo_users.
The following command will read data from a text file and insert it into the database:
vi rxWod/management/commands/rebuild_database.py
# rebuild_database.py
from django.core.management.base import BaseCommand
import argparse
import sys
from rxWod.models import Exercise
class Command(BaseCommand):
help = 'Rebuild database from file data.'
def add_arguments(self, parser):
parser.add_argument('file_path', help='Path to exercise data file.')
def handle(self, *args, **options):
file_path = options['file_path']
print('------------------------------------')
print('| Database Rebuilder by kr0m v0.2b |')
print('------------------------------------')
# Check for duplicated ids:
exercise_ids = []
with open(file_path) as fp:
for line in fp:
line = line.strip('\n')
if line == '' or line[0] == '#':
continue
exercise_id = line.split('|')[0]
#print('exercise_id: %s' % exercise_id)
#print('exercise_ids: %s' % exercise_ids)
if exercise_id in exercise_ids:
print('+ ERROR: Cant load exercises data, duplicated ID: %s' % exercise_id)
sys.exit()
else:
exercise_ids.append(exercise_id)
# Insert data:
print('>> Populating DB with new exercises, source: %s' % file_path)
inserted_exercises = 0
with open(file_path) as fp:
for line in fp:
line = line.strip('\n')
#print('')
#print('+ Readed line: %s' % line)
if line == '' or line[0] == '#':
continue
exercise_id = line.split('|')[0]
name = line.split('|')[1]
#print('name: %s' % name)
description = line.split('|')[2]
category_id = line.split('|')[3]
level = line.split('|')[4]
default_value = line.split('|')[5]
url = line.split('|')[6]
is_metabolic = line.split('|')[7]
name_es = line.split('|')[8]
description_es = line.split('|')[9]
print('- Inserting exercise ID: %s - %s - level: %s' % (exercise_id, name, level))
# object is the retrieved or created object and created is a boolean specifying whether a new object was created
exercise, created = Exercise.objects.get_or_create(exercise_id=exercise_id)
#print('Created: %s' % created)
exercise.name = name
exercise.description = description
exercise.category_id = category_id
exercise.level = level
exercise.default_value = default_value
exercise.url = url
exercise.is_metabolic = is_metabolic
exercise.name_es = name_es
exercise.description_es = description_es
exercise.save()
inserted_exercises = inserted_exercises + 1
print('>> Inserted exercises: %i' % inserted_exercises)
print('>> Done')
We generate the exercise file:
# Categoris: 0 Shoulders, 1 Back, 2 Biceps, 3 Triceps, 4 Chest, 5 Core, 6 Gluteus, 7 Quadriceps, 8 Hamstring, 9 Cardio, 10 Lumbar, 11 Grip
# Levels: 0 N1, 1 N2, 2 RX, 3 RX+
# ----- CORE -----
0|Sit Ups|Sit Ups|5|0|10|https://www.youtube.com/watch?v=_HDZODOx7Zw&list=PLgve_TNgIw480TOU1ZuFiZh-zfRkRZVM6&index=30|True|Abdominales|Abdominales
1|Sit Ups|Sit Ups|5|1|20|https://www.youtube.com/watch?v=_HDZODOx7Zw&list=PLgve_TNgIw480TOU1ZuFiZh-zfRkRZVM6&index=30|True|Abdominales|Abdominales
2|Sit Ups|Sit Ups|5|2|40|https://www.youtube.com/watch?v=_HDZODOx7Zw&list=PLgve_TNgIw480TOU1ZuFiZh-zfRkRZVM6&index=30|True|Abdominales|Abdominales
We insert the data:
------------------------------------
| Database Rebuilder by kr0m v0.2b |
------------------------------------
>> Populating DB with new exercises, source: ./exercise_data.txt
- Inserting exercise ID: 0 - Sit Ups - level: 0
- Inserting exercise ID: 1 - Sit Ups - level: 1
- Inserting exercise ID: 2 - Sit Ups - level: 2
>> Inserted exercises: 3
>> Done
If we consult the database, we will see that the data has indeed been inserted:
su - postgres
$ psql
postgres=# \c rxwod
rxwod=# SELECT * FROM "rxWod_exercise";
id | exercise_id | name | description | default_value | category_id | level | url | is_metabolic | name_en | name_es | description_en | description_es
----+-------------+---------+-------------+---------------+-------------+-------+----------------------------------------------------------------------------------------------+--------------+---------+-------------+----------------+----------------
1 | 0 | Sit Ups | Sit Ups | 10 | 5 | 0 | https://www.youtube.com/watch?v=_HDZODOx7Zw&list=PLgve_TNgIw480TOU1ZuFiZh-zfRkRZVM6&index=30 | t | Sit Ups | Abdominales | Sit Ups | Abdominales
2 | 1 | Sit Ups | Sit Ups | 20 | 5 | 1 | https://www.youtube.com/watch?v=_HDZODOx7Zw&list=PLgve_TNgIw480TOU1ZuFiZh-zfRkRZVM6&index=30 | t | Sit Ups | Abdominales | Sit Ups | Abdominales
3 | 2 | Sit Ups | Sit Ups | 40 | 5 | 2 | https://www.youtube.com/watch?v=_HDZODOx7Zw&list=PLgve_TNgIw480TOU1ZuFiZh-zfRkRZVM6&index=30 | t | Sit Ups | Abdominales | Sit Ups | Abdominales
(3 rows)
This is just an example, with these types of commands we can perform any type of administrative tasks quickly and easily.