Django: Generating a queryset from a GET request

安稳与你 提交于 2019-12-12 09:43:35

问题


I have a Django form setup using GET method. Each value corresponds to attributes of a Django model. What would be the most elegant way to generate the query? Currently this is what I do in the view:

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 pretty sure there's a better way to go about it.


回答1:


You could do it with a list comp and and "interested params" set:

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 don't actually do this) you could do it in 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 



回答2:


well, the basic way you are approaching the problem seems sound, but the way you wrote it out looks a little funny. I'd probably do it this way:

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)



回答3:


If you want it to be fully dynamic, you can use a little bit of model introspection to find out what fields you can actually query, and filter only using those.

Though, this solution won't allow you to use __lookups in GET parameters, 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)



回答4:


def search_items(request):
    try:
        items = Items.objects.filter(**dict([
            (F, request.GET[F]) for F in ('color', 'shape')
        ]))

    except KeyError:
        raise Http404

Suppose 'color' and 'shape' are required GET params. Predefined tuple of filtering params is prefered because of security reasons.



来源:https://stackoverflow.com/questions/4011028/django-generating-a-queryset-from-a-get-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!