NOTE: This article was initially posted on my Substack, at https://andresalvareziglesias.substack.com/
Hi everyone!
Our multiplayer Tic Tac Toe is growing, and we have learned a lot about Django in this way: how to create a basic Django App, how to structure our app with subsites, how to separate UI and logic with views... Now, is the turn of a very, very, VERY important part of the development: managing pur application data.
Django comes with a great integrated ORM, so... let's learn how to use it!
Articles in this series
- Chapter 1: Let the journey start
- Chapter 2: Create a containerized Django app with Gunicorn and Docker
- Chapter 3: Serve Django static files with NGINX
- Chapter 4: Adding a database to our stack
- Chapter 5: Applications and sites
- Chapter 6: Using the Django ORM
- Chapter 7: Users login, logout and register
Writing Data Models
In chapter 4 of the series, we added a TimescaleDB (PostgreSQL) instance to our cluster. Now is the time to use it.
The Django migration process also automates the DB schema creation and management. To do that, Django must know the structure of our tables. To define them, we need to write Data Models.
A Data Model is a class that describes our table. For example, let' write a couple of Data Model for our Tic Tac Toe games, inside the game/models.py file:
class Game(models.Model):
user_o = models.ForeignKey(
User,
related_name="GameUserO",
on_delete=models.DO_NOTHING
)
user_x = models.ForeignKey(
User,
related_name="GameUserX",
on_delete=models.DO_NOTHING,
null=True
)
board = models.CharField(max_length=9)
creation = models.DateTimeField(auto_now_add=True)
last_move = models.DateTimeField(auto_now=True)
winner = models.CharField(max_length=1)
class GameMovement(models.Model):
user = models.ForeignKey(
User,
related_name="GameMovement",
on_delete=models.DO_NOTHING
)
game = models.ForeignKey(
Game,
related_name="GameMovement",
on_delete=models.DO_NOTHING
)
symbol = models.CharField(max_length=1)
movement = models.IntegerField()
date = models.DateTimeField(auto_now_add=True)
These two Data Models define two tables:
- A game table, linked to an Users table, with the current board and several info fields
- A game movements table, to store every movement of a game, linked to Users and Game tables
Once the Data Models are created, execute the cluster again. The migration process will do its magic, and the databases will be automatically created. To check them, we can enter inside the DB container with:
sudo docker exec -it db psql ticmagicalline
Once inside the PostgreSQL CLI get tables with \dt command:
List of relations
Schema | Name | Type | Owner
--------+----------------------------+-------+-------
public | auth_group | table | tic
public | auth_group_permissions | table | tic
public | auth_permission | table | tic
public | auth_user | table | tic
public | auth_user_groups | table | tic
public | auth_user_user_permissions | table | tic
public | django_admin_log | table | tic
public | django_content_type | table | tic
public | django_migrations | table | tic
public | django_session | table | tic
public | game_game | table | tic
public | game_gamemovement | table | tic
(12 rows)
And voilá! We now have our two game tables among Django inner tables.
Using Data Models
Once the tables are defined and mapped as objects, now we can use the Django ORM to do a lot of operations from our views, like data retrieval:
myGames = Game.objects.filter(Q(user_o=user), Q(winner='')).order_by("-creation")
paginator = Paginator(myGames, numStartPageGames)
context['myGames'] = paginator.get_page(1)
context['myGamesCount'] = paginator.count
In this example, we added a filter to our query (user is our logged user) and we are sorting the resultset by the creation field.
In the same way, we can create a new game:
game = Game.objects.create(
user_o=user,
user_x=None,
board="EEEEEEEEE",
winner="",
creation=datetime.now()
)
Or modify and save and existing one:
game.last_move = datetime.now()
game.save()
As you can see, the Django ORM simplifies the data management of our app. Now, we have all tools to develop the full logic of our shiny Tic Tac Toe:
- The user must log into the app with its credentials (using standar Django users)
- The user must be able to see its created games, or create a new one
- The user must be able to make movements in it game
The real fun starts now!
About the list
Among the Python and Docker posts, I will also write about other related topics (always tech and programming topics, I promise... with the fingers crossed), like:
- Software architecture
- Programming environments
- Linux operating system
- Etc.
If you found some interesting technology, programming language or whatever, please, let me know! I'm always open to learning something new!
About the author
I'm Andrés, a full-stack software developer based in Palma, on a personal journey to improve my coding skills. I'm also a self-published fantasy writer with four published novels to my name. Feel free to ask me anything!
Top comments (0)