首页 > 解决方案 > 将列表值从 django 模板发送到 django 视图

问题描述

我编写了一个代码,当用户单击添加按钮时,它会动态添加一个列表。例如,创建了两个列表-

      <ul>
         <li>samsung galaxy</li>
          <li>xiaomi redmi note 5</li>
      </ul>

添加li的前端代码

<div class="compare_val"> <input type="text" id="txtVal" placeholder="write 
 to add">
      <button onclick="addLi()" class="btn">Add</button></div>
       <ul id="list">
       <li>{{ Brand }}</li>
    </ul>
    <button id="Com_action" class="btn btn-danger ml-3" 
  onclick="ComAction()">Compare</button>

    <script>
       function addLi()
        {

            var txtVal = document.getElementById('txtVal').value,
                listNode = document.getElementById('list'),
                liNode = document.createElement("LI"),
                txtNode = document.createTextNode(txtVal);

                liNode.appendChild(txtNode);
                listNode.appendChild(liNode);
        }
    </script>

现在我想将 li 数据作为列表发送

['samsung galaxy', 'xiaomi redmi note 5']到视图

当用户点击比较按钮时。

请帮助我实现这一目标。

html页面的图片

标签: djangodjango-rest-frameworkdjango-views

解决方案


您需要修改脚本以包含csrfmiddlewaretoken和发送数据XmlHttpRequest(我假设您没有使用jquery):

<script>
    // Standard django function to get csrf_token. More info:
    // https://docs.djangoproject.com/en/2.2/ref/csrf/#acquiring-the-token-if-csrf-use-sessions-and-csrf-cookie-httponly-are-false
    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                let cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }

    const listNode = document.getElementById('list');
    let brands = [];

    function addLi() {
        let txtVal = document.getElementById('txtVal').value,
            liNode = document.createElement("LI"),
            txtNode = document.createTextNode(txtVal);

        liNode.appendChild(txtNode);
        listNode.appendChild(liNode);

        // Save newly added brand to array
        brands.push(txtVal);
    }

    function ComAction() {
        // Prepare AJAX request
        let xhr = new XMLHttpRequest(),
            data = new FormData();

        // Add token
        data.append('csrfmiddlewaretoken', getCookie('csrftoken'));

        // Add all brands
        brands.forEach(function (brand) {
            data.append('brand', brand);
        });

        // We are sending it via POST request to url '/'
        xhr.open('POST', '/', true);
        xhr.onload = function () {
            if (xhr.status === 200) {
                alert('Data received successfully. Brands are ' + xhr.responseText);
            } else if (xhr.status !== 200) {
                alert('Request failed.');
            }
        };
        // Actually send request
        xhr.send(data);
    }
</script>

您的 django 端点可以处理这样的品牌:

视图.py:

def index(request):
    if request.method == 'POST':
        brands = request.POST.getlist('brand')
        return HttpResponse(", ".join(brands))
    return render(request, 'index.html')

如果您希望 django 发送数据并重定向用户,请修改脚本:

// ...
xhr.open('POST', '/', true);
xhr.onload = function () {
            if (xhr.status === 200) {
                data = JSON.parse(xhr.responseText);
                alert('Data received successfully. Brands are ' + data.brands);
                window.location.replace(data.redirect_url);
            } else if (xhr.status !== 200) {
                alert('Request failed.');
            }
        };
xhr.send(data);

和 django:

视图.py:

def index(request):
    if request.method == 'POST':
        brands = request.POST.getlist('brand')
        response_data = {
            'brands': brands,
            'redirect_url': '/new_url'
        }
        return JsonResponse(response_data)
    return render(request, 'index.html')

推荐阅读