更新模板数据后,我是否需要重新渲染页面

时间:2018-11-30 16:51:06

标签: django django-models django-templates django-views

首先我有searched and seen another answer,但是它不能满足我的需求。

我正在尝试使用jQuery / AJAX从我的HTML发布数据来更新也在我的HTML上的列表。

当我第一次渲染模板时,它有两个列表组容器,其中左容器是预先填充的。

two containers

用户在左侧容器上做出的选择决定了右侧容器的列表组数据。

我想发回后端Python(服务器),该服务器从左容器中选择用户,以便为第二个(右)容器填充适当的列表。这就是为什么我使用jQuery / AJAX的POST方法发送用户选择的原因。

HTML

这是HTML的 Plnkr

下面是 WORKS 的jQuery / AJAX实现。它将数据发送回Python (至我的views.py)

JS / jQuery / AJAX:

<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
    $("#leftContainer > a").click(function(event){
        event.preventDefault();
        $("#leftContainer > a").removeClass("active");
        $(this).addClass("active");

        var leftDataSet = parseInt($(this).attr("data-set"));        
        var item_selected = $(this).text();
        var item_index = $(this).attr("id")   //Users selection to send

        $.ajax({
            type:'POST',
            url:"home/view_results/onclick/",
            data:{
                selected_item:item_index,
                csrfmiddlewaretoken:"{{ csrf_token }}"
            },
            dataType:"text",
            success: function(){$('#message').html("<h3>Data Submitted!</h3>") }
        })        
    });

    $("#rightContainer > a").click(function(event){
        event.preventDefault();
        $(this).toggleClass("active");
    });
</script>

views.py

#app/views.py
from django.shortcuts import render
class View_Items():

   def render_view_items(self, request, shopid):
      item_history = self.get_item_list(shopid)     #Fetches a list
      return render(request, 'view_results/View_items.html',{
           'item_list':item_history,
        })

urls.py

#app/urls.py
from django.urls import path, re_path
from . import views
results = views.View_Items()
urlpatterns=[
        ...
        re_path(r'view_results/(?P<shopid>\w+)$', results.render_view_items, name = 'view_items'),
        re_path(r'view_results/onclick/$', results.render_view_items_again, name = 'view_results_new'),  # NEW
]

我的问题是:

现在,我已经在views.py将AJAX数据返回了我的Python后端,是否需要重新渲染页面以在HTML中填充Right容器的列表组项目?或者可以更新列表而不必重新渲染。如果是这样,为什么我在 NOT 下建议的重新渲染功能更新HTML的 RIGHT容器?更新Right容器是需要选择左侧容器的目标。

我对views.py的添加

#app/views.py
def render_view_items_again(self, request):
    selected_item_by_user = request.POST.get('selected_item')
    # print(selected_item_by_user)
    models = self.get_all_models(selected_item_by_user)  #Fetches a list.
    # print(models)                     #Tested if my list is populated.
    return render(request, 'view_results/View_items.html',{
        'model_list':models,
        })

1 个答案:

答案 0 :(得分:0)

完全有可能填充正确的容器,而无需重新加载页面。

通常要做的是将来自views.py的函数划分为第一个渲染的情况以及从AJAX POST返回时的情况。就您而言,views.py类似于:

if request.method == 'POST': # Returning from AJAX
    selected_item_by_user = request.POST.get('selected_item')
    models = self.get_all_models(selected_item_by_user)  #Fetches a list.
    return JsonResponse({'completed': "ok", 'list': models})

else:  # First time render
    item_history = self.get_item_list(shopid)     #Fetches a list
    return render(request, 'view_results/View_items.html',{
         'item_list':item_history,
       })

如您所见,我只是第一次渲染模板。当您从AJAX返回时,我仅致电JsonResponse。将以下导入添加到您的代码中:

from django.http import JsonResponse

请注意,根据列表的构建方式(您未提供详细信息),您需要对其进行accodingly编码。

然后,在您的AJAX方法的success函数中,您可以轻松地使用list(进行修改以填充正确的容器):

success: function(data){console.log(data.list)}

因此,将在不进行页面重新渲染/刷新的情况下填充正确的容器。

编辑1

现在,我看到您还在AJAX方法中重定向到另一个URL。如果不想刷新,请按以下步骤在AJAX方法中设置网址:

$.ajax({
    type:'POST',
    url: window.location.href,
    data:{
        selected_item:item_index,
        csrfmiddlewaretoken:"{{ csrf_token }}"
    },
    dataType:"text",
    success: function(){$('#message').html("<h3>Data Submitted!</h3>") }
})  

因此,您在urls.py文件中也只需要一个网址。

我不知道您正确的容器的HTML代码,但是如果它是列表ul(假设它有一个id=list_conditions),则可以将一个项目添加到正确的容器中,如下所示:如下:

// Get where I should add the index
let ul=document.getElementById("list_conditions");
// Create a new child
let li=document.createElement("li");
li.setAttribute("class", "list-group-item list-group-item-secondary");              
li.appendChild(document.createTextNode(data.list[0])); // Here you can replace by the index you need from the list
ul.appendChild(li);