Mercurial > hg > savane-forge
view savane/filters.py @ 304:9c66eb6b4bdd
i18n fixes
author | Sylvain Beucler <beuc@beuc.net> |
---|---|
date | Sun, 15 Aug 2010 12:30:16 +0200 |
parents | 492005721817 |
children |
line wrap: on
line source
# -*- coding: utf-8 -*- # # Copyright (C) 2010 Sylvain Beucler # Copyright ??? Django team # # This file is part of Savane. # # Savane is free software: you can redistribute it and/or modify it # under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # Savane is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from django.db import models import operator from django.http import HttpResponse # Copy/paste these: #from django.contrib.admin.views.main import #ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, PAGE_VAR, #SEARCH_VAR, TO_FIELD_VAR, IS_POPUP_VAR, ERROR_FLAG ALL_VAR = 'all' ORDER_VAR = 'o' ORDER_TYPE_VAR = 'ot' PAGE_VAR = 'p' SEARCH_VAR = 'q' TO_FIELD_VAR = 't' IS_POPUP_VAR = 'pop' ERROR_FLAG = 'e' class ChangeList: """ Object to pass views configuration to (e.g.: search string, ordering...) -Draft- """ def __init__(model_admin, request): self.query = request.GET.get(SEARCH_VAR, '') self.list_display = model_admin.list_display def search(f): """ Inspired by Django's admin interface, filter queryset based on GET parameters (contrib.admin.views.main.*_VAR): - o=N: order by ModelAdmin.display_fields[N] - ot=xxx: order type: 'asc' or 'desc' - q=xxx: plain text search on ModelAdmin.search_fields (^ -> istartswith, = -> iexact, @ -> search, each word ANDed) - everything else: name of a Q filter exceptions: - p=N: current page - all=: disable pagination - pop: popup - e: error - to: ? (related to making JS-friendly PK values?) additional exclusions: - page: used by django.views.generic.list_detail We could also try and deduce filters from the Model, or avoid using some declared parameters as Q filters, or find a better idea. """ def _decorator(request, *args, **kwargs): qs = kwargs['queryset'] model_admin = kwargs['model_admin'] lookup_params = request.GET.copy() for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, 'page'): if lookup_params.has_key(i): del lookup_params[i] try: qs = qs.filter(**lookup_params) # Naked except! Because we don't have any other way of validating "params". # They might be invalid if the keyword arguments are incorrect, or if the # values are not in the correct type, so we might get FieldError, ValueError, # ValicationError, or ? from a custom field that raises yet something else # when handed impossible data. except: return HttpResponse("Erreur: paramètres de recherche invalides.") #raise IncorrectLookupParameters # TODO: order - but maybe in another, separate filter? ## # Search string ## def construct_search(field_name): if field_name.startswith('^'): return "%s__istartswith" % field_name[1:] elif field_name.startswith('='): return "%s__iexact" % field_name[1:] elif field_name.startswith('@'): return "%s__search" % field_name[1:] else: return "%s__icontains" % field_name query = request.GET.get(SEARCH_VAR, '') search_fields = model_admin.search_fields if search_fields and query: for bit in query.split(): or_queries = [models.Q(**{construct_search(str(field_name)): bit}) for field_name in search_fields] qs = qs.filter(reduce(operator.or_, or_queries)) for field_name in search_fields: if '__' in field_name: qs = qs.distinct() break kwargs['queryset'] = qs # TODO: pass order params if not kwargs.has_key('extra_context'): kwargs['extra_context'] = {} kwargs['extra_context']['q'] = query # TODO: move in a clean-up decorator del kwargs['model_admin'] return f(request, *args, **kwargs) return _decorator