【问题标题】:How to filter querysets dynamically with ajax and dropdown menu如何使用 ajax 和下拉菜单动态过滤查询集
【发布时间】:2020-06-15 09:08:52
【问题描述】:

我认为以下代码:

def stato_patrimoniale(request):
    now=datetime.datetime.now()
    now=now.year
    ...
    if Ricavi.objects.count()>0:
            for year, month, totale in(Ricavi.objects.values_list( 'data_pagamento_acconto__year', 'data_pagamento_acconto__month').
                annotate(totale=ExpressionWrapper(Sum(F('acconto')),
                output_field=FloatField())).values_list('data_pagamento_acconto__year', 'data_pagamento_acconto__month', 'totale')):
                if id not in incassi.keys() and  year == now:
                    incassi[id]=list(defaults)
                index=month-1
                incassi[id][index]=totale

now变量用于过滤我在查询集中的数据,其中我的ricavi是以下模型:

class Ricavi(models.Model):
    codice_commessa=models.ForeignKey(Informazioni_Generali, on_delete=models.CASCADE, null=True, blank=True)
    # numero_lavorazione
    acconto=models.DecimalField()
    data_pagamento_acconto=models.DateField()

现在我想用一个表格替换now 变量,让我可以选择年份并更新我的观点。

我已经使用以下模型创建了另一个应用程序,该应用程序带有一个可以添加新年的表单:

class Timing(models.Model):
    reference_year = models.DecimalField(max_digits=4, decimal_places=0, default="2020")

现在我想创建一个下拉按钮,其中包含所有填充的reference_year,当客户端单击其中一个时,我的def stato_patrimoniale(request): 中的now 变量会更新。我怎样才能达到这个目标?

【问题讨论】:

  • 为什么不发布year 变量以在stato_patrimoniale 中使用它?
  • 在什么意义上?
  • 您想更新now 变量并更新您的视图。因此,当它发生变化时将其发布到stato_patrimoniale,然后更新now 和...
  • 在您的请求中查找年份:request.POST['year']

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


【解决方案1】:

以如下形式插入下拉菜单:

<form method="POST" action="url to stato_patrimoniale">
{% csrf_token %}
<select name="year" id="year" onchange="this.form.submit()">
   <option value="2020">2020</option>
   <option value="2019">2019</option>
   <option value="2018">2018</option>  
</select>
</form>

然后在stato_patrimoniale 添加:

 now = now.year
 if request.method == 'POST':
     year = request.POST['year']
     if year != '':
          now = year

【讨论】:

  • 我相信他正在寻找一个 Ajax 请求
【解决方案2】:

我有这种方法来编写接收 ajax 请求的视图。

注意:将展示一些示例代码,因为我太困了,无法处理完整的示例哈哈

不是最有效的方法,但它有效,还接受多个参数来过滤或操作或做任何你想做的事情。

def searchAjaxView(request):
    if request.method == "POST" and request.is_ajax:
        body = json.loads(request.body)
        requestData = {}
        for item in body:
            name = item['name']
            requestData[name] = item
   #all your logic goes here ... 
   #for example read the year
   #Important, check if it exist on the dict before trying to get the value OR always send a default value... in this case im working around the default option in select
   year= requestData['year']['value']
   if year !='':
      #ah idk do your stuff here with the year i'll return a json response
      product_list = list(MyTable.objects.all())
   data = serializers.serialize('json', product_list)
   return JsonResponse(data, safe=False)

好的,在 html-js 中,我有这个带有 jquery 的示例。工作正常,再次不是最花哨的方式。

<!-- no need ne method attrs, just declaratively -->
<form method="POST" id="filterForm" name="filterForm">{% csrf_token %}
 <select name="year" id="year" class="m-auto basic-single my-1 mr-sm-2">
 <option value="">Select a year</option>
<!-- at this point i'm copy-paste code from my project, ps: trick to lazy fill the select with years -->
 {% with ''|center:10 as range %}
 {% for _ in range reversed %}
 <option value="200{{ forloop.counter0 }}">200{{ forloop.counter0 }}</option>
 {% endfor %}
 {% endwith %}
 {% with ''|center:10 as range %}
 {% for _ in range reversed %}
 <option value="201{{ forloop.counter0 }}">201{{ forloop.counter0 }}</option>
 {% endfor %}
 {% endwith %}
 {% with ''|center:1 as range %}
 {% for _ in range reversed %}
 <option value="202{{ forloop.counter0 }}">202{{ forloop.counter0 }}</option>
 {% endfor %}
 {% endwith %}
 </select>
 <div class="form-group container my-1">
 <button class="col-12 form-control btn btn-success" type="sumbit">Filter</button>
 </div>
</form>

<script>
    var frm = $('#filterForm');
    frm.submit(getAjax);
    function getAjax() {
        var formData = JSON.stringify($("#filterForm").serializeArray());
        console.log("Request parameters:")
        console.log(JSON.parse(formData))
        $.ajax({
            headers: { "X-CSRFToken": '{{csrf_token}}' },
            type: "POST",
            url: "{% url 'publication:response' %}",
            contentType: 'application/json',
            dataType: 'json',
            data: formData,
            success: function (data) {
                jsonData = console.log(data);
                var dataObj = JSON.parse(data);
                console.log("Response data:")
                console.log(dataObj)
                //more stuff here, too much for this example
            },
        }); return false;
    }
</script>

如果您的项目变得很大,并且您必须对模板进行许多此类动态更新,请考虑使用前端框架或 javascript 库。两者都好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-05
    • 2017-02-14
    • 1970-01-01
    • 2013-05-09
    • 2021-07-19
    • 2014-09-06
    • 2013-12-19
    • 2018-01-19
    相关资源
    最近更新 更多