A Django FotoBlog in VS Code — Custom User Model

How To Create A FotoBlog in VS Code — Part II — DjangoSeries Episode # 16

J3
Jungletronics
6 min readMar 26, 2023

--

Starter code for this episode: GitHub link

Hi, we get started with this question:

Why we haven’t made migrations in the previous episode?

Because we will not use the Django Default User Model.

We will use a Custom User Model.

Let me explain better…

Django comes with a User model?

Yes, Django comes with a built-in User model that provides authentication functionality out of the box. The User model is defined in the django.contrib.auth.models module and includes common fields such as username, password, email, and first_name and last_name.

You can use the built-in User model as is, or you can create a custom User model by subclassing the AbstractBaseUser class or the AbstractUser class provided by Django. This allows you to add additional fields or modify existing ones to fit your application's specific requirements.

It’s worth noting that starting from Django 3.1, the recommended approach is to create a custom User model using the AbstractUser class instead of AbstractBaseUser, as it includes some additional fields and functionality that make it easier to work with.

Just to reinforce the point, even if you think that the default User model is good enough, you should always implement a custom User model in your project, even if it is identical to the default one.

After your Django site has been set up and your initial migrations have been run, it requires lots of tricky migrations and an in-depth understanding of SQL. Please refer to this project where I use One-To-One relationship with User Model (jungledev/users_hub/models.py), signals, and more complicated things:/).

So that’s why we postpone the migration. Let’s get it on!

00#Step —Use a Custom User Model

When using a custom User model, Django provides two base classes that you can extend to meet your specific needs:

AbstractUser — This class provides all the features and fields of the default User model and the added flexibility of being able to add additional fields and methods to it later. We will extend this one. Type inside authenticate/models.py:

# authenticate/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class User(AbstractUser):
CREATOR = 'CREATOR'
SUBSCRIBER = 'SUBSCRIBER'

ROLE_CHOICES = (
(CREATOR, 'Creator'),
(SUBSCRIBER, 'Subscriber'),
)

profile_photo = models.ImageField()
role = models.CharField(max_length=30, choices=ROLE_CHOICES)

AbstractBaseUser — Extend this class if we don't want to use every field provided by the default User class.

On more thing: we’ll need to import PIL. The Python Imaging Library (PIL) is a 3rd party Python package that adds image processing capabilities to your Python interpreter. It allows you to process photos and do many common image file manipulations.

# on terminal, to work with image, run:

pip install pillow

01#Step — Configure Django to Use a Custom User

Just point AUTH_USER_MODEL to the correct model in the settings.

# fotoblog/settings.py

...
AUTH_USER_MODEL = 'authenticate.User'

02#Step —Finally, run the Initial Migrations:

Open the terminal, and type:

python manage.py makemigrations
python manage.py migrate
Finally we migrate successfully our fotoblog database

03#Step — Open dbeven.ce app and point it to db.sqlite3:

Inside dbeven.ce app go to Database > New Database Connection > SQLITE > next and points to sqlite3.db file (~/fotoblog/fotoblog); Select All DBs and right click mouse to Create a new ERP Diagram:

ERP Diagram — fotoblog

When you extend the AbstractUser class in Django, it creates several tables in the database:

  1. authenticate_user: This table contains the default fields of the AbstractUser class such as username, email, password, first_name, last_name, etc, and the two fields we’ve added: profile_photo and role;
  2. authenticate_user_groups: This table contains the relationship between users and groups. It is a Many-To-Many table that stores the user's ID and the group's ID;
  3. authenticate_user_user_permissions: This table contains the relationship between users and permissions. It is a Many-To-Many table that stores the user's ID and the permission's ID;
  4. auth_group: This table contains the groups that can be assigned to users;
  5. auth_permission: This table contains the permissions that can be assigned to users. It has the format <crud>_<auth_sys>. Crud_id: 1-add | 2-change | 3-delete | 4-view; The auth system consists of logentry | permission | group | contenttype | session | user; So for User , add_user, change_user, delete_user, view_user;
  6. django_content_type: They are: admin | auth | contenttypes | sessions |authenticate;
  7. django_admin_log: It generates a REPORT:
Report:
At the time [action_time]
the user [user_id]
changed
by the register [object_id] code,
the artifact [content_id_type]
Represented by title [object_repr]
using [action_flag] permission
registering the message: [change_message]
A Report example:

At 2023–02–22 18:23:35.629424
the user 1 - j3
changed
by the register 2 code (blog_blog table register 2)
the artifact blog.blog (table <app><model>)
represented by title - Blog 1 - From UserTest2
using 2 - change permission
registering the message: [{"changed": {"fields": ["Starred"]}}]

What is the role of django_admin_log table?

The django_admin_log table is a built-in table in Django's default database schema that is used to log all the administrative activities performed in the Django admin interface.

Whenever a user performs any action on a model through the Django admin interface, such as adding, modifying, or deleting an object, a record of that activity is stored in the django_admin_log table. This includes the user who performed the action, the date and time of the action, the type of action performed, the name of the model, and the primary key of the affected object (see Report example above).

The django_admin_log table is designed to help track changes made by administrators to the system and to provide a history of those changes. This can be useful for auditing purposes, debugging issues, and identifying potential security threats.

In addition, the django_admin_log table can be queried directly using Django's built-in query API or accessed through the Django admin interface itself. This allows administrators to view a log of all the actions performed in the system, as well as filter, search, and export the log as needed.

When you add additional fields to the AbstractUser class, Django creates new columns in the auth_user table for each field. For example, if you add a phone_number field to the AbstractUser class, Django will create a new phone_number column in the auth_user table.

Let’s Recap!

  • Django uses the User model to handle authentication.
  • It is always a good idea to use a custom User model in a project, even if you don't need added functionality, as it makes it much easier to customize it later.
  • You can extend the AbstractUser to build on the default User model.
  • You can extend AbstractBaseUser for further flexibility and to design all the fields yourself.

In the next episode we will Create a Login Page With Self-Service Password Reset functionality.

See you there!

bye for now!

References & Credits

Create a Web Application With Django by openclassrooms.com

DBeaver Community 23.0.0 by dbeaver.io

A Django Blog In VS Code — Quick Start! by jungletronics

Tagging:

Note: run in one line in the terminal.

 git tag -a Episode.02 -m "FotoBlog - v1.0:  from http://jungletronics.com" 
-m "Second Episode Tutorial - DjangoSeries - Step-by-step list:"
-m "1-Use Custom Model;"
-m "2-Config Djangoto use Custom User;"
-m "3-Run the Migration"

git push origin Episode.02

Note: on github repo click tag. I am using Python 3.7.6 Django 3.2.18.

Nave-Gate-Tuts-Parts: I . II . III . IV . V . VI . VII . VIII . IX . X

--

--

J3
Jungletronics

Hi, Guys o/ I am J3! I am just a hobby-dev, playing around with Python, Django, Ruby, Rails, Lego, Arduino, Raspy, PIC, AI… Welcome! Join us!