我有一个页面,它呈现了数据库中的对象列表。我需要按下一个按钮,该按钮在我的数据库中查询特定对象,在我的视图中执行一些操作,并返回一个价格值,我希望在同一页面上以弹出气泡显示该值,而无需重新加载它,而不是我拥有的填充文本。我尝试通过创建一个带有按钮的表单来执行此操作,该按钮在值字段中具有对象的id
,并将该值发送到我的原始页面的视图,然后调用一个函数来处理我想用该 id 执行的操作。我请求对象的id
,将其传递给新的视图函数,并查询我的数据库并尝试返回值。我在原始页面的视图 t 中做了一个if request.POST
语句,并将呈现的变量更改为我想要显示的新值。当我按下按钮时,我在弹出气泡中得到相同的填充文本,在我的控制台中,我收到以下错误:
ValueError: The view engine.views.search_list didn't return an HttpResponse object. It returned None instead.
因此,每当调用视图函数时,我似乎都必须返回HTTP请求。我尝试在新视图函数中返回呈现的响应,并在检查后if request.POST
并将新值作为上下文传递:
return render(request, 'original_page.html', {'value':new_value})
我得到同样的错误。如何在同一页面上返回所需的值而不会收到此错误?我尝试使用带有空白值的HttpResponse
,redirect('some_place.html')
没有成功。我确实有一个 Iframe,它可以阻止我的 html 页面重新加载。这是我正在使用的代码:
.HTML
<iframe name="submit-frame" style="display: none"></iframe>
<form action="{% url 'search_list' %}" method="post" target="submit-frame">{% csrf_token %}
<button name="productId" value="{{product.id}}" data-toggle="popover" data-animation="true" data-content="{{price}}" type="" id='button'>Reveal Price</button>
</form>
<script type="text/javascript">
$('[data-toggle="popover"]').popover({
container: 'body',
delay: { "show": 100, "fade": 100 },
})
</script>
视图 - 获取新值的功能
def get_price(request):
product_id = request.POST.get('productId')
item = get_object_or_404(Product, id=product_id)
price = item.price
return price
视图 - 原始渲染视图
def search_list(request):
results = Product.objects.all().order_by('name')
price = 'no_price'
if request.POST:
print(request.POST.get('productId'))
tcg_price = get_price(request)
return render(request, 'search_result_list.html', {'tcg_price': tcg_price})
else: ...
return render(request, 'search_result_list.html', {'price': price, 'results':results})
您尝试执行的操作通常应通过异步调用 (AJAX) 处理。您当前设置的方式,表单提交,页面将重新加载。这不是用户友好的体验,并且是"Web 1.0"的做事方式(也iframes
......哎呀!以下是我将如何更改您的设置:
新建视图
def ajax_get_price(request):
response = {}
product_id = request.POST.get('productId')
try:
item = Product.objects.get(id=product_id)
response['price'] = item.price
response['success'] = True
except ObjectDoesNotExist:
response['error'] = "Item not found!"
response['success'] = False
return JSONResponse(response)
新的前端处理程序
您将通过JavaScript中的AJAX调用将数据发送到这个新的"视图"。我将在这里使用 jQuery 作为示例:
$("button[name='productId']").on("click", function() {
var productID = $(this).val();
$.ajax({
'data': {
'productId': productID
},
'type': "POST",
'url': "{% url 'myproject:ajax_get_price' %}"
})
.done(function(json) {
if(json.success == true) {
var itemPrice = json.price;
// TODO: Do something with the price here (show a popup, tooltip, whatever)
} else {
if(json.hasOwnProperty('error') {
// TODO: Show the error
})
}
})
.fail(function(xhr, status, error) {
// TODO: Handle this error case also
});
});
除了此存根之外,您还需要处理一些事情:
- 您可能必须在 JavaScript 代码中
$.ajax()
beforeSend
调用中处理 CSRF(跨站点请求伪造)令牌。 - 您应该检查视图中是否存在虚假查询(请求是GET调用吗?)和其他类似的边缘情况。