annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
175
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
2 #
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
3 # Copyright (C) 2010 Sylvain Beucler
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
4 # Copyright ??? Django team
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
5 #
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
6 # This file is part of Savane.
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
7 #
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
8 # Savane is free software: you can redistribute it and/or modify it
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
9 # under the terms of the GNU Affero General Public License as
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
10 # published by the Free Software Foundation, either version 3 of the
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
11 # License, or (at your option) any later version.
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
12 #
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
13 # Savane is distributed in the hope that it will be useful, but
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
16 # Affero General Public License for more details.
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
17 #
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
18 # You should have received a copy of the GNU Affero General Public License
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
20
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
21 from django.db import models
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
22 import operator
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
23 from django.http import HttpResponse
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
24
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
25 # Copy/paste these:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
26 #from django.contrib.admin.views.main import
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
27 #ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, PAGE_VAR,
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
28 #SEARCH_VAR, TO_FIELD_VAR, IS_POPUP_VAR, ERROR_FLAG
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
29 ALL_VAR = 'all'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
30 ORDER_VAR = 'o'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
31 ORDER_TYPE_VAR = 'ot'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
32 PAGE_VAR = 'p'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
33 SEARCH_VAR = 'q'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
34 TO_FIELD_VAR = 't'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
35 IS_POPUP_VAR = 'pop'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
36 ERROR_FLAG = 'e'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
37
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
38 class ChangeList:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
39 """
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
40 Object to pass views configuration to (e.g.: search string, ordering...)
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
41 -Draft-
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
42 """
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
43 def __init__(model_admin, request):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
44 self.query = request.GET.get(SEARCH_VAR, '')
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
45 self.list_display = model_admin.list_display
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
46
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
47 def search(f):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
48 """
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
49 Inspired by Django's admin interface, filter queryset based on GET
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
50 parameters (contrib.admin.views.main.*_VAR):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
51
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
52 - o=N: order by ModelAdmin.display_fields[N]
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
53 - ot=xxx: order type: 'asc' or 'desc'
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
54 - q=xxx: plain text search on ModelAdmin.search_fields (^ -> istartswith, = -> iexact, @ -> search, each word ANDed)
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
55 - everything else: name of a Q filter
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
56
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
57 exceptions:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
58 - p=N: current page
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
59 - all=: disable pagination
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
60 - pop: popup
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
61 - e: error
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
62 - to: ? (related to making JS-friendly PK values?)
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
63
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
64 additional exclusions:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
65 - page: used by django.views.generic.list_detail
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
66
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
67 We could also try and deduce filters from the Model, or avoid
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
68 using some declared parameters as Q filters, or find a better
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
69 idea.
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
70 """
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
71 def _decorator(request, *args, **kwargs):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
72 qs = kwargs['queryset']
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
73 model_admin = kwargs['model_admin']
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
74
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
75 lookup_params = request.GET.copy()
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
76 for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, 'page'):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
77 if lookup_params.has_key(i):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
78 del lookup_params[i]
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
79
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
80 try:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
81 qs = qs.filter(**lookup_params)
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
82 # Naked except! Because we don't have any other way of validating "params".
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
83 # They might be invalid if the keyword arguments are incorrect, or if the
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
84 # values are not in the correct type, so we might get FieldError, ValueError,
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
85 # ValicationError, or ? from a custom field that raises yet something else
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
86 # when handed impossible data.
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
87 except:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
88 return HttpResponse("Erreur: paramètres de recherche invalides.")
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
89 #raise IncorrectLookupParameters
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
90
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
91 # TODO: order - but maybe in another, separate filter?
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
92
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
93 ##
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
94 # Search string
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
95 ##
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
96 def construct_search(field_name):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
97 if field_name.startswith('^'):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
98 return "%s__istartswith" % field_name[1:]
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
99 elif field_name.startswith('='):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
100 return "%s__iexact" % field_name[1:]
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
101 elif field_name.startswith('@'):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
102 return "%s__search" % field_name[1:]
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
103 else:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
104 return "%s__icontains" % field_name
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
105
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
106 query = request.GET.get(SEARCH_VAR, '')
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
107 search_fields = model_admin.search_fields
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
108 if search_fields and query:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
109 for bit in query.split():
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
110 or_queries = [models.Q(**{construct_search(str(field_name)): bit}) for field_name in search_fields]
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
111 qs = qs.filter(reduce(operator.or_, or_queries))
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
112 for field_name in search_fields:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
113 if '__' in field_name:
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
114 qs = qs.distinct()
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
115 break
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
116
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
117 kwargs['queryset'] = qs
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
118
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
119 # TODO: pass order params
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
120 if not kwargs.has_key('extra_context'):
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
121 kwargs['extra_context'] = {}
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
122 kwargs['extra_context']['q'] = query
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
123
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
124 # TODO: move in a clean-up decorator
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
125 del kwargs['model_admin']
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
126 return f(request, *args, **kwargs)
492005721817 Add list of users and groups
Sylvain Beucler <beuc@beuc.net>
parents:
diff changeset
127 return _decorator