1

i'm trying to make a query that gives me the results in the order that i have the conditions in. I tried the following:

 if query:
    word_list = query.split()
    for word in word_list:
       icons = icons.filter(
                   Q(name__iexact=word) |
                   Q(name__istartswith=word) |
                   Q(words__text__icontains=word) |
                   Q(name__icontains=word)
               ).distinct()

and also

if query:
    word_list = query.split()
    for word in word_list:
       exact_icons = icons.filter(Q(name__iexact=word)).distinct()
       start_with_icons = icons.filter(Q(name__istartswith=word)).distinct()
       contains_icons = icons.filter(
                         Q(words__text__icontains=word) |
                         Q(name__icontains=word)
                     ).distinct()
       icons = exact_icons | start_with_icons | contains_icons

so i would like to first get the results that match exactly, then the ones that start with and only at end the ones that contain the word, but neither of the alternatives above seem to work. Any ideas how can i accomplish this? Thanks

WNB
  • 61
  • 3
  • 12

1 Answers1

1

You can use chain. It does the following:

list_a = ['A', 'B', 'C']
list_b = ['D', 'E', 'F']
print(list(chain(list_a, list_b)))
>>> ['A', 'B', 'C', 'D', 'E', 'F']

Here to use in your second try:

from itertools import chain
...
icons = list(chain(exact_icons, start_with_icons, contains_icons))

Due to your updated infos:

from functools import reduce, import operator
words_qs = reduce(operator.or_, (Q(name__iexact=word) for word in words))
YourModel.objects.filter(..., words_qs)
zypro
  • 1,158
  • 3
  • 12
  • 33
  • the thing is that i have to do this inside a for loop and i have to apply the filtering to the latest icons set and i think i need to have that icons as a queryset instead of a list. i also updated the example with the whole block, including the for – WNB Nov 09 '18 at 10:14
  • and where do you try to collect all queryersets generated by the for loop? in Icons are always only the current ones... – zypro Nov 09 '18 at 10:26
  • this thing actually does a search and we can have multiple words search, such as 'school bus' and the search should first do that search for 'school' and on the exact queryset returned by the search of 'school' should then search for 'bus' also. so the point is that i need the results in order at the end of each iteration of the loop, but as a queryset, so that i can further search for the next word – WNB Nov 09 '18 at 10:31
  • I updated my anwser, have a look at it and try to adapt it to your problem ;-) – zypro Nov 09 '18 at 10:53
  • by the way, icons = list(chain(exact_icons, start_with_icons, contains_icons)) seems to bring duplicates also. is the a way to prevent this? – WNB Nov 09 '18 at 13:27