Build an API system with Python Django Rest Framework — Part 2 : Generate App & Create Models
It is a series of simple guide:
- Build an API System With Python Django Rest Framework — Part 1: Dockerize Python Django
- Build an API system with Python Django Rest Framework — Part 2 : Generate App & Create Models
Previously in part 1, we have setup :
- Dockerfile & docker-compose.yml for Python image
- Django & Django rest framework inside container
- Generate Project template by
django-admin
In following parts, I will break into smaller sections for easier understanding. It may be better than showing all the things at one article.
So, in this section, we will do the followings:
- Generate app template by
manage.py
- Configure Django & DRF(Django Rest Framework)
- Create sample model & view
- Show them on admin page
We will use manage.py
to generate some boilerplate code so that we don’t need to type in everything manually every time we start a new app. It is basically similar to django-admin
. From Django document:
manage.py
is automatically created in each Django project. It does the same thing asdjango-admin
but also sets theDJANGO_SETTINGS_MODULE
environment variable so that it points to your project’ssettings.py
file.
Generate an app
Make sure you already started the container that we built in previous section. Then open a command prompt and connect to the container by below command:
docker ps
Then you can see below result
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
<container id> tutor_medi_web "sh -c 'source ../..…" 11 hours ago Up 20 seconds 0.0.0.0:9090->8000/tcp tutor_medi_web
Now you got the running container ID , you can connect to it by executing the /bin/sh
command.
docker exec -it <your container ID> /bin/sh
You are in container now !
Another way:
You can use Docker GUI to connect to existing container, with just one click on the CLI icon of running container.
Now, let’s generate an app template using manage.py
!
App directory location?
According to Django documentation, you can actually put the app folder anywhere. Same directory level as project folder, or inside project folder as a submodule. It depends on your need and future flexibility if the app may need to be shared with other projects.
Here we will generate the app as same level as project. Let’s create an app calledpet
:
cd /code/src/proj_medi/
source /code/venv/bin/activate
python manage.py startapp pet
Remember to change the environment by source
command as above
After execute, you will see our directory structure like this:
/code/src/proj_medi
├── manage.py
├── pet
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── proj_medi
└── ...
Configure Django & DRF(Django Rest Framework)
Now, we have project & app code template ready. But we first need to configure them before really coding our models.
First, create an admin account using below command. (Remember to change to venv
if you quit the command prompt that we used in previous section)
python manage.py createsuperuser
Then it will ask you to enter username and password …etc.
This account will be used to login to admin page in later section. And it is saved into the sqlite database, which is used by Django by default. You can find the sqlite file: db.sqlite3
under /code/src/proj_medi
Extra:
You can use some GUI tools to browse the sqlite database, such as DB Browser for SQLite
Next, edit your setting.py
under project folder /code/src/proj_medi/proj_medi
, add ‘rest_framework’
& the app we just created as below:
INSTALLED_APPS = [
...... 'rest_framework',
'pet.apps.PetConfig', ......
]
pet.apps.PetConfig
is to tell our project, by adding a reference to pet
configuration class
ALL Finish ! It’s all that simple. Now you can build anythings with the Django & using DRF package.
Next section we will build some simple models & views. by some pieces of code. Then we are able to perform CRUD by API / admin page, even WITHOUT building whole bunch of codes we normally do in other languages or framework.
Create sample model & view
In this final section, we will create a model and their view. So you can access them through web , admin page or API.
Edit /code/src/proj_medi/pet/models.py
as below:
from django.db import models# Create your models here.class Pet(models.Model):
hp = models.IntegerField(default=0)
attack = models.IntegerField(default=0)
defense = models.IntegerField(default=0)
#default related name = skill_setclass Skill(models.Model):
owned_pet = models.ForeignKey(Pet, on_delete=models.CASCADE)
description_text = models.CharField(max_length=200)
power = models.IntegerField(default=0)
We create two sample class in models.py
, Pet & Skill. It is quite common in games that we use some pets to fight. So these Pet
, has some attribute such as hp, attack …etc. Skill
is about the skills that a pet owns. Imagine a Pet
owns two Skill
like “Fireball” & “Frost wall”.
One thing to be noted, in Django, you can define Many-to-One, Many-to-Many, One-to-One relationship. But you cannot define One-to-Many. Instead, when you define Many-to-One by using
models.ForeignKey(Pet,xxxxx)
, you can actually accessSkill
fromPet
. This is because Django will create a related name in the target model ofmodels.ForeignKey
. You can check out more info from their doc.
Then, in your command prompt, make sure you already changed environment & in same directory with manage.py
, execute below command:
python manage.py make migrations
This command is to tell Django, we made some changes to our model. And ask Django to prepare files for modifying database(without execute it yet). The prepared changes file is pet/migrations/0001_initial.py
.
Finally , run the migration execute command:
python manage.py migrate
The database tables are created accordingly. You can already start to use these two models to store data. Or we can try the model in shell
and using Django database API
shell
means Python Interactive Shell which is used to execute Python code line-by-line and get the result.
python manage.py shell
Then you are now in python shell , and enter below code.
>>> from pet.models import Pet, Skill #To list out all Pet
>>> Pet.objects.all()
<QuerySet []>#To list out all Skill
>>> Skill.objects.all()
<QuerySet []>#Create a new Pet record
>>> newP = Pet( hp=100, attack=20, defense=10)
>>> newP.save()
#We created a record with pk / id =1
>>> newP.id
1#Let's try to modify some value and save
>>> newP.hp
100
>>> newP.hp = 120
>>> newP.save()
>>> newP.hp
120#Next, create a Skill with the foreign key point to this Pet
>>> newS = Skill( owned_pet=newP, description_text = "fireball", power=70)
>>> newS.save()#Access the attribute of Pet, from Skill
>>> newS.owned_pet.pk
1
>>> newS.owned_pet.hp
120#Get skill from Pet is also in similar way
>>> newP.skill_set.get(pk=1).id
1
>>> newP.skill_set.get(pk=1).power
70
After finish trying, you can enter exit()
or click Ctrl+D
to quit the python shell
Add the models to Django Admin
In this last section, we can add our model to the Django admin, so that we can perform CRUD action on models through Django admin page.
Edit your /code/src/proj_medi/pet/admin.py
from django.contrib import adminfrom .models import Pet, Skill
# Register your models here.admin.site.register(Pet)
admin.site.register(Skill)
We added the models to the Django admin. Now let’s access our webpage Django admin in http://localhost:9090/admin (Please check your docker-compose.yml setting for the correct port ). And then login with the admin user account we created before.
You can see in bottom part, we are able to view, create, update, delete the two models. And we even didn’t make any coding on the webpage, but just two lines of code to add the models to admin. (In my previous workplace, we always took few days or even weeks to just create such simple CRUD pages for managing some database tables & records… but it is another story.)
At this stage, I believe we already learned how to create some models in quick way, and use the Django default admin to manage those records easily. Certainly, there are a lot of things for optimization. But I will leave it to future articles.
In the next part, I will start to use Django Rest Framework package, to further speed up & enhance our API development experience. Such as using Response()
to handle the response to return a good UI of API information OR return pure json.
Please leave comment if you think any parts can become better or do in a smarter way!