Tips for upgrading Python/Django versions in existing apps
Python is a robust and powerful programming language. In addition to machine learning, Python can be used for tasks such as web scraping, image processing, scientific computing, and much more. A framework such as Django, which is built on top of Python, enables you to build beautiful web applications—top websites such as Dropbox, Instagram, and YouTube use Django.
However, as you create applications and release them to consumers, upgrading to the latest Python version becomes essential to keep pace with updates and new features. For instance, Python 3.11 was released in October 2022, sporting various bug fixes. Before that, there was Python 3.10, 3.9, 3.8, and others. There are also numerous third-party libraries that you should regularly watch out for.
Incorporating these updates into our applications can be beneficial, as doing so can enhance the security and reliability. However, doing this incorrectly could also break your application.
Why you should be upgrading your Python version
Upgrading your Python and Django applications to the latest version is important for several reasons.
-
New versions come with additional features and improvements. Newer Django versions can help reduce boilerplate code, enabling you to develop and push products to the market much faster. They can also help you learn new ways of adding functionalities to your application that can be more fun and easier to implement.
-
New versions can help with bug fixes in your code. Apart from enabling your application to behave as expected, eliminating bugs also streamlines the software development process, meaning that you'll be less frustrated. A Python upgrade can improve your app's stability during production.
-
Upgrading your application also makes it easier to maintain your codebase. You can quickly incorporate changes in your project without major downtimes.
-
Ensuring you're using the latest Python or Django version also improves security. Hackers are always looking for new ways to infiltrate systems, steal data, install malicious files and viruses, and just wreak havoc. Upgrading your application to use the latest version of Python or Django ensures that you have the latest security updates.
Now that we understand why upgrading applications is necessary, let's jump into the action itself.
Things to know before updating
Before updating the Python version, you should read the changes in the newest Python release. Go through the official documentation, particularly the release notes. Note that with each new version, Django releases accompanying documentation, which is quite helpful when upgrading applications.
Next, look at the functions, objects, and other items deprecated in the latest version. Consider the deadline or timeline in which these deprecation changes are set to come into effect. Understanding the deprecation timeline allows you to better plan your upgrade process, including the prioritization of certain tasks over others.
You should also keep an eye on backwards compatibility. Remember that some things that work in your existing application may fail when you upgrade to a new Python version. This is why it's recommended to test things first before pushing to production. Whenever an upgrade causes your app to break, you can roll back to the previous version as you figure out the next steps.
How to update Python/Django apps
In this section, we will learn how to upgrade Python and Django in a simple Django Movie API to use the a newer version. You can download the project's code from this GitHub repository.
Check Django and other library versions
Once you've downloaded the Movie API project and finished setting it up on your computer, the first step is to check the versions of the dependencies that the project uses.
To do this, launch the project in your preferred code editor and open the requirements.txt file. All dependencies used by the project are listed in this file, as follows.
asgiref==3.3.1
Django==3.1.8
django-filter==2.4.0
djangorestframework==3.12.2
djangorestframework-simplejwt==4.6.0
pytz==2021.1
sqlparse==0.4.1
Since we now know the versions in use (shown above), the next step is to determine the current official version from the documentation. For instance, the latest official Django version is 4.2.1; our application uses an older version (3.1.8), so there's a need to upgrade.
Activate local debugging
Trying to update things in production could cause them to break and lead to poor user experience and other negative consequences. You should test your applications locally and ensure that everything is working before pushing them to production.
You can activate local debugging by setting the debug option in the settings.py file to True.
# settings.py
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, …)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/wa
# SECURITY WARNING: Don’t run with debug turned on in production!
DEBUG = True # Set debug to true
ALLOWED_HOSTS = []
Run Django checks with python -Wall manage.py check
Before starting the upgrade, we'll need to run several checks to determine if there are any deprecation warnings in our project.
Deprecation warnings show that certain features will stop working at some point simply because they have been replaced by better alternatives.
You can check for any warnings using the following command:
python -Wa manage.py test
Install new dependencies
Now that we have enabled local debugging and identified any deprecation warnings in our project, it's time to install new dependencies in our project.
To get the latest Django version, we use the following command.
python -m pip install -U Django
When you run the above command, the following output should appear in your terminal. We have now successfully updated Django to ver 4.2.1, asgiref to ver 3.6.0, and tzdata to ver 2023.3.
Requirement already satisfied: Django in c:\users\wanjamike\appdata\local\programs\python\python310\lib\site-packages (3.1.8)
Collecting Django
Downloading Django-4.2.1-py3-none-any.whl (8.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.0/8.0 MB 43.5 kB/s eta 0:00:00
Requirement already satisfied: sqlparse>=0.3.1 in c:\users\wanjamike\appdata\local\programs\python\python310\lib\site-packages (from Django) (0.4.1)
Collecting tzdata
Using cached tzdata-2023.3-py2.py3-none-any.whl (341 kB)
Collecting asgiref<4,>=3.6.0
Using cached asgiref-3.6.0-py3-none-any.whl (23 kB)
Installing collected packages: tzdata, asgiref, Django
Attempting uninstall: asgiref
Found existing installation: asgiref 3.3.1
Uninstalling asgiref-3.3.1:
Successfully uninstalled asgiref-3.3.1
Attempting to uninstall: Django
Found existing installation: Django 3.1.8
Uninstalling Django-3.1.8:
Successfully uninstalled Django-3.1.8
Successfully installed Django-4.2.1 asgiref-3.6.0 tzdata-2023.3
We can update the remaining dependencies in our project using the following command:
python -m pip install -U django-filter djangorestframework djangorestframework-simplejwt pytz sqlparse
Expected output:
Successfully installed django-filter-23.2 djangorestframework-3.14.0 djangorestframework-simplejwt-5.2.2 pytz-2023.3 sqlparse-0.4.4
Let's generate a new requirements.txt file and double-check that we have the latest libraries in our project.
pip freeze > requirements.txt
When you open the requirements.txt, you should find all the latest dependencies, as shown below:
asgiref==3.6.0
Django==4.2.1
django-filter==23.2
djangorestframework==3.14.0
djangorestframework-simplejwt==5.2.2
pytz==2023.3
sqlparse==0.4.4
tzdata==2023.3
Check methods and functions
In most software updates, developers will try to change how certain functions or components work to improve performance, efficiency, memory usage, or convenience. Rather than fighting such changes, consider embracing and integrating them into your application to realize their benefits.
Note that while this may be a time-consuming step, the benefits are worth it. You should go through the official documentation to understand new changes and learn how you can integrate them into your application.
Let's review some of the changes in Django 4.2 that can help you in future upgrades.
First, support for MariaDB 10.3, MySQL 5.7, and PostgreSQL 11 databases was dropped. If your application was using any of these database versions, consider upgrading. Make sure to back up your data before upgrading to avoid service disruptions.
Second, Django 4.2 changed how we do data indexing. In the past, we indexed data using the statement below:
index_together = [["rank", "name"]]
But now we must call the Index method from the models class, as demonstrated below.
indexes = [models.Index(fields=["rank", "name"])]
Third, the length_is template filter is now deprecated and has instead been replaced by the traditional == operator.
Don't do this:
{% if value|length_is:4 %}…{% endif %}
{{ value|length_is:4 }}
Do this:
{% if value|length == 4 %}…{% endif %}
{% if value|length == 4 %}True{% else %}False{% endif %}
Updating Python is important
Updates are a normal thing during software development. Therefore, it's best to learn how to update your app's Python version and integrate changes in our applications. Apart from improved security, software updates allow us to deal with bugs and ensure that our code is maintainable.
When upgrading to a new version of Python, make sure to test things out in your local environment before pushing them to production. We don't want things to break and cause a poor user experience.
Written by
Michael BarasaMichael Barasa is a software developer. He loves technical writing, contributing to open source projects, and creating learning material for aspiring software engineers.