python - 如何将ajax添加到django网页
问题描述
我正在开发一个 django 应用程序。此应用程序有两种形式。在第一个表单 ( image_form ) 中,用户可以上传图像。在第二种形式(image_description)中,用户可以填写一些关于图像的描述。当图像以第一种形式上传时,图像上运行的图像分类器会尝试填充 image_description 表单的部分内容。提交第二个表单后,该项目将显示在新页面 ( item_list ) 中。这是应用程序的 urlpatterns。
网址.py
urlpatterns = [
path('', views.index, name='home'),
path('accounts/', include('django.contrib.auth.urls')),
path('signup/', views.signup, name='signup'),
path('items/', views.item_list, name='item_list'),
path('items/upload/description/', views.upload_item, name='upload_item'),
path('items/<int:pk>/', views.delete_item, name='delete_item'),
path('items/upload/image_classification/', views.image_classification, name='image_classification'),
]
这里的item_list是显示所有项目的页面。提交 image_description 表单后,将显示此页面。
upload_item页面包含这两种形式。
image_classification在第一个表单中的上传图片按钮被点击时运行。这发生在 upload_item 页面中。
视图.py
def item_list(request):
items = Item.objects.all()
return render(request, 'item_list.html', {'items':items})
def upload_item(request):
if request.method == 'POST':
form_des = ItemForm(request.POST, request.FILES)
if form_des.is_valid():
form_des.save()
return redirect('item_list')
else:
form_des = ItemForm()
return render(request, 'upload_item.html', {'form_des': form_des})
def image_classification(request):
form_des = ItemForm()
if request.method == 'POST':
if 'file' in request.FILES:
handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))
img = np.expand_dims(cv2.resize(cv2.imread(os.path.join('./media/item/img/', str(request.FILES['file']))), (170, 100)), axis=0)
cat_prediction = cat_classifier.predict_classes(img)[0]
pattern_prediction = pat_classifier.predict_classes(img)[0]
form_des.fields['title'].widget.attrs['value'] = cat_prediction
form_des.fields['pattern'].widget.attrs['value'] = pattern_prediction
form_des.fields['user'].widget.attrs['value'] = request.user
form_des.fields['user'].widget.attrs['readonly'] = True
return render(request, 'upload_item.html', {'form_des': form_des})
else:
return redirect('upload_item')
upload_item.html 模板
<div class="container">
<div class="row justify-content-center">
<div class="col-7">
<center>
<h2>Upload image</h2>
<!-- <div class="row justify-content-center"> -->
<div class="upload-btn-wrapper">
<form action="{% url 'image_classification' %}" method="POST" enctype="multipart/form-data" data-url="image_classification/" class="my_form">
{% csrf_token %}
<input type="file" name="file" id="file" class="inputfile" multiple/>
<label for="file" class="btn btn-outline-dark btn-lg mt-5 select">Choose a file</label>
<input class='btn btn-primary btn-lg btn-block upload_image_button' type="submit" value="Upload image" disabled/>
</form>
</div>
<!-- </div> -->
<center>
<p class='font-weight-bold mt-5 mb-5 text-danger'>Step: 1 of 2</p>
</center>
<div class="separation"></div>
<h2>Item description</h2>
</center>
<div class="card mb-2 mt-3">
<div class="card-body">
<form method="post" enctype="multipart/form-data" action="{% url 'upload_item' %}" id='item_des'>
{% csrf_token %}
{{form_des.title|as_crispy_field}}
{{form_des.pattern|as_crispy_field}}
{{form_des.color|as_crispy_field}}
{{form_des.user|as_crispy_field}}
<button type="submit" class='btn btn-primary btn-lg btn-block save_btn'>Save item</button>
</form>
</div>
</div>
<center>
<p class='font-weight-bold mt-2 mb-5 text-danger'>Step: 2 of 2</p>
</center>
</div>
</div>
</div>
我的问题是,当在第一个表单中单击上传图片按钮时,url 会从items/upload/description/
to更改,items/upload/image_classification/
并且页面会重新加载第二个表单中的自动填充部分。
我想使用 AJAX 自动填写第二个表单而不重新加载页面,但不知道该怎么做。我遵循了一些教程,但无法做到这一点。
请帮我
谢谢
[EDIT1] 根据 Adeel Siddiqui 的回答,我对views.py进行了一些更改
视图.py
def image_classification(request):
form_des = ItemForm()
user =str(request.user)
if request.method == 'POST':
if 'file' in request.FILES:
handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))
img = np.expand_dims(cv2.resize(cv2.imread(os.path.join('./media/item/img/', str(request.FILES['file']))), (170, 100)), axis=0)
cat_prediction = cat_classifier.predict_classes(img)[0]
pattern_prediction = pat_classifier.predict_classes(img)[0]
form_des.fields['title'].widget.attrs['value'] = cat_prediction
form_des.fields['pattern'].widget.attrs['value'] = pattern_prediction
form_des.fields['user'].widget.attrs['value'] = request.user
form_des.fields['user'].widget.attrs['readonly'] = True
context = {
'tops_prediction' :tops_prediction,
'pattern_prediction':pattern_prediction,
'user' :user,
}
return HttpResponse(json.dumps(context))
else:
return redirect('upload_item')
如何从jquery 中的fillImageDescriptionText访问此上下文并在 upload_item 页面中自动填写第二个表单?
解决方案
您可以防止在提交表单时发生默认事件。假设您的图像分类表单具有 id image-classify-form,则:
$("#image-classify-form").submit(function(event) {
event.preventDefault();
imageClassifyAjax();
}
您的 imageClassifyAjax 函数在哪里执行此操作(我之前忘记在第 2 行创建 FormData 对象,这导致 POST 请求失败):
function imageClassifyAjax() {
let $form = $("#image-classify-form");
let form_data = new FormData($form[0]);
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: form_data,
processData: false,
contentType: false,
dataType: 'json',
success: function (data) {
fillImageDescriptionText(data);
},
error: function (xhr) {
console.log("Something went wrong: " + xhr.responseText);
}
});
}
fillImageDescriptionText 使用视图返回的 json 数据来填充图像描述的表单。所以你必须修改你的视图对 POST 方法的作用。您必须返回 HttpResponse 而不是渲染模板:
import json
from django.http import HttpResponse
def image_classification(request):
form_des = ItemForm()
if request.method == 'POST':
...
...
return HttpResponse(json.dumps({'title': cat_prediction, 'pattern': pattern_prediction, 'user': request.user.email}))
fillImageDescriptionText接收这个 json 对象作为输入,所以你基本上可以:
function fillImageDescriptionText(data) {
$("#item_des #id_title").val(data.title);
$("#item_des #id_pattern").val(data.pattern);
$("#item_des #id_user").val(data.user);
$("#item_des #id_user").prop('readonly', true);
}
其中 id_ 是 django 脆皮表单或您用于表单的任何包为元素生成的 id。它主要以“id_”为前缀。您可以通过检查浏览器中的元素来检查它。
推荐阅读
- node.js - 为什么不在 REST API 版本控制中考虑模型?
- javascript - amCharts 4 - 第二个 Y 轴不显示值
- c# - 如何上传具有确切文件夹结构的整个文件夹?
- python - 如何在 python-curses 中启用鼠标移动事件
- c - 我正在为斐波那契数列编写代码,在第 44 个系列之后,我开始在系列中得到负值,我不知道为什么?
- c# - 一段时间后如何从循环中的数组中删除对象
- ios - 传入的推送通知设置警报两次 swift 4
- c# - 如何格式化xml对象类的值
- apache-nifi - 在 Evaluate jsonpath 处理器的 nifi usgae 中是否会因为属性创建而影响性能
- python - 你如何替换'|' 用 ' ' 或空字符串?