Ticket #11868: 11868_luke1.diff
File 11868_luke1.diff, 11.7 KB (added by , 13 years ago) |
---|
-
django/contrib/admin/media/css/base.css
diff -r b3394ccce096 django/contrib/admin/media/css/base.css
a b 326 326 background: url(../img/admin/arrow-down.gif) right .4em no-repeat; 327 327 } 328 328 329 table thead th.sorted a span.text { 330 display: block; 331 float: left; 332 } 333 334 table thead th.sorted a span.sortpos { 335 display: block; 336 float: right; 337 font-size: .6em; 338 } 339 340 table thead th.sorted a img { 341 vertical-align: bottom; 342 /* Make it look like a link */ 343 border-bottom: 1px solid #5b80b2; 344 } 345 346 table thead th.sorted a span.clear { 347 display: block; 348 clear: both; 349 } 350 351 #sorting-popup-div { 352 position: absolute; 353 background-color: white; 354 border: 1px solid #ddd; 355 z-index: 2000; /* more than filters on right */ 356 padding-right: 10px; 357 } 358 329 359 /* ORDERABLE TABLES */ 330 360 331 361 table.orderable tbody tr td:hover { -
django/contrib/admin/templates/admin/change_list_results.html
diff -r b3394ccce096 django/contrib/admin/templates/admin/change_list_results.html
a b 1 {% load adminmedia %} 1 2 {% if result_hidden_fields %} 2 3 <div class="hiddenfields">{# DIV for HTML validation #} 3 4 {% for item in result_hidden_fields %}{{ item }}{% endfor %} … … 8 9 <table id="result_list"> 9 10 <thead> 10 11 <tr> 11 {% for header in result_headers %}<th scope="col"{{ header.class_attrib }}> 12 {% if header.sortable %}<a href="{{ header.url }}">{% endif %} 13 {{ header.text|capfirst }} 14 {% if header.sortable %}</a>{% endif %}</th>{% endfor %} 12 {% for header in result_headers %} 13 <th scope="col" {{ header.class_attrib }}> 14 {% if header.sortable %}<a href="{{ header.url }}">{% endif %} 15 <span class="text">{{ header.text|capfirst }}</span> 16 {% if header.sortable %} 17 {% if header.sort_pos > 0 %}<span class="sortpos"> 18 {% if header.sort_pos == 1 %}<img id="primary-sort-icon" src="{% admin_media_prefix %}img/admin/icon_primary_sort.png" alt="Primary sort field" />{% endif %} 19 {{ header.sort_pos }}</span> 20 {% endif %} 21 <span class="clear"></span></a> 22 {% endif %} 23 </th>{% endfor %} 15 24 </tr> 16 25 </thead> 17 26 <tbody> … … 24 33 </tbody> 25 34 </table> 26 35 </div> 36 37 {# Sorting popup: #} 38 <div style="display: none;" id="sorting-popup-div"> 39 <p>Sorting by:</p> 40 <ol> 41 {% for header in result_headers|dictsort:"sort_pos" %} 42 {% if header.sort_pos > 0 %} 43 <li>{{ header.text|capfirst }}</li> 44 {% endif %} 45 {% endfor %} 46 </ol> 47 <p><a href="{{ reset_order_url }}">Reset sorting</a></p> 48 </div> 49 <script type="text/javascript"> 50 <!-- 51 (function($) { 52 $(document).ready(function() { 53 var popup = $('#sorting-popup-div'); 54 /* These next lines seems necessary to prime the popup: */ 55 popup.offset({left:-1000, top:0}); 56 popup.show(); 57 var popupWidth = popup.width() 58 popup.hide(); 59 60 $('#primary-sort-icon').toggle(function(ev) { 61 ev.preventDefault(); 62 var img = $(this); 63 var pos = img.offset(); 64 pos.top += img.height(); 65 if (pos.left + popupWidth > 66 $(window).width()) { 67 pos.left -= popupWidth; 68 } 69 popup.show(); 70 popup.offset(pos); 71 }, 72 function(ev) { 73 ev.preventDefault(); 74 popup.hide(); 75 }); 76 }); 77 })(django.jQuery); 78 //--> 79 </script> 80 27 81 {% endif %} -
django/contrib/admin/templatetags/admin_list.py
diff -r b3394ccce096 django/contrib/admin/templatetags/admin_list.py
a b 93 93 if field_name == 'action_checkbox': 94 94 yield { 95 95 "text": header, 96 "sort_pos": 0, 96 97 "class_attrib": mark_safe(' class="action-checkbox-column"') 97 98 } 98 99 continue … … 100 101 # It is a non-field, but perhaps one that is sortable 101 102 admin_order_field = getattr(attr, "admin_order_field", None) 102 103 if not admin_order_field: 103 yield {"text": header }104 yield {"text": header, "sort_pos": 0 } 104 105 continue 105 106 106 107 # So this _is_ a sortable non-field. Go to the yield … … 110 111 111 112 th_classes = [] 112 113 new_order_type = 'asc' 113 if field_name == cl.order_field or admin_order_field == cl.order_field: 114 th_classes.append('sorted %sending' % cl.order_type.lower()) 115 new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type.lower()] 114 ordering_fields = cl.get_ordering_fields() 115 sort_pos = 0 116 if field_name in ordering_fields or admin_order_field in ordering_fields: 117 if not field_name in ordering_fields: 118 field_name = admin_order_field 119 order_type = ordering_fields.get(field_name).lower() 120 sort_pos = ordering_fields.keys().index(field_name) + 1 121 th_classes.append('sorted %sending' % order_type) 122 new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type] 123 124 # build new ordering param 125 o_list = [] 126 make_qs_param = lambda t, n: ('-' if t == 'desc' else '') + str(n) 127 128 for f in ordering_fields.keys(): 129 try: 130 n = cl.list_display.index(f) 131 except ValueError: 132 continue 133 134 if f == field_name: 135 # We want clicking on this header to bring the ordering to the 136 # front 137 o_list.insert(0, make_qs_param(new_order_type, n)) 138 else: 139 o_list.append(make_qs_param(ordering_fields.get(f), n)) 140 141 if field_name not in ordering_fields: 142 n = cl.list_display.index(field_name) 143 o_list.insert(0, make_qs_param(new_order_type, n)) 144 145 o_list = '.'.join(o_list) 116 146 117 147 yield { 118 148 "text": header, 119 149 "sortable": True, 120 "url": cl.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}), 150 "sort_pos": sort_pos, 151 "url": cl.get_query_string({ORDER_VAR: o_list}), 121 152 "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '') 122 153 } 123 154 … … 231 262 return {'cl': cl, 232 263 'result_hidden_fields': list(result_hidden_fields(cl)), 233 264 'result_headers': list(result_headers(cl)), 265 'reset_order_url': cl.get_query_string(remove=[ORDER_VAR]), 234 266 'results': list(results(cl))} 235 267 236 268 @register.inclusion_tag('admin/date_hierarchy.html') -
django/contrib/admin/views/main.py
diff -r b3394ccce096 django/contrib/admin/views/main.py
a b 3 3 from django.core.exceptions import SuspiciousOperation 4 4 from django.core.paginator import InvalidPage 5 5 from django.db import models 6 from django.utils.datastructures import SortedDict 6 7 from django.utils.encoding import force_unicode, smart_str 7 8 from django.utils.translation import ugettext, ugettext_lazy 8 9 from django.utils.http import urlencode … … 75 76 self.list_editable = () 76 77 else: 77 78 self.list_editable = list_editable 78 self.order _field, self.order_type= self.get_ordering()79 self.ordering = self.get_ordering() 79 80 self.query = request.GET.get(SEARCH_VAR, '') 80 81 self.query_set = self.get_query_set(request) 81 82 self.get_results(request) … … 171 172 # manually-specified ordering from the query string. 172 173 ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name] 173 174 174 if ordering[0].startswith('-'):175 order_field, order_type = ordering[0][1:], 'desc'176 else:177 order_field, order_type = ordering[0], 'asc'178 175 if ORDER_VAR in params: 179 try: 180 field_name = self.list_display[int(params[ORDER_VAR])] 176 # Clear ordering and used params 177 ordering = [] 178 order_params = params[ORDER_VAR].split('.') 179 for p in order_params: 181 180 try: 182 f = lookup_opts.get_field(field_name) 183 except models.FieldDoesNotExist: 184 # See whether field_name is a name of a non-field 185 # that allows sorting. 181 none, pfx, idx = p.rpartition('-') 182 field_name = self.list_display[int(idx)] 186 183 try: 187 if callable(field_name): 188 attr = field_name 189 elif hasattr(self.model_admin, field_name): 190 attr = getattr(self.model_admin, field_name) 191 else: 192 attr = getattr(self.model, field_name) 193 order_field = attr.admin_order_field 194 except AttributeError: 195 pass 196 else: 197 order_field = f.name 198 except (IndexError, ValueError): 199 pass # Invalid ordering specified. Just use the default. 200 if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'): 201 order_type = params[ORDER_TYPE_VAR] 202 return order_field, order_type 184 f = lookup_opts.get_field(field_name) 185 except models.FieldDoesNotExist: 186 # See whether field_name is a name of a non-field 187 # that allows sorting. 188 try: 189 if callable(field_name): 190 attr = field_name 191 elif hasattr(self.model_admin, field_name): 192 attr = getattr(self.model_admin, field_name) 193 else: 194 attr = getattr(self.model, field_name) 195 field_name = attr.admin_order_field 196 except AttributeError: 197 pass 198 else: 199 field_name = f.name 200 201 ordering.append(pfx + field_name) 202 203 except (IndexError, ValueError): 204 pass # Invalid ordering specified. Skip it. 205 206 return ordering 207 208 def get_ordering_fields(self): 209 # Returns a SortedDict of ordering fields and asc/desc 210 ordering_fields = SortedDict() 211 for o in self.ordering: 212 none, t, f = o.rpartition('-') 213 ordering_fields[f] = 'desc' if t == '-' else 'asc' 214 return ordering_fields 203 215 204 216 def get_lookup_params(self, use_distinct=False): 205 217 lookup_params = self.params.copy() # a dictionary of the query string … … 290 302 break 291 303 292 304 # Set ordering. 293 if self.order _field:294 qs = qs.order_by( '%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field))305 if self.ordering: 306 qs = qs.order_by(*self.ordering) 295 307 296 308 # Apply keyword searches. 297 309 def construct_search(field_name):