I wanted to write a function that takes the generated url for each device and converts it to a qr code. this function should be called in add_new_device after url is created. My code is like this, it's not adding device at the moment.
def add_new_device(self, request):
user = User.objects.get(username=request.data["username"])
# last num of device to add in device_id
last_number = len(Device.objects.all())
device = Device()
device = self.write_fields_to_object(device, request.data, user)
device.device_id = self.random_string_generator() + \
'-' + str(int(last_number) + 1)
device.save()
# Creates new station data added for the device
self.set_station_data(request.data, device)
if device.VMIscreen == "true":
# Creates VMI screen automatically for url
self.auto_create_new_layout(request, device)
else:
# Creates epmtpy screen for url
empty_layout = Layout()
self.create_url(empty_layout, device)
self.create_qr(device)
# Create Event object
self.create_notification(
user, device, "add", "device", "has added new Device")
return "ok"
def create_qr(self, device):
qr_content = device.screen_url
qr_name = f'qr_{device.device_id}.png'
qr = make(qr_content)
qr.save('media/' + qr_name)
def create_url(self, layout, device):
screen_url = base_screen_url + device.device_id + ".html"
Device.objects.filter(device_id=device.device_id).update(
screen_url=screen_url)
html = self.edit_device_url_html(layout, device)
s3.put_object(Bucket=device_url_bucket, Key=str(device.device_id) + ".html", Body=html, ACL='public-read',
ContentType='text/html', CacheControl='no-cache, no-store, must-revalidate')
Actually, I would not create a QR code for the Device
s, at least not proactively.
We can construct such QR code on demand, in a view where we want to obtain the QR code. Indeed, such view would look like:
from io import BytesIO
from django.http import HttpResponse
from qrcode import make
from qrcode.image.svg import SvgPathImage
def qr_code_for_device(request, pk):
device = get_object_or_404(Device, pk=pk)
buffer = BytesIO()
image = make(device.screen_url, image_factory=SvgPathImage)
image.save(buffer)
return HttpResponse(buffer.getvalue(), content_type='image/svg+xml')
when visiting the view thus for a certain device, it will return an SVG image with the QR code for the screen_url
of that device.
If later the screen_url
of the device changes, requesting the qr code with a new request will thus render a QR code with the updated screen_url
. It will also save a lot of diskspace, since the images generated only exist in memory until the response is send. Finally performance is likely not an issue here, since QR codes are generated quite efficiently, and actually opening and loading the file to send this as a response is probably comparable in terms of performance, but very likely not that much more efficient.