I have a problem filtering the data and showing the result in a table...

In my template I have some inputs that I send input values with ajax and then i get the value using request.POST.get() in my views. The problem appears when some fields are empty I receive an error "Cannot use None as a query value"

I want to do something like this but i cannot find a solution

ex. when the request.POST.get is empty that Q to be ignored Can anyone help me? Thanks and sorry for my english

This is my code in my views.py

def api(request):
    a = request.POST.get('a')
    b = request.POST.get('b')
    c = request.POST.get('c')
    d = request.POST.get('d')
    e = request.POST.get('e')
    f = request.POST.get('f')
    g = request.POST.get('g')
    h = request.POST.get('h')
    raport = Test.objects.filter(
        Q(data_test__year__gte=a) &
        Q(data_test__year__lte=b) &
        Q(data_in__isnull=c) &
        Q(data_out__isnull=d) &
        Q(adress__fieldone=e) &
        Q(adress__fieldtwo=f) &
        Q(categoru=g) &
        Q(stare=h) &
        Q(medic=i)
    )
    serializer = TestSerializer(raport, many=True)
    return JsonResponse(serializer.data, safe=False)

1 Answers

2
Willem Van Onsem On Best Solutions

We can make a function that creates a Q-object [Django-doc] for only non-None values, like:

from django.db.models import Q

def q_without_none(**kwargs):
    return Q(**{k: v for k, v in kwargs.items() if v is not None})

or if you want to exclude the empty string as well:

from django.db.models import Q

def q_without_empty(**kwargs):
    return Q(**{k: v for k, v in kwargs.items() if v not in (None, '')})

Then we can construct the query like:

raport_pacient = Pacient.objects.filter(
    q_without_none(
        data_creare_pacient__year__gte=de_la,
        data_creare_pacient__year__lte=pana_la,
        data_iesire__isnull=iesit,
        data_deces__isnull=iesit,
        adresa_pacient__judet__nume_judet=judet,
        adresa_pacient__localitate__nume_localitate=localitate,
        categorie=categorie,
        stare_civila=stare_civila,
        medic=request.user.medic
    )
)

Note: although not really your question, using a JsonResponse with safe=False is, like the name suggests, not very safe. There have been exploits with lists for JSON, so it is usually better to define a dictionary at the top level, for example like:

return JsonResponse({'data': serializer.data})