Working on Django projects I find very often that many developers access the values that are defined in settings in this way
from django.conf import settings
my_value = settings.MY_SETTING
What happens if MY_SETTING has not been defined in settings.py? The code will raise an error and crash, of course. How can we make the code more reliable? We could try/except the code block that tries to read the value and maybe set a value if we get an exception, but this would not be a clean way to do this job.
A cleaner way to do it is to use getattr in this way:
from django.conf import settings
my_value = getattr(settings, 'MY_SETTING', 'my-default-value')
getattr will try to read MY_SETTING value from settings.py, if the value doesn’t exist my_value will be assigned with my-default-value.
To understand how a Django Middleware works we need to remember that the basic architecture of Django is composed by a request and a response. A middleware is something that stays in the middle. Let’s give a look to the next diagram, taken from official Django documentation:
Important things to know
There are four important things to know about middlewares:
- You need to write a class that just inherit from object
- The order where you place your middleware in settings.py is important: middlewares are processed from top to bottom during a request and from bottom to top during a response.
- You don’t need to implement all the available methods of a middleware. For example you can just implement process_request and process_template_response
- If you implement process_request and you decide to return an HttpResponse, all the other middlewares, views etc… will be ignored and only your response will be returned
Writing a middleware
In my example I wanted to implement a feature that saves the time when a request is made and the time when a request has been processed, then calculates the time delta and exposes this value in the context so that is accessible from our templates. How to implement a similar feature using a middleware? Here is my example:
from datetime import datetime
def process_request(self, request):
request._request_time = datetime.now()
def process_template_response(self, request, response):
response_time = request._request_time - datetime.now()
response.context_data['response_time'] = abs(response_time)
Please don’t care about how I calculated the time. I’m aware that there are better ways to do it, but I just wanted to keep it simple and show how to implement a simple middleware.
If you want to see a complete example of a project that includes and uses this middleware, here you can find the complete source code: https://github.com/andreagrandi/benchmark-middleware-example
I must admit it, there was a time when I was not using HTTPS, not even to protect the admin section of the website. This means that anyone could have intercepted the password and published (or deleted) things in my name. Since a couple of years ago I started protecting my admin sectio using an SSL certificate. I haven’t done it before for a couple of reason: my hosting was on a provider that required a lot of money (something like 100$/year) to enable SSL support, plus an SSL certificated costed at least 100-120$/year.
When I migrated my website on my own VPS on DigitalOcean I finally discovered that StartSSL was giving free class 1 certificates and I immediately got one. I made the mistake to just serve the admin pages using HTTPS, not all the website. I regretted about this decision after readin a couple of articles that were explaining how some internet providers where changing served HTTP pages injecting their own ads or banner. That was unacceptable to me and I swicthed the whole website to HTTPS.
Basically, if you don’t serve even your personal website using HTTPS, someone could change the page while it’s being transfered to the requester. Imagine if you have (like me) a page on your blog that let people download your public PGP key. Users could be served with a different key, so someone else would be able to decrypt a message intended for you only. Scary, isn’t it?
If you need more informations about how to request a StartSSL certificate and how to install it on Nginx/Apache, I can suggest this nice tutorial: https://konklone.com/post/switch-to-https-now-for-free
If you need to serve a WordPress website, that configuration is not enough. In that case you may want to have a look at my own Nginx configuration, available at this address: https://gist.github.com/andreagrandi/5de9dc9c4eb7e732764c
p.s: if you are you curious to try how Digital Ocean VPS works and fancy 10$ credit (enough for 2 months if you choose the basic droplet) for free, use this link and enjoy it https://www.digitalocean.com/?refcode=cc8349e328a5
This won’t be a full post, but just a quick note (probably the first one of a serie) about development with Django.
When we write a TestCase test, if we have defined a setUp method, it will be called before the execution of each test. One could think that the database is completely reset after each test, but this is not true (not like I was thinking). After each test, whatever we wrote on the database is rolled back. If we create a “Client” row (assuming we have a model called Clients) in our setUp, when we call it the second time the ID won’t be 1 as someone (me included) could expect. It will be 2 instead, because the database has not completely deleted and created from scratch.
This means that we can’t assume that our Client ID will always be 1 for each test and we should rather reference to it in a dinamic way like: self.client.id
This could be a trivial thing for many people but I was not 100% sure about this so I asked for a confirmation on #django IRC room and people (expecially apollo13) was kind enough to explain me how it works.
I’m a big fan of Soma.fm (a 25+ channels streaming radio based in San Francisco) and during the years I’ve been writing clients for this radio for different mobile platforms (Maemo, MeeGo, Harmattan, Windows Phone, BlackBerry 10, Jolla). I love in particular their “Indie Pop Rock” channel that during these years made me discover some very good artists.
When Spotify finally was available in Italy (I’m still using it right now that I live in the UK), something that I always missed was a radio with the same good music. Why not just listening to Soma.fm? Because I like to listen to the music while I commute and in the London Underground it’s nearly impossible to have signal.
So I was thinking: it would be nice to have a Spotify playlist with Soma.fm tracks. Wait a moment…. I can do it!
Soma.fm publishes the tracks history with all the tracks streamed during the last hour http://somafm.com/indiepop/songhistory.html so I just needed something to parse this list for me and return me a well formatted version.
Thanks to import.io (it’s a service that takes a web page as input, parse the data and generates a RESTful API to access this data) I was able to easily get the data I needed. At this point I only needed to be able to loop through the list, search each track on Spotify and add it to my playlist.
The source code is fully available here https://github.com/andreagrandi/spotisoma
Note: you can’t just get the code and run it. You will need to get your own import.io api key, generate your import.io api url, get a Spotify application key (the old/deprecated one, since it was nearly impossible for me to use oauth in a simple Python script due to the fact I didn’t have an endpoint to receive the token back. You can get more informations here: https://pyspotify.mopidy.com/en/latest/quickstart/#application-keys ) and set your env variables with your Spotify username and password. Last but not least: the old Spotify library only works with Premium accounts.