1

Consider this url:

www.anysite.com/get_count/?sex=5&sex=6&city=5&city=7&job=7&job=8......

For using in dynamic query in view:

model = anyModel.objects.filter(sex=5).filter(sex=6).filter(city=5)....

How can I insert url parameters in this query?

2 Answers 2

7

What about something like this?

model = anyModel.objects
for k,vals in request.GET.lists():
    for v in vals:
        model = model.filter(**{k: v})

Or, if you want to change the type of filter, (to, for example, __contains), you can replace last line with something like:

        model = model.filter(**{"%s__contains" % k: v})

Another alternative, if you want to interpret multiple values for a get variable as an OR, is to use the in comparison:

model = anyModel.objects
for k,vals in request.GET.lists():
    model = model.filter(**{"%s__in" % k: vals})
Sign up to request clarification or add additional context in comments.

7 Comments

.items() should probably be .lists(); .items gets you one value for each key, not a list of values.
Change GET.items() to GET.lists() to make your answer correct.
yep, good point: didn't know about .lists(), I treated GET as it were a dict, while it isn't..
redshadow, many thanks for your help, I have edited your anwser a bit:for k,vals in request.GET.lists(): s = "%s__in" % k q = "[%s]" % (','.join(vals)) model = eval('model.filter(%s__in=%s)'%(k,q)). The ` model = model.filter(**{"%s__in" % k: vals}) ` has syntax error
eval() is evil and introduces a big security risk; just use model = model.filter(**{s : vals}), where ** extracts maps the dict to kwargs..
|
1

The URL dispatcher does not match against GET query parameters, so if you had a URL pattern such as url(r'^get_count$', view, name='get_count'), then you simply reverse the URL and append the GET query, such as:

from django.core.urlresolvers import reverse
from urllib import urlencode

query = (('sex', 5), ('sex', '6'), ('city', 5), ('city', 7))
url = `%s?%s` % (reverse('get_count'), urlencode(query))

You should do this in your view as it gets a bit convoluted to accomplish the same in your templates, unless your going to write static queries, such as:

{% url 'get_content' %}?sex=5&sex=6&city=5&city=7

If your trying to filter a queryset dynamically by inspecting request.GET in your views, then I suggest you have a look at django-filter. It takes no time at all to integrate it and it will sanitize and validate the GET query, the importance of which developers often overlook and introduce security holes. Using it is as simple as passing request.GET to your defined filter and you get the filtered queryset immediately.

1 Comment

Cool.. I didn't know about django-filter.. Anyways, sure, my answer is just on how to apply multiple filters, but then you should validate attribute names in some way..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.