简体   繁体   English

在 Django 3 中过滤搜索 MultiSelectField

[英]Filtered search for MultiSelectField in Django 3

Now that I change some choice fields into multi select fields for usability.现在我将一些选择字段更改为多个 select 字段以提高可用性。 When I set up the drop down filtering for sorting using iexact with the MultipleSelectField it is no longer or not supported supported.当我使用带有 MultipleSelectField 的 iexact 设置下拉过滤以进行排序时,它不再受支持或不受支持。

Is there a way to Filtered search for MultiSelectField using unique individual values to find both individual and multiple results.有没有办法使用唯一的单个值对 MultiSelectField 进行过滤搜索以查找单个和多个结果。

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.所需的功能我尝试对可以找到的多个 select 字段进行下拉排序,每十年只有一个选择。 Then the search to find single or multiple select results.然后搜索找到单个或多个 select 结果。

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.当每个选项只有一个选项但具有多种组合可能性时,.distinct() 效果很好,现在也是唯一的。 I assume the iexact no longer working for filtering.我认为 iexact 不再适用于过滤。

Select decade
1950s, 1960s, 1970s
...
2000
2010, 2020
2020

In the view it search for the keyword in the field在视图中搜索字段中的关键字

act / views.py行动/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行为/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主页.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>

Not working with multiselectfeild不使用 multiselectfeild 不使用 multiselectfeild

Working without multiselectfield在没有多选字段的情况下工作在没有多选字段的情况下工作

According your decades_choices :根据您的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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM