如何使用 AJAX 或类似的东西在 Django 中使用 Python 脚本?
Posted
技术标签:
【中文标题】如何使用 AJAX 或类似的东西在 Django 中使用 Python 脚本?【英文标题】:How to use Python script in Django using AJAX or something like that? 【发布时间】:2018-09-25 05:12:00 【问题描述】:我正在开发一个物联网项目,例如学校和大学的智能考勤和无现金支付系统。我使用 Raspberry Pi 3 作为我的客户端机器和 DigitalOcean 来托管 PostgreSQL 和核心 Django 项目。除了 Raspberry Pi,我还在使用 EM-18 RFID 阅读器和 R305 指纹阅读器。现在,到现在为止,我已经构建了一个 CLI 实用程序来使用项目,但对于一个不熟悉 Linux 或一般 shell 的人来说,它并不是很方便。
现在我的问题在于我当前的代码逻辑。例如,如果我想将学生信息连同他们的 RFID/指纹信息一起添加到数据库中,我首先扫描分配给他们的 RFID 标签。检查该标签是否已经在数据库中,如果没有,则询问他们的信息。在这一步之后,我再次要求他们再次点击同一张卡以注册他们的指纹。所有这些过程都可以在 CLI 上正常工作。我无法弄清楚如何让操作员知道现在要执行哪个步骤。虽然我在 Django 中构建了一个 Web 界面,但它既不友好也不交互。我想我必须使用 JSON/AJAX 来做到这一点,但我不知道该怎么做。
【问题讨论】:
【参考方案1】:我终于明白了。我已将过程分为多个部分。然后我调用 AJAX 来访问它。
我的urls.py
文件:
from django.conf.urls import url
from .views import tag, check_tagid, scan_tag
urlpatterns = [
url(r'^tag/', tag, name="tag"),
url(r'^check_tagid/', check_tagid, name="check_tagid"),
url(r'^scan_tag/', scan_tag, name="scan_tag"),
]
我的views.py
文件:
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from .models import Student
import serial
def check_tagid(request):
"""Check if scanned tag id is already associated or not"""
tagid = request.GET.get('tagid', None)
if Student.objects.filter(tag_id__iexact=tagid).exists():
data =
'is_taken': Student.objects.filter(tag_id__iexact=tagid).exists(),
'student': Student.objects.get(tag_id=tagid).name
else:
data =
'is_taken': Student.objects.filter(tag_id__iexact=tagid).exists(),
return JsonResponse(data)
def scan_tag(request):
"""Function to check if tag is scanned or not"""
if request.is_ajax():
## Init RFID reader
data = serial.Serial(
port='/dev/ttyUSB1',
baudrate = 9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
context = 'tagid': data.read(12).decode("utf-8")
return JsonResponse(context)
else:
return HttpResponse("This route only handles AJAX requests")
def tag(request):
return render(request, 'students/tag.html', )
我的tag.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<center><h1><div id="tag_id">Scanning for tag</div></h1></center>
<div id="if_exists"></div>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
$.get("/scan_tag/", function(data)
console.log(data.tagid);
var x = document.createElement("INPUT");
x.setAttribute("id", "tag_id_in");
x.setAttribute("type", "hidden");
x.setAttribute("value", data.tagid);
document.body.appendChild(x);
// check tag
tagid = $("#tag_id_in").val();
console.log(tagid);
$.ajax(
type: "GET",
url: "% url 'check_tagid' %",
data:
'tagid': tagid
,
success: function(data)
if (data.is_taken)
document.getElementById('tag_id').innerHTML = "Welcome "+data.student;
else
document.getElementById('tag_id').innerHTML = "No student with this tag id found";
);
);
);
</script>
</body>
</html>
所有这些现在都按预期工作。
所以,/tag/
是主要入口点。现在在tag.html
中,我在/scan_tag/
上使用jQuery get
方法。它将返回 RFID 标签号。然后我在/check_tagid/
上调用 AJAX,它的真/假取决于学生是否在数据库中。
【讨论】:
对不起,我完全忘记了这个问题,很高兴你能自己解决。并使用“filter.exsist()”而不是“get()”来避免“尝试/期望”。如果您正在寻找进一步的改进:“data = serial.Serial(...”似乎是错误的,因为您每次调用函数时都会对其进行初始化。这应该是全局 IMO。您还可以将 jQuery ajax 调用转换为 nativ XMLRequest 到摆脱 jQuery 开销。 @hansTheFranz 非常感谢您的回复!我尝试将“data = serial.Serial(...”设置为全局,但似乎没有扫描 RFID 标签。此外,我猜将其设置为非全局会节省电力,因为它需要 12V。我对此一无所知原生 XMLRequest。你能给我推荐一个很好的参考吗?我找到了this 再次感谢你的建议!【参考方案2】:请不要将其视为答案,而更像是更长的评论;)
所以首先阅读 MVC 概念(例如:https://djangobook.com/model-view-controller-design-pattern/)以了解 Web 界面如何与其余代码交互。
经典的 django 方式是
-
根据您的
model
创建一个form
(在forms.py
中)。
你会写一些 html 来在网站上显示表单
验证views.py
中的表单输入
发回结果并显示它们(同样是 html)
如果您想使用 AJAX 进行此操作,则需要做一些额外的工作,但结果是值得的。 (例如:How to POST a django form with AJAX & jQuery)
您将调用您首先在urls.py
文件中初始化的特定网址(在 django 2.0 中为path('checkForm', views.checkForm, name='checkForm'),
)
url 指向在views.py
中定义的函数,名称为checkForm
(与本示例中的url 路径相同,但您可以随意调用它)。在这个函数中,您可以编写您的 python 代码或从那里调用函数来执行您的数据库查询、验证等。
发回带有代码结果的响应。
success: function(data, status)
$('#whatever').html(data);
alert("whatever");
“data”在这里是来自服务器的响应。 我希望我给了你一个正确方向的提示。请问您是否卡在某个地方。
附言我不知道如何通过 http 发送指纹数据,检查是否有一些库。
x=data.read(12).decode("utf-8")
tag_id_in = x
这是不好的代码,请去掉 x。第一个 x 是一个错误的变量名,第二个是完全多余的。
您还希望将您的 print
语句转换为 logs
或其他任何内容,但打印不会让您走得太远。
【讨论】:
这真的很有帮助,我已经按照你的建议更新了我的代码。看我的views.py here。现在我得到了 RFID 标签数据,它也被提交到数据库,但我的问题是我没有得到HttpResponse("Form submitted")
。它只是重新开始阅读标签。我希望它只是一次性的过程。另外,建议更好的代码实践来消除“try except block”。提交表单后,我不知道为什么必须扫描我的标签才能提交数据并显示 HttpResponse。以上是关于如何使用 AJAX 或类似的东西在 Django 中使用 Python 脚本?的主要内容,如果未能解决你的问题,请参考以下文章
Django - 如何使用 JQuery Ajax 插入多个表单数据