A QR code generator in Django

Posted on 30 July 2023

The following code is the views.py file for the make_qr app behind this QR code generator app. The qrcode Python package generates a Pillow Image object, which is encoded in base-64 for rendering in the template, saving the need for an intermediate PNG file.

from django.shortcuts import render
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
import qrcode
from PIL import Image
import base64
from io import BytesIO

def home(request):
    """The view function handling QR code generation."""

    url = request.GET.get('url')
    if not url:
        # The user hasn't entered a URL yet: render an empty form.
        return render(request, 'make_qr/make_qr.html', {})

    c = {'url': url}

    # Validate the URL to make sure it's well-formed. NB this means it
    # must include the protocol identifier prefix, e.g. 'https://', etc.
    val = URLValidator()
    try:
        val(url)
    except ValidationError:
        # Not a valid URL: render the page with an error message.
        c['status'] = 1
        return render(request, 'make_qr/make_qr.html', c)

    # Make the QR code image
    qr_img = qrcode.make(url)

    # Now convert the image into a base 64 encoded string so it can
    # be rendered directly in the HTML page without us having to save
    # an intermediate PNG file.
    output = BytesIO()
    qr_img.save(output, format='PNG')
    output.seek(0)
    output_s = output.read()
    b64 = base64.b64encode(output_s)
    # We have to decode to remove the b prefix and quotes.
    c['qr_b64'] = b64.decode()

    return render(request, 'make_qr/make_qr.html', c)