Django: создание набора запросов из запроса GET - PullRequest
3 голосов
/ 25 октября 2010

У меня есть настройка формы Django с использованием метода GET.Каждое значение соответствует атрибутам модели Django.Какой будет самый элегантный способ создания запроса?В настоящее время это то, что я делаю в представлении:

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)

Но я уверен, что есть лучший способ сделать это.

Ответы [ 4 ]

6 голосов
/ 25 октября 2010

Вы можете сделать это с помощью списка comp и набора «заинтересованных параметров»:

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)

Просто для удовольствия (иначе на самом деле не делайте этого) вы можете сделать это в одну строку:

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 
1 голос
/ 25 октября 2010

хорошо, основной подход к проблеме кажется здравым, но то, как вы это записали, выглядит немного забавно. Я бы, наверное, сделал это так:

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)
0 голосов
/ 27 декабря 2010
def search_items(request):
    try:
        items = Items.objects.filter(**dict([
            (F, request.GET[F]) for F in ('color', 'shape')
        ]))

    except KeyError:
        raise Http404

Предположим, что 'color' и 'shape' являются обязательными GET-параметрами.Предопределенный набор параметров фильтрации предпочтителен по соображениям безопасности.

0 голосов
/ 25 октября 2010

Если вы хотите, чтобы он был полностью динамическим, вы можете использовать небольшую интроспекцию модели, чтобы выяснить, какие поля вы действительно можете запрашивать, и фильтровать только по ним.позволяют вам использовать __lookups в параметрах GET, не знаю, нужно ли вам это.

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)
...