This page looks best with JavaScript enabled

Django Administrative Commands

 ·  🎃 kr0m

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:


As always, we activate the project’s venv:

cd rxWod
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:

mkdir -p rxWod/management/commands/
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:

vi exercise_data.txt

# 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:

python manage.py rebuild_database ./exercise_data.txt

------------------------------------  
| 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 -l
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.

If you liked the article, you can treat me to a RedBull here