Now that I change some choice fields into multi select fields for usability. When I set up the drop down filtering for sorting using iexact with the MultipleSelectField it is no longer or not supported supported.
Is there a way to Filtered search for MultiSelectField using unique individual values to find both individual and multiple results.
Desired functionality I am try to get to a drop down to sort with only one choice of each decade for the multiple select fields that can find. Then the search to find single or multiple select results.
Select decade
1950s
...
2000
2010
2020
Currently, the front end displays what is created for each new entry so if single of combination it creates a unique entry for each combo or single entry so its kind of ugly and messy. The .distinct() worked good when only one choice per choices but with many possibilities of combinations are now also unique. I assume the iexact no longer working for filtering.
Select decade
1950s, 1960s, 1970s
...
2000
2010, 2020
2020
In the view it search for the keyword in the field
act / views.py
# SEARCH BASED-KEYWORD
def search(request):
act = Act.objects.order_by('-created_date')
demographics_search = Act.objects.values_list('demographics', flat=True).distinct()
defaultgenre_search = Act.objects.values_list('defaultgenre', flat=True).distinct()
decade_search = Act.objects.values_list('decade', flat=True).distinct()
genre_search = Act.objects.values_list('genre', flat=True).distinct()
# if has keyword request from the url
if 'keyword' in request.GET:
keyword = request.GET['keyword']
# check if keyword is not blank, find the keyword in the whole of the description
if keyword:
act = act.filter(description__icontains=keyword)
# if has keyword request from the url
if 'demographics' in request.GET:
demographics = request.GET['demographics']
# check if keyword is not blank, find the keyword in the whole of the description
if demographics:
act = act.filter(demographics__iexact=demographics)
if 'defaultgenre' in request.GET:
defaultgenre = request.GET['defaultgenre']
# check if keyword is not blank, find the keyword in the whole of the description
if defaultgenre:
act = act.filter(defaultgenre__iexact=defaultgenre)
act / models.py
from django.db import models
from django.db.models import CharField
from django.utils import timezone
from ckeditor.fields import RichTextField
from multiselectfield import MultiSelectField
# Create your models here.
class Act(models.Model):
artists_name = models.CharField(max_length=255)
description = RichTextField(blank=True)
call_to_action = models.CharField(max_length=255)
artists_photo = models.ImageField(upload_to='photo/%y/%m/%d/')
act_page_title = models.CharField(max_length=255)
act_page_description = models.CharField(max_length=255)
act_page_keywords = models.CharField(max_length=255)
created_date = models.DateTimeField(auto_now_add=True)
defaultgenre_choices = [
('Adult Contemporary','Adult Contemporary'),
('Classic Rock','Classic Rock'),
('Country Music','Country Music'),
('Disco & Funk','Disco & Funk'),
('Trap Music', 'Trap Music'),
('Folk Music', 'Folk Music'),
('Singer / Songwriter', 'Singer / Songwriter'),
('Latin Music', 'Latin Music'),
]
defaultgenre = models.CharField(
choices= defaultgenre_choices,
max_length= 100,)
decades_choices = [
(1,'1950s'),
(2,'1960s'),
(3,'1970s'),
(4,'1980s'),
(5,'1990s'),
(6,'2000s'),
(7,'2010s'),
(8,'2020s'),
]
decade = MultiSelectField(max_length=100,
choices= decades_choices,)
def __str__(self):
return self.artists_name
home.html
<div class="search-box-4 sb-8">
<form action="{% url 'search' %}" method="">
<div class="form-group">
<input type="text" name="keyword" placeholder="Search by name" class="form-control">
</div>
<div class="form-group">
<select class="form-control search-fields" name="demographics">
<option selected="true" disabled="disabled">Demographics</option>
{% for demographics in demographics_search %}
<option value= "{{demographics}}">{{demographics}}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<select class="form-control search-fields" name="defaultgenre">
<option selected="true" disabled="disabled">Default Genres</option>
{% for defaultgenre in defaultgenre_search %}
<option value= "{{defaultgenre}}">{{defaultgenre}}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<select class="form-control search-fields" name="decade">
<option selected="true" disabled="disabled">Decade</option>
{% for decade in decade_search %}
<option value= "{{decade}}">{{decade}}</option>
{% endfor %}
</select>
</div>
According your decades_choices
:
decades_choices = [ (1,'1950s'),(2,'1960s'),(3,'1970s'),(4,'1980s'), (5,'1990s'),(6,'2000s'),(7,'2010s'),(8,'2020s'), ]
I assume that your values look like this:
<div class="form-group">
<select class="form-control search-fields" name="decade">
<option selected="true" disabled="disabled">Decade</option>
<option value="7, 8">2010s, 2020s</option>
<option value="8">2020s</option>
</select>
</div>
Then to filter by decade you have to do so:
decade = request.GET.get("decade")
if decade:
# convert string to list
decade = decade.split(",")
act = act.filter(decade=decade)