How to make django querysets with dynamic filters? -


so have website in django storefront , end user has 3 filters use. product type filter (pants, shoes, shirts, etc), delivery filter (yes/no), , location/popularity filter.

currently in views.py have method.

if request.is_ajax():     if request.get.get('filter') == 'shirts':         latest_entries = entry.objects.filter(entrytype="shirts")         context = {'latest_entries': latest_entries}         return render(request, 'storefrontload.html', context)     if request.get.get('filter') == 'pants':         latest_entries = entry.objects.filter(entrytype="pants")         context = {'latest_entries': latest_entries}         return render(request, 'storefrontload.html', context)     if request.get.get('filter') == 'shoes':         latest_entries = entry.objects.filter(entrytype="shoes")         context = {'latest_entries': latest_entries}         return render(request, 'storefrontload.html', context) 

as can see, handles first filter. problem i'm having if select, let's 'pants', filters pants disregards selected in other 2 filters. example, let's select pants, page populates results of filter. if go delivery filter , select "yes", page populates items deliverable, "pants" filter forgotten.

what i'm trying figure how how create queryset in views remembers other 2 querysets (if makes sense).

the way can think of create true/false flags each value in each filter, , add 100 lines of if/then statements checking each flag. there has got better way.

update:

this how passing filter value template.

function filter(type) {   $.get("/storefront/?filter="+type, function(data) {      var $data = data;      $('.grid').children().remove();      $('.grid').append( $data ).masonry( 'appended', $data, true ).masonry( 'layout' );    }); }     //product filter     $("#shirts").unbind().click(function () {    filter("shirts");   return false; });   $("#pants").unbind().click(function () {    filter("pants");   return false; });  $("#shoes").unbind().click(function () {    filter("shoes");   return false; });      //delivery filter $("#deliveryyes").unbind().click(function () {    filter("deliveryyes");   return false; });  $("#deliveryno").unbind().click(function () {    filter("deliveryno");   return false; }); 

in views.py, not work:

 entry_types = request.get.getlist('filter')  latest_entries = entry.objects.filter(entrytype__in=entry_types) 

because need filter entrytype('pants', 'shirts', shoes') , deliveryoption ('deliveryyes', 'deliveryno'). each filter has it's own column in model.

models.py  class entry(models.model):     headline= models.charfield(max_length=200,)     body_text = models.textfield()     author=models.foreignkey(settings.auth_user_model, related_name='entryauthors')     pub_date=models.datetimefield(auto_now_add=true)     zipcode =models.integerfield(null=true, max_length=10)     !!! entrytype = models.charfield(null=true, max_length=10)     !!! deliveryoption=models.charfield(null=true, max_length=5) 

you can pass comma-separated list of filter values:

/mylist/filter=shirts,pants 

and entries using __in lookup:

entry_types = request.get.get('filter', '').split(',') latest_entries = entry.objects.filter(entrytype__in=entry_types) 

or use the getlist() method of querydict:

/mylist/filter=shirts&filter=pants 

with same orm call:

entry_types = request.get.getlist('filter') latest_entries = entry.objects.filter(entrytype__in=entry_types) 

update: pass multiple types view save them in array , use join() method comma-separated string of them:

var types = []; // shown entry types  function filter(type) {   // add or remove items grid   var index = types.indexof(type);   if (index > -1) {     types.splice(index, 1); // remove type list   } else {     types.push(type); // add type filter   }   $.get("/storefront/?filter="+types.join(","), function(data) {     ...   } } 

update 2: if use 2 fields filter queryset have create 2 separate lists in view:

filters = request.get.getlist('filter') entry_types = [f f in filters if not f.startswith('delivery')] delivery_types = [f f in filters if f.startswith('delivery')]  latest_entries = entry.objects.all() if entry_types:     latest_entries = latest_entries.filter(entrytype__in=entry_types) if delivery_types:     latest_entries = latest_entries.filter(deliverytype__in=delivery_types) 

javascript code work without touches.


Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

order - Notification for user in user account opencart -