Blog postings
Did 7.73km in 55:04 which is a bit faster than the other day. Also there are altocumuli in the sky. Nice.

Long ago, when Netscape 4 and IRIX were still relevant, I had a dumb website that had a Favourites Icon. The wee image you see in tabs or favourites. Back in those halcyon days you used a program to make a Windows icon file, call it favicon.ico, and dump it in the root directory of your website.
Ha.
These days that still works but the low res Windows 3.0 file icons look bad essentially everywhere. Plus now every device has several zillion custom icons it looks for. And a JSON file it can use to discover icons.
This isn't really too bad to deal with. Apple devices look for a apple-touch-icon relation (180x180px). Other platforms look for a range of size options which you specify as icon relations. The old school favicon.ico can be put in (outside of root as a relation). Finally the JSON file can be put in.
Phew.
I used the sunshine emoji as the base for this, generated using a helpful emoji to favicon webapp with the graphics done by Twemoji (part of Twitter). Thanks, Elon!
First time in a while so my pace was poor although I did go the distance. Only walked for a wee bit up the hill. Quanta: 7.76km in 56 min (yikes). Want to get to 5 min. Will take some time I think!
Anyway. Here is an image. Some interesting cloud formations if nothing else!
Essentially all article postings have the following in it:
<link rel="canonical" href="path/to/here" />
Let's see if the bots like it
I updated to Django 4.0 and noticed that the custom DeleteView delete() function I had written to deal with comment deletions was no longer being called. Urgh. There was in the logs the rather cryptic message
DeleteViewCustomDeleteWarning: DeleteView uses FormMixin to handle POST requests. As a consequence, any custom deletion logic in CommentDeleteView.delete() handler should be moved to form_valid().
This turned out to be exactly what I needed to do. I had a def delete(self, request, *args, **kwargs): override that returned HttpResponseRedirect(self.get_success_url()). Changing the function signature to def form_valid(self,form): was all I needed to do. How about that.
For completeness, I show the amended soft delete function below. This was called delete() prior to 4.0.
def form_valid(self,form):
self.object = self.get_object()
self.object.is_deleted = True
self.object.save()
return HttpResponseRedirect(self.get_success_url())
Two ways of handling this. You can define your queryset to filter out is_deleted = True (so your rendering layer can pretend it doesn't exist), or you can skip over the items in the queryset when rendering.