0

I have one field with ManyToManyField and want to filter my object with list of values.I get this values from dropdown.

my template

<form class="" action="." method="get">
  <div class="SearchWithTags">
    <select name="searchcategory" id="TagDropDown">
          {% for k in types_list %}
            <option>{{k.name}}</option>
          {% endfor %}
    </select>
    <div class="PlaceForTags">
      <div id="PlaceForTagsId" class="Tags">

      </div>
      <a href="#"><img src="{% static 'assets/search.png' %}"></a>
    </div>
  </div>
    <input id="SendTagArray" type="submit" class="Search" name="startsearch" value="search">
</form>

i'm creating array of this values

values = [];

$(function() {

$('#TagDropDown').change(function() {
    values.push($('#TagDropDown option:selected').text());
            $('#PlaceForTagsId').append("<div class='tagex'>" +$('#TagDropDown option:selected').text()+"</div>");

});

    $("#SendTagArray").click(function(){
        console.log(values);
        $.ajax({
         type: 'GET',
         url: '/sitelink/',
         data: {'tags': values},
        });
    });

});

views.py

tags = request.GET.getlist('tags', '')
if searchbutt:
    if tags != '':
        search_filter_kw['tags__name__in'] = tags

but i have problem that it doesn't send values to my view and tags variable is empty.

1 Answer 1

1

How about use request.GET.getlist('tags[]', '') ?

Result Before Search

before

Result After Search by ajax

after


This example below is how to implement it.

Example:

1. yourapp/models.py

from django.db import models

class Foo(models.Model):
    name = models.CharField(max_length=200)

    def __str__(self):
        return self.name


class Ref(models.Model):
    foo = models.ManyToManyField(Foo, related_name='ref_foo')
    other = models.CharField(max_length=200)

    def __str__(self):
        return self.other

2. yourapp/views.py

from django.shortcuts import render
from foo.models import (Foo, Ref)

def fooview(request):
    foos = Foo.objects.all()
    refs = Ref.objects.all()
    return render(
      request, 'foo.html', 
      {'types_list': foos, 'refs': refs}
    )

def search(request):
    if request.is_ajax():
        tags = request.GET.getlist('tags[]', '')
        #print(tags)
        if tags != '':
            results = Ref.objects.filter(foo__name__in=tags).distinct()
            return render(
              request, 'search.html', 
              {'results': results, 'tags': tags}
            )
    return render(request, 'search.html', {})

3. yourapp/urls.py

from django.conf.urls import url
from yourapp.views import (fooview, search)

urlpatterns = [
    url(r'^$', fooview, name='foo'),
    url(r'^search/$', search, name='search')
]

3. templates/foo.html

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>

<body>
<div class="original-data">
 Original Data:<br />
 {% for ref in refs %}
   <li>{{ ref }} - {% for foo in ref.foo.all %}{{ foo }}, {% endfor %}</li>
 {% endfor %}
</div>
<hr />

<div class="main-search">
  <div class="SearchWithTags">
    <select name="tags" id="TagDropDown">
      <option>Choice categories...</option>
      {% for k in types_list %}
        <option value="{{ k.name }}">{{ k.name }}</option>
      {% endfor %}
    </select>
    <div class="PlaceForTags">
      <div id="PlaceForTagsId" class="Tags">
      </div>
    </div>
  </div>
  <button id="SendTagArray" class="search">Search...</button>
</div><!-- end /.main-search -->

<div class="main-results">
</div>

<script>
  values = [];
  $(function() {
    $('#TagDropDown').change(function() {
        var val = $('#TagDropDown option:selected').text();
      // check if has duplicate values
      if (values.includes(val) == false){
        values.push(val);
        $('#PlaceForTagsId').append("<div class='tagex'>" +$('#TagDropDown option:selected').text()+"</div>");
      }
    });
    $("#SendTagArray").click(function(){
      console.log(values);
      $.ajax({
        type: 'GET',
        url: '{% url "search" %}',
        data: {
          'csrfmiddlewaretoken': '{{ csrf_token }}', 
          'tags': values
        },
        success: function(data) {
           $('.main-results').html(data);
        },
        error: function(data) {
           console.log(data);
        }
      });
    });
  });
</script>
</body>
</html>

4. templates/search.html

<div class="results">
  Result of {{ tags }}:
  <hr />

  {% for result in results %}
    <li>{{ result }}</li>
  {% endfor %}
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

I didn't paste my whole form html, i have another dropdowns in this form, but in this situation i want to filter my object with many tags and it impossible without javascript so when i click my search button it executes ordinary query filter from other dropdowns and javascript to execute this filter with tags. Is it possible that this is a problem here?
ofcourse can, please checkout this answer stackoverflow.com/a/28417702/6396981

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.