2012-04-09 4 views
1

Я сделать общий шаблон, который будет выведен список объектов из QuerySet:Фильтрация QuerySet на основе захваченных параметров URL в Django?

{% for o in objects %} 
    {{ o.name }} 
{% endfor %} 

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

def display_objects(request, filters, orders, template_name): 
    objects = Object.objects.all() 
    for filter in filters: 
     objects = objects.filter(('%s__%s' % (filter['field'], filter['relationship']), filter['value'])) 
    for order in orders: 
     objects = objects.order_by('-' if 'descending' in order else '' + order['field']) 
    # render objects to template with context 
    pass 

Я не уверен, если то, что я сделал до сих пор даже работать, но я столкнулся с проблемой. Я не знаю, возможно ли отфильтровать запрос, заданный параметром, зафиксированным в URL-адресе, с моей текущей функцией.

Например, если бы я хотел, чтобы отобразить объекты, относящиеся к определенному пользователю, я бы сделать что-то вроде:

(r'^user/(?P<account_username>[^/]+)/$', display_objects, dict(filters=[{'field':'account__username','relationship':'iexact','value':account_username}], orders=[{'field':'foobar'}], template_name='user.html')) 

Очевидно, account_username не определенное поле, пока URL обрабатывается и отправляется в display_objects функция. Было бы легко сделать функцию просмотра, которая принимает параметр account_username, но я хочу иметь возможность использовать эту функцию для отображения других наборов запросов объектов, которые будут отфильтрованы с различными захваченными параметрами.

Есть ли способ передать переданные параметры URL-функции функции просмотра, чтобы динамически фильтровать или заказывать набор запросов для отображения?

ответ

1

Вот один из способов вы можете сделать это:

в urls.py:

(r'^user/(?P<account_username>[^/]+)/$', display_objects, dict(filters=[{'field':'account__username','relationship':'iexact'}], orders=[{'field':'foobar'}], template_name='user.html')) 

А потом в views.py:

def display_objects(request, filters, orders, template_name, **kwargs): 

    objects = Object.objects.all() 
    for filter in filters: 
     objects = objects.filter(('%s__%s' % (filter['field'], filter['relationship']), kwargs.get(filter['field']))) 
    for order in orders: 
     objects = objects.order_by('-' if 'descending' in order else '' + order['field']) 
    # render objects to template with context 
    pass 

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

+0

Как я думал об этом, я понял, что способ, которым я структурировал функцию просмотра, был, вероятно, не оптимальным. Есть ли у вас какие-либо предложения относительно того, как еще вы могли бы динамически фильтровать и заказывать запросы для шаблонов? – mburke13

0

Вы не можете передать строку непосредственно в filter. Вам нужно перевести его в kwargs.

query_string = '%s__%s' % (filter['field'], filter['relationship']) 
objects = objects.filter(**{query_string: filter['value']})) 
+0

Я не уверен, когда это произошло, но его синтаксис работает на 1.4A 'obj.filter (('key', 'value'))'. Поймал меня и охранник, но он принимает ключевые/ценностные кортежи. !? –

+0

Ничего себе. Просто проверил его на 1.3.1 и там тоже работает. –

Смежные вопросы