Satendra
Satendra

Reputation: 6865

How can i set query parameter dynamically to request.GET in Django

OVERVIEW


A url with query parameters looks like.

http://example.api.com/search/?name=jhon&age=26

and on view if i am using django-filter all parameters are automatically extracted from request and it will return a filtered query-set .

views.py

class SearchView(TemplateView):
   template_name = "search.html"

   def get_queryset(self):
       return SearchFilter(request.GET, queryset=Model.objects.all()).qs

   def get_context_data(self, **kwargs):
      context = super(SearchView, self).get_context_data(**kwargs)
      return context

If i want to extract it manually from request.GET i can do.

def get_queryset(self):
   # extracting query parameter 
   q = self.request.GET.get('name')

PROBLEM STATEMENT


My search url looks like

 http://example.api.com/search/jhon-26

I am doing this because i don't want to reveal keys like 'name' and 'age' to public, this is for security abstraction these are the column of my db table .

I am getting jhon-26 in **kwargs, I want to split it and set as query parameter to request.GET so that my filter class will work fine

QUESTION


Is there anything to set attribute to request.GET?

# may be any set function available for this
self.request.GET.set('name', 'jhon')

How can i achieve this.

Upvotes: 10

Views: 25179

Answers (3)

Salad.Guyo
Salad.Guyo

Reputation: 3395

Build your filter dynamically like so;

    query_data={}
    name = request.query_params.get('name')
    age = request.query_params.get('age')
    if name is not None:
        query_data['name'] = name
    if age is not None:
        query_data['age'] = age

    return Model.objects.filter(**query_data)
        

Upvotes: 1

Satendra
Satendra

Reputation: 6865

I found solution to set query parameters to request.GET here

As request.GET QueryDict instance is immutable so we can not modify it directly so for that we need to set its _mutable property to True

if not request.GET._mutable:
   request.GET._mutable = True

# now you can edit it
request.GET['name'] = 'jhon'
request.GET['age'] = 26

Upvotes: 29

yusuf.oguntola
yusuf.oguntola

Reputation: 492

Well, you can do what django-filter does for you by simply saying:

  result = Model.objects.filter(**dict)

However, for request.GET, you'd have to format it to make a valid dictionary since it's values are usually list. You can simply do:

  formatted = {key: dictionary.get(key)[0] for key in dict(request.GET).keys()}

And then you can add the remaining variables into it:

   formatted['age'] = 26 //As extracted from **kwargs. etc.

And then do:

  result = Model.objects.filter(**formatted)

If you do not necessarily need to use request.GET (Since there's a way around what django-filter does), then you can simply form your dictionary and use it in the model's filter method.

By the way, why are you using request.GET if you do not want the public to see your data? How did you form your url? You may want to Ignore all of that as far as your code is working fine anyway!

Upvotes: 2

Related Questions