繁体   English   中英

使用 Django 刷新页面而不重新加载

[英]Refresh a page without reloading with Django

我正在制作一个系统来通过 Django 的 QR 码检测存在,我需要一种在检测到 QR 码时显示图像和文本而无需重新加载页面的方法,我看到了一些关于 HTMX 但我做不到很多。 互联网上没有太多关于使用 if 语句来执行此操作的内容。

视图.py

from datetime import datetime
from django.http import JsonResponse, StreamingHttpResponse
from django.shortcuts import render
import cv2
import numpy as np
from pyzbar.pyzbar import decode
from django.views.decorators import gzip
from .models import *

def camera_feed(request):
    stream = CameraStreamingWidget()
    frames = stream.get_frames()
    return StreamingHttpResponse(frames, content_type='multipart/x-mixed-replace; boundary=frame')

class CameraStreamingWidget:
    def __init__(self):
        self.camera = cv2.VideoCapture(int(os.environ.get('CAMERA')))
        self.media_path = os.path.join(os.getcwd(), "media", "images")
        
        # create "media/images" folder if doesn't exist
        if not self.media_path:
            os.mkdir(self.media_path)

    def get_frames(self):
        while True:
            # Capture frame-by-frame
            success, frame = self.camera.read()
            if not success:
                break
            else:
                ret, buffer = cv2.imencode('.jpg', frame)
                
                # Add text on top of the barcode if there is a barcode in the stream using opencv
                # convert camera frame to numpy array
                color_image = np.asanyarray(frame)

                # decode numpy array to check if there is a barcode in color_image
                # you can add a custom check here to verify if the qr code has right identifier information
                if decode(color_image):
                    for barcode in decode(color_image):
                        barcode_data = (barcode.data).decode('utf-8')

                        print(barcode_data)
                        # if barcode data exists
                        if barcode_data:

                            '''# save file as PNG if a QR code is detected
                            image = os.path.join(self.media_path, f"{barcode_data}.png")
                            cv2.imwrite(image, frame)
                            
                            # print info for debugging purpose
                            print('-'*50)
                            print('Saving image to media...')
                            print('-'*50)
                            print(f'Saved as: {image}')
                            print('-'*50)'''
                            
                            pts = np.array([barcode.polygon], np.int32)
                            pts = pts.reshape((-1,1,2))
                            # draw polylines on the barcode
                            cv2.polylines(
                                img=color_image,
                                pts=[pts],
                                isClosed=True,
                                color=(0,255,0),
                                thickness=3
                            )
                            pts2 = barcode.rect
                            # put text on top of polylines
                            barcode_frame = cv2.putText(
                                img=color_image,
                                text=barcode_data,
                                org=(pts2[0], pts2[1]),
                                fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
                                fontScale=0.1,
                                color=(0,0,255),
                                thickness=2
                            )
                            # encode the new barcode_frame that has polylines and barcode data text
                            _, buffer_ = cv2.imencode('.jpg', barcode_frame)
                            # convert barcode_frame to bytes
                            barcode_frame = buffer_.tobytes()
                            # yield output stream with polylines and barcode data text
                            yield (b'--frame\r\n'
                                b'Content-Type: image/jpeg\r\n\r\n' + barcode_frame + b'\r\n\r\n')
                # else, yield the normal camera stream
                else:
                    frame = buffer.tobytes()
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')



def detect(request):
    stream = CameraStreamingWidget()
    success, frame = stream.camera.read()
    if success:
        status = True
    else:
        status = False

    return render(request, 'detect_barcodes/detect.html', context={'cam_status': status})

HTML 模板

{% extends '../base.html' %}

{% load static %}

{% block content %}
<div class="row">
    <h2>Sistema de Presença de Aluno por QR Code</h2>
    <hr />
    <div class="col-md-6">
        {% if cam_status %}
        <h3>Status do fluxo da câmera: Ligada</h3>
        <img src="{% url 'camera_feed' %}" style="width: 540px; height: 400px;" />
        {% else %}
        <h3>Status do fluxo da câmera: a câmera não está acessível ou está ocupada</h3>
        <h5>Coisas para checar: </h5>
        <ul class="text-right list-inline">
            <li>Conexão USB?</li>
            <li>Número da câmera em seu arquivo .env?</li>
            <li>A câmera já está em uso?</li>
        </ul>
        {% endif %}
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<script>
    $("#btn_ReadQRCode").on("click", function (e) {
        console.log("Ajax request triggered.");
        e.preventDefault();
        $.ajax({
            type: "POST",
            url: "{% url 'camera_feed' %}",
            data: {
                csrfmiddlewaretoken: "{{ csrf_token }}",
                dataType: "json",
            },
            success: function (data) {
                if (data.barcode_data !== null && data.barcode_data !== '') {
                    console.log(data);
                    $("#txt_BarcodeData").html(data.barcode_data);
                    $("#lbl_LastModified").html(
                        "Last modified at: " + data.file_saved_at
                    );
                } else {
                    console.log(data);
                    $("#txt_BarcodeData").html("");
                    $("#lbl_LastModified").html("<h3><em>No data or file not found. Scan barcode again.</em></h3>");
                }
            },
            error: function () {
                console.log(error);
            }
        });
    });
</script>
{% endblock content %}

(抱歉我的英语不好,我用的是翻译器)

您最好使用Ajax + Javascirpt/JQuery查看 POSTing forms ,这将允许您提交表单并刷新。

不过,我不能 100% 确定您将如何返回 Ajax 中的图片。

我以前使用过条形码,我所做的是在文件夹static/barcodes/encoded_barcode_text.png中生成它们,然后使用 URL 使用图像标签为它们提供服务。 然后你可以在某个时候运行一个 Cron/Scheduled Task 来清除那个目录

您可以使用django 通道使用 javascript websocket 内置库与服务器建立异步连接,您可以通过此文档阅读更多信息,了解 javascript

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM