Django: creating a set of requests from a GET request

I have a Django form setup using the GET method. Each value corresponds to the attributes of a Django model. What would be the most elegant way to generate a request? Currently, as I understand it:

def search_items(request): if 'search_name' in request.GET: query_attributes = {} query_attributes['color'] = request.GET.get('color', '') if not query_attributes['color']: del query_attributes['color'] query_attributes['shape'] = request.GET.get('shape', '') if not query_attributes['shape']: del query_attributes['shape'] items = Items.objects.filter(**query_attributes) 

But I'm sure there is a better way to do this.

+3
django django-views django-queryset
source share
4 answers

You can do this with the comp list and the "interested options":

 def search_items(request): if 'search_name' in request.GET: interested_params = ('color', 'shape') query_attrs = dict([(param, val) for param, val in request.GET.iteritems() if param in interested_params and val]) items = Items.objects.filter(**query_attrs) 

Just for fun (aka not really doing this) you can do it on one line:

 def search_items(request): items = Items.objects.filter( **dict([(param, val) for param, val in request.GET.iteritems() if param in ('color', 'shape') and val]) ) if 'search_name' in request.GET else None 
+6
source share

well, the main way that you approach the problem seems to be sound, but the way you wrote it seems a little funny. I would do it like this:

 def search_items(request): if 'search_name' in request.GET: query_attributes = {} color = request.GET.get('color', '') if color: query_attributes['color'] = color shape = request.GET.get('shape', '') if shape: query_attributes['shape'] = shape items = Items.objects.filter(**query_attributes) 
+1
source share

If you want it to be fully dynamic, you can use a little introspection of the model to find out which fields you really can request and filter only their use.

Although this solution will not allow you to use __lookups in GET parameters, I don’t know if you need it.

 def search_items(request): if 'search_name' in request.GET: all_fields = Items._meta.get_all_field_names() filters = [(k, v) for k, v in request.GET.items() if k in all_fields] items = Items.objects.filter(*filters) 
0
source share
 def search_items(request): try: items = Items.objects.filter(**dict([ (F, request.GET[F]) for F in ('color', 'shape') ])) except KeyError: raise Http404 

Suppose the color and shape parameters require GET parameters. A predefined tuple of filtering parameters is preferable for security reasons.

0
source share

All Articles