Django Raspberry Pi 3
Hello! This post is part of a series on building a Django app and deploying it on my Raspberry Pi. You may want to start with the first post in the series.
Last time, we got the web server to actually send requests to the django process, but it doesn’t serve static assets or have a database yet. Let’s check on the original checklist!
- Get our python code onto the Pi. DONE :)
- Get the dependencies installed on the Pi. DONE :)
- Configure apache webserver to forward requests to django. ALMOST!
- Set up a database
- Probably other things I haven’t thought of yet.
I visit the site in Firefox and open the dev tools. I see that the site tries to download all the static assets, but gets 404s. So the HTML references the static assets, but were not serving them correctly from the server. So this is still an apache2 problem, a django problem or an “apache2 not talking to django” problem.
To try to diagnose this, I ssh into the Pi and tail the apache server logs. I see a lot of errors in the logs like this:
192.168.0.34 - - [19/Jun/2023:18:32:12 +0000] "GET
/static/admin/js/nav_sidebar.js HTTP/1.1" 404 496
"http://192.168.0.105/admin/login/?next=/admin/" "Mozilla/5.0 (Macintosh; Intel
Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/113.0"
Ok, so we’re looking for a file called nav_sidebar.js
and not finding it. A
reasonable question to ask is, “is this file on my server and if so where.” So
let’s check!
$ find . -name nav_sidebar.js
./djenv/lib/python3.9/site-packages/django/contrib/admin/static/admin/js/nav_sidebar.js
That makes sense! I’m trying to view the admin page, which I didn’t build, and
is part of django itself. So the static assets for it are in the directory
where pip
put all the django stuff when I did python -m pip install .
.
After looking around for a while, I realized that I was missing a setting, and
a django command. First off, I was missing STATIC_ROOT
:
@@ -127,6 +127,7 @@ USE_TZ = True
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = "static/"
+STATIC_ROOT = path.join(BASE_DIR, "static")
I was surprised to need both these settings, so let’s figure out what the difference is! This post gives a pretty clear explanation, if you want to read more, but basically:
STATIC_URL
: the URL (or path) that clients should download static assets from.STATIC_ROOT
: the directory on the host wherecolllectstatic
should put things.
And, to get this going on the server, I need to run colllectstatic
:
python manage.py collectstatic
Now if I re-run the find command:
$ find . -name nav_sidebar.js
./djenv/lib/python3.9/site-packages/django/contrib/admin/static/admin/js/nav_sidebar.js
./static/admin/js/nav_sidebar.js
You can see that the static assets from the django package got moved to
./static
relative to my site root.
Let’s make sure that apache2 is configured to serve those:
<VirtualHost *:80>
# ... snip ...
Alias /static /home/pi/pidjango/static
<Directory /home/pi/pidjango/static>
Require all granted
</Directory>
# ... snip ...
</VirtualHost>
Looks good! And, sure enough, when I visit the browser now, I get nice layouts
and such on /admin
because the static assets are working.
Next time, we’ll try to set up the database!
Till then, happy learning!
–Will
Love this post? Hate it? Is someone wrong on the internet? Is it me? Please feel free to @me on mastodon
I used to host comments on the blog, but have recently stopped. Previously posted comments will still appear, but for new ones please use the mastodon link above.
Discussion