In this post, we will specifically look at using AppSignal to track errors in a Django application.
We'll first create a Django project, install AppSignal, introduce some faulty code, and then use the AppSignal Errors dashboard to debug and resolve errors.
Let's get started!
Prerequisites
To follow along, you'll need:
- Python 3.8+ installed on your local machine
- An AppSignal-supported operating system
- An AppSignal account
- Basic Django knowledge
Project Setup
We'll be working on a movie review web app. The app will allow us to manage movies and reviews via a RESTful API. To build it, we'll utilize Django.
I recommend you follow along with the movie review web app first. After you grasp the basic concepts, using AppSignal with your projects will be easy.
Begin by creating and activating a new virtual environment, installing Django, and bootstrapping a new Django project.
If you need help, refer to the Quick install guide from the Django docs.
Note: The source code for this project can be found on the appsignal-django-error-tracking GitHub repo.
Install AppSignal for Django
To add AppSignal to a Django-based project, follow the AppSignal documentation:
To ensure everything works, start the development server. Your Django project will automatically send a demo error to AppSignal. In addition, you should receive an email notification.
From now on, all your app errors will be reported to AppSignal.
App Logic
Moving along, let's implement the movie review app logic.
You might notice that some code snippets contain faulty code. The defective code is placed there on purpose to later demonstrate how AppSignal error tracking works.
First, create a dedicated app for movies and reviews:
Add the newly-created app to INSTALLED_APPS
in settings.py:
Define the app's database models in models.py:
What's Happening Here?
- We define two models,
Movie
andMovieReview
. AMovie
can have multipleMovieReview
s. Both models include aserialize_to_json()
method for serializing the object to JSON. - The
Movie
model includesget_average_rating()
for calculating a movie's average rating. MovieReview
'srating
is locked in a[1, 5]
interval via the modifiedsave()
method.
Now, make migrations and migrate the database:
Define the Views in Python
Next, define the views in movies/views.py:
What's Happening Here?
- We define three views:
index_view()
,statistics_view()
, andreview_view()
. - The
index_view()
fetches all the movies, serializes them, and returns them. - The
statistics_view()
calculates and returns the average rating of every movie. - The
review_view()
allows users to create a movie review by providing the movie ID and a rating.
Register the URLs
The last thing we must do is take care of the URLs.
Create a urls.py file within the movies
app with the following content:
Then register the app URLs globally:
Using Fixtures
To get some test data to work with, I've prepared two fixtures.
First, download the fixtures, create a fixtures folder in the project root, and place them in there:
django-error-tracking/ +-- fixtures/ +-- Movie.json +-- MovieReview.json
After that, run the following two commands to load them:
We now have a functional API with some sample data to work with. In the next section, we'll test it.
Test Your Django App's Errors with AppSignal
During the development of our web app, we left intentional bugs in the code. We will now deliberately trigger these bugs to see what happens when an error occurs.
Before proceeding, ensure your Django development server is running:
Your API should be accessible at http://localhost:8000/movies.
AppSignal should, of course, be employed when your application is in production rather than during development, as shown in this article.
Error 1: ZeroDivisionError
Start by visiting http://localhost:8000/movies/statistics in your favorite browser. This endpoint is supposed to calculate and return average movie ratings, but it results in a ZeroDivisonError
.
Let's use AppSignal to figure out what went wrong.
First, navigate to your AppSignal dashboard and select your application. On the sidebar, you'll see several categories. Select "Errors > Issue list":
You'll see that a ZeroDivisionError
has been reported. Click on it to inspect it.
The error detail page displays the error's summary, trends, state, severity, etc. But we are interested in the samples. Select the "Samples" menu item in the navigation bar to access them.
A sample refers to a recorded instance of a specific error. Select the first sample.
The sample's detail page shows the error message, what device triggered the error, the backtrace, and more. We can look at the backtrace to determine what line of code caused the error.
In the backtrace, we can see that the error occurred in movies/models.py on line 16
. Looking at the code, the error is obvious: if a movie has no reviews, this results in a division by zero.
To fix this error, all you have to do is slightly modify the Movie
's get_average_rating()
method:
Reload the development server, test the functionality again, and set the error's state to "Closed" if everything works as expected.
Error 2: ValueError
We can trigger another error by submitting a review with a rating outside the [1, 5]
interval. To try it out, open your terminal and run the following command:
As expected, a ValueError
is reported to AppSignal. To track the error, follow the same procedure as in the previous section.
The error can be easily fixed by adding a check to review_view()
in views.py:
After that, test the functionality again and tag the error as "Resolved" if everything works as expected.
Wrapping Up
In this article, you've learned how to use AppSignal to track errors in a Django application.
To get the most out of AppSignal for Python, I suggest you review the following two resources:
Happy coding!
P.S. If you'd like to read Python posts as soon as they get off the press, subscribe to our Python Wizardry newsletter and never miss a single post!