How it works...

Responsive images are powerful and, at their base, are concerned with providing different images based on media rules that indicate the features of the displays upon which each image will be shown. The first thing we did here was to add the django-imagekit app, which makes it possible to generate the different images that are needed on the fly.

Obviously, we also will need the original image source, so in our Location model, we added an image field called picture. In the upload_to() function, we built the upload path and filename out of the current year and month, the UUID of the location, and the same file extension as the uploaded file. We also defined the image version specifications there as follows:

  • picture_desktop will have the dimensions of 1,200 x 600 and will be used for the desktop layout
  • picture_tablet will have the dimensions of 768 x 384 and will be used for tablet
  • picture_mobile will have the dimensions of 640 x 320 and will be used for smartphones

In the delete() method of the location, we check whether the picture field has any value and then try to delete it and its image versions before deleting the location itself. We use the contextlib.suppress(FileNotFoundError) to silently ignore any errors if a file was not found on the disk.

The most interesting work happens in the template. When a location picture exists, we construct our <picture> element. On the surface, this is basically a container. In fact, it could have nothing inside of it besides the default <img> tag that appears at the end in our template, though that would not be very useful. In addition to the default image, we generate thumbnails for other widths—480 px and 768 px—and these are then used to build additional <source> elements. Each <source> element has the media rule with the conditions under which to select an image from the srcset attribute value. In our case, we only provide one image for each <source>. The location detail page will now include the image above the map and should look something like this:

When the browser loads this markup, it follows a series of steps to determine which image to load:

  • The media rules for each <source> are inspected in turn, checking to see whether any one of them matches the current viewport
  • When a rule matches, the srcset is read and the appropriate image URL is loaded and displayed
  • If no rules match, then the src of the final, default image is loaded

As a result, smaller images will be loaded on smaller viewports. For example, here we can see that the smallest image was loaded for a viewport only 375 px wide:

For browsers that cannot understand the <picture> and <source> tags at all, the default image can still be loaded, as it is nothing more than a normal <img> tag.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.39.23