Open-sourcing django-swap-user to simplify custom user models
By default, the user model in Django framework includes an email, username, and password. But there are often situations where it is necessary to extend and replace the default user model. So our Python Teamlead wrote such a wrapper and open-sourced it.
Everyone knows that Python has a very popular Django framework. By default, the user model there includes an email, username, and password. But there are often situations where it is necessary to extend and replace the default user model.
For example, there are situations where we do not need a username, only an email. Or we need a phone number instead of an email, and the email is not important. In these types of situations, the default model should be changed to a custom one which includes the relevant fields. So, the purpose of the django-swap-user project is to replace an existing model with a custom one.
In addition, authorization by one-time code is now beginning to gain popularity. So we accounted for this scenario in the library as well. When a new user model appears, it has only one field—email or phone number—and a one-time passcode. There is no password stored in the database, and a one-time passcode is sent using any provider that you connect. You get a one-time SMS, which you can use to log in.
Why did we write an entire library for this? When we start new projects, we often need a custom user model. Previously, we copied everything from one project to another, but then we realized—why constantly copy, when you can write a library once and that's it. We wanted to find a ready-made library, but all the ready-made ones were abandoned or out-of-date. So our Python Teamlead, Artem Innokentiev, decided to write this wrapper himself and open-source it.
So, if you are tired of copying a custom user model from one project to other ones—use this package. It will do it all for you!
Installation
pip install django-swap-user
Architecture
Application swap_user
is split into several apps:
to_email
- provides user withemail
username fieldto_email_otp
- provides user withemail
username field and OTP (One Time Password) authenticationto_phone
- provides user withphone
username fieldto_phone_otp
- provides user withphone
username field and OTP (One Time Password) authentication
Why such an unusual architecture?
If we leave them in one app, they will all create migrations and tables, leading to redundant tables. They will be treated as three custom models within the same app, which causes confusion.
With this approach (where there is a common app which contains internal apps), the user can choose and connect only the specific user model best suited for concrete business logic.
We modeled this approach after the Django REST Framework authtoken
application, referenced here.
Utilizing a custom user model at the start of a project
When you are starting a project from scratch, this is the best time to integrate a custom user model, since you haven’t had a lot of migrations or you can easily regenerate them. Moreover, Django's official docs recommend that you use a custom user model, even if you are fully satisfied with the default one. In the future, it will be easier to extend a custom model to fit your use cases.
Incorporating a custom user model in the middle of a project
Adding a custom user model in the middle of a project is a harder way of doing things, but it is still possible.
- Complete all the steps in the testing database and—ONLY IF all of them were successful—try to apply it in the production environment
- Please note that these steps fit most cases, but in some circumstances, you may need to adapt to the situation
- Create a backup of your database
- Add stable tag into your repository or save a commit hash reference
- Pray :D
- Remove all of your migrations in every app of the Django project
- Remove all records from
django_migrations
table, for example, withSQL TRUNCATE django_migrations
- Now you have a "clean" state, so you can change the default model
- Generate new migrations for all of your applications—
python manage.py makemigrations
- Now you need to fake migrate, because you already have all the tables with data
- First, fake the
auth
application, because you are depending on this one:python manage.py migrate --fake auth
- Install the library, follow the instructions, and apply migrations
- Then, fake the rest of the migrations you have—
python manage.py migrate --fake
- Run your application!
Plans for the future
In the future, we plan to write better documentation and add implementation to the project. We will slowly add new authorization methods, for example, mixed ones. There are cases where you need to do authorization either by email or by phone, and we would like to add this.
At the moment, everyone can use this project, and we would love to attract members of the community to contribute and help with the development of the project!
And, of course, reach out to us via the form below if you need to develop an open-source solution or are looking for a team of professionals to build a project from scratch!