簡體   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