Django-麻烦在模板中调用函数,并将该函数的值返回到同一页面

时间:2018-07-23 17:56:09

标签: django python-3.x django-templates django-views django-request

我有一个页面呈现来自数据库的对象列表。我需要按下一个按钮,查询数据库中的特定对象,在视图中执行一些操作,并返回一个价格值,该价格值我希望在弹出气泡中显示在同一页面上,而不用重新加载它,我有填充文字。我尝试通过创建一个带有一个在value字段中具有对象id的按钮的表单,并将该值发送到原始页面的视图中来执行此操作,然后调用一个函数来处理要处理的事情用那个ID做。我请求对象的id,将其传递给新的view函数,然后查询数据库并尝试返回该值。我在原始页面的视图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})

1 个答案:

答案 0 :(得分:0)

您尝试执行的操作通常应通过异步调用(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代码中对beforeSend的{​​{1}}调用中处理CSRF(跨站点请求伪造)令牌。
  • 您可能应该检查视图中的虚假查询(请求是否为GET调用?)和其他类似情况。