0

I have a search field named q in a form.When I am searching a member, I want it filter like below

results = Member.objects.filter(Q(mid=q) | Q(mobile=q)).order_by('pub_date')

In other forms I want to do something similar.
such as :

Account.objects.filter(Q(name=q)|Q(card=q)).order_by('pub_date')


I need exactly equal filter, so using django-haystack is overkill.

Simple base form:

class SimpleSearchForm(forms.Form):
    q = forms.CharField(required=False)
    search_fields = []

    def __init__(self, model=None):
        super(SimpleSearchForm, self).__init__()
        if not model:
            raise Exception('SimpleSearchForm need init with a model')

        self.model = model

    def search(self):
        q = self.cleaned_data['q']

        if len(self.search_fields) > 0:
            # construct a Q() statement, filter result and return

But I don't know how to construct such a Q() statement.

Tomasz Jakub Rup
  • 9,464
  • 7
  • 44
  • 47
Mithril
  • 10,339
  • 13
  • 81
  • 121

1 Answers1

1

ok, so if I am getting you right, you are ultimately asking 'how to construct such a Q() statement'.

For making dynamic Q() statements, you may use powerful **kwargs feature. For dynamically making your following query:

results = Member.objects.filter(Q(mid=q) | Q(mobile=q))

Here is the code:

from django.db.models import Q
import operator
predicates = [('mid', q), ('mobile', q)] # You may form this list dynamically as per your requirement
q_list = [Q(x) for x in predicates] # generates a list of Q objects dynamically
results = Member.objects.filter(reduce(operator.or_, q_list)) # to combine all Q objects, reduce and operator python methods are used

In this way, you may make dynamic queries

For more detailed description, visit here

Ali Raza Bhayani
  • 2,445
  • 21
  • 20