1

I want to use filter with OR condition in django. For this i want to use Q objects. My code is this

def product(request):
    try:

        proTitle = request.GET.get('title')
        ProDescription = request.GET.get('description')


    except:
        pass


    list0 = []
    result = Product.objects.filter(Q(title__contains=proTitle ) | Q(description__contains=ProDescription ) )

    for res in result:

        list0.append(res.project_id)
    data ={'title result':list0}
    return HttpResponse(json.dumps(data))



return HttpResponse(json.dumps(data), content_type='application/json')

When pass all value that is proTitle,ProDescription it working fine. If any value is going to none it encounter a errorCannot use None as a query value` Why this error occured when i am using OR operator into my queryset

I am also try this

result = Project.objects.filter(title__contains=proTitle) | Project.objects.filter(description__contains=ProDescription )

but same error occured I am unable to understand actually what is the problem

vikrant
  • 81
  • 3
  • 11

3 Answers3

2

You may set the defaults of the get method to something other than None, say empty string:

proTitle = request.GET.get('title', '')
ProDescription = request.GET.get('description', '')
funAria = request.GET.get('funAria', '')
femaleReq = request.GET.get('femaleReq', '')

This is however likely to return all results in the DB when using __contains.

Otherwise you may build the Q functions discarding all None values.

Use this as a guideline: How to dynamically compose an OR query filter in Django?

Community
  • 1
  • 1
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
0

You can build the Q object in a loop, discarding all values that are none. Note that after consideration, it appears that your except will never be reached because get will simply return None if the Get parameter is not present. You can thus replace the try with an if.

The following code assumes that you simply want the unset values to be ignored in the filter.

(This is untested--let me know if you have any issues.)

attributes = (('title', 'title__contains'),
              ('description', 'description__contains'),
              ('funAria', 'functional_area__contains'),
              ('femaleReq', 'female_candidate'))

query_filter = Q() # initialize

for get_param, kw_arg in attributes:
    get_value = request.GET.get(get_param)
    if get_value:
        query_filter |= Q(**{ kw_arg: get_value })

result = Product.objects.filter(query_filter)
brianpck
  • 8,084
  • 1
  • 22
  • 33
0

Your error seems to mean that one of your values is None:

def product(request):
    try:

        proTitle = request.GET.get('title')
        ProDescription = request.GET.get('description')
        funAria = request.GET.get('funAria')
        femaleReq = request.GET.get('femaleReq')
        someIntValue = request.GET.get('someIntValue')

    except:
        pass

    allQs = Q()
    if proTitle is not None: 
        allQs |= Q(title__contains=proTitle )
    if ProDescription is not None:
        allQs |= Q(description__contains=ProDescription )         
    if funAria is not None:
        allQs |= Q(functional_area__contains=funAria )
    if someIntValue is not None:
        allQs |= Q(some_int_value__gte=someIntValue) # no need to convert someIntValue to an int here as long as you are guaranteed it is unique.
    allQs |= Q(female_candidate=femaleReq )
    list0 = []
    result = Product.objects.filter(allQs)
    for res in result:

        list0.append(res.project_id)
    data ={'title result':list0}
    return HttpResponse(json.dumps(data))
2ps
  • 15,099
  • 2
  • 27
  • 47
  • i want to add two more field cost_gte = int(request.GET.get('cost_gte')) cost_lte = int(request.GET.get('cost_lte')) – vikrant Oct 06 '16 at 17:35
  • how can i add.when i am adding this and send no value it gives me error.refrence before assignment – vikrant Oct 06 '16 at 17:36