【问题标题】:Django remove certain parameter from GETDjango 从 GET 中删除某些参数
【发布时间】:2020-04-19 03:17:25
【问题描述】:

我正在使用 GET 方法进行过滤,我希望能够只删除特定的过滤器,我该怎么做?

现在我有一个带有令牌字段的表单,所以我得到了国家和城镇的 ID:

    <form id="search" method="GET" action="{% url 'selection'%}">
        <div class="bg-grey text-center">
                <input type="text" class="form-control" id="tokenfield1" name="country">
        </div>
        {% if filteredcountries %}
        <table class="table table-list">
         {% for c in filteredcountries %}
         <tr>
            <td><button type="button" class="btn btn-xs btn-danger" data-remove="{{c.id}}"><i class="fas fa-times"></i></button></td>
            <td>{{c.country_name`}}</td>
         </tr>
         {% endfor %}
         </table>
        {% endif %}
        <div class="bg-grey text-center">
                <input type="text" class="form-control" id="tokenfield2" name="town">
        </div>
        {% if filteredtowns %}
        <table class="table table-list">
         {% for t in filteredtowns %}
         <tr>
            <td><button type="button" class="btn btn-xs btn-danger" data-remove="{{t.id}}"><i class="fas fa-times"></i></button></td>
            <td>{{t.town_name}}</td>
         </tr>
         {% endfor %}
         </table>
        {% endif %}

views.py:

    def defense_planning(request):
        countries = request.GET.get('country')
        if not countries:
            countries = []
        else:
            countries = countries.split(', ')

        towns = request.GET.get('town')
        if not towns:
            towns = []
        else:
            towns = towns.split(', ')

        results = Hotel.objects.filter(Q(town_id__in = towns) | Q(country_id__in = countries))

        context = {
            'filteredcountries': countries, 
            'filteredtowns': towns,
            'hotels': results
        }
       return render(request, 'myapp/hotels.html', context)

现在我想单击按钮并从 GET 中删除特定的城镇或国家,并保留其他的。你能引导我找到解决方案吗?

按钮点击前的示例网址:

..myapp/hotels?country=2%2C+4&town=2

按钮点击后的网址,国家 ID 为 2:

..myapp/hotels?country=4&town=2

或在按钮点击城镇 id 2 后:

..myapp/hotels?country=2%2C+4&town=

【问题讨论】:

  • %2c 是一个逗号,所以它基本上是country=2, 4
  • 是的,但这在我的问题中并不重要。
  • 您是否有任何理由要在 GET 中而不是在您的视图中这样做?如果你真的需要修改 url,你可以选择 javascript 吗?
  • @Chris 如果 url 发生变化,我不介意这样做。是的,javascript 可能是。在他删除其中一个参数后,我需要以某种方式使用 get params 更改 url。

标签: django forms django-templates django-views


【解决方案1】:

如果您的令牌字段包含所有可能的 id 作为逗号分隔的列表,则在加载 javascript 以从令牌字段中删除特定 id 时可能如下所示:

<script>
    $('.country-btn').click(function(){
        var id = $(this).data('remove');
        var countries = $('#tokenfield1').val().split(',');
        var index = countries.indexOf(id.toString());
        if (index >= 0){
            countries.splice(index, 1)
        }
        $('#tokenfield1').val(countries.join());
    })

</script>

为了使用上下文中返回的 id 填充您的令牌字段,您可以执行类似的操作

<input type="text" class="form-control" id="tokenfield1" name="country" 
       value="{% for c in filteredcountries %}{{c.id}}{% if not forloop.last %},{% endif %}{% endfor %}">

【讨论】:

  • 问题是我需要再次通过后端运行它以选择相关酒店进行过滤。这就是为什么我需要编辑 GET 参数。
  • @popcorn 是的,但是如果您将我发布的脚本添加到您的模板并提交您的表单,它就会这样做。还是我误会了你?
  • 哦,是的,但是当我提交表单时,#tokenfields 不再具有值,它仅在上下文和 GET 中
  • @popcorn 您的意思是在从 defence_planning 视图返回到表单后,令牌字段为空?你为什么不把它们放回去?
  • 我不知道,我应该把它们放回去吗?
【解决方案2】:

这是一个使用 javascript 和 JQuery 的解决方案。基本做法如下:

  1. 在页面加载时将当前window.location.href 存储在变量中。为什么? 否则对它的每次操作都会导致发送一个新的 GET 可能不受欢迎的请求
  2. 处理存储的字符串 在提到的变量中,具体取决于单击的按钮。
  3. 防止提交按钮直接触发,但使用 被操纵的字符串

这里有一些 cmets 的脚本部分:

<script>
    var current_get = window.location.href // Store current url

    var handleget = function(part_chooser, id){
        // part_chooser = country or town, id = pk to remove
        var parts = current_get.split('?');

        if (parts.length < 2){  // No get params to manipulate
            return;
        }
        var get_part = parts[1];
        var get_parts =get_part.split('&');
        var i; // To keep order of new href if important
        var str_to_handle; // Part to manipulate
        for (i = 0; i < get_parts.length; i++){
            if (get_parts[i].startsWith(part_chooser)){
                str_to_handle = get_parts[i];
                break;
            }
        };

        // Do manipulation and store new url
        var get_arr = str_to_handle.split('=');
        if (get_arr.length > 0){
            params = get_arr[1].split('%2C+');
            var index = params.indexOf(id.toString());
            if (index >= 0){
                params.splice(index, 1);
                params = params.join('%2C+');
                get_parts[i] = part_chooser + '=' + params;
                current_get = parts[0]+'?'+get_parts.join('&');
                console.log(current_get);
            }

        };
    };

    $('button[type=submit]').click(function(event){
        event.preventDefault();
        window.location.href = current_get;
    })

    $('.country-btn').click(function(){
        var id = $(this).data('remove');
        handleget('country', id);
    });

</script>

一些意见

  1. 我故意不使用长链 JS 来缩短代码,因为恕我直言,一步一步阅读更容易
  2. 可以通过巧妙地使用正则表达式来缩短字符串操作。

【讨论】:

  • 就是这样!我只需要切换 $('button[type=submit]').... 与 $('.country-btn')...
猜你喜欢
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
  • 2014-11-06
  • 2018-06-29
  • 1970-01-01
  • 2015-09-15
  • 2011-03-17
  • 1970-01-01
相关资源
最近更新 更多