Permalink
Browse files

queryset-refactor: Merged to [6155]

git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6332 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent c8f6e48 commit fb6a0c8ffa1cd74c63aaf4b011665e5952d449e7 @adrianholovaty adrianholovaty committed Sep 15, 2007
Showing with 717 additions and 100 deletions.
  1. +2 −0 AUTHORS
  2. +5 −1 django/contrib/admin/media/js/urlify.js
  3. +1 −1 django/contrib/admin/templates/admin/change_list_results.html
  4. +1 −1 django/contrib/databrowse/templates/databrowse/calendar_day.html
  5. +1 −1 django/contrib/databrowse/templates/databrowse/calendar_homepage.html
  6. +1 −1 django/contrib/databrowse/templates/databrowse/calendar_main.html
  7. +1 −1 django/contrib/databrowse/templates/databrowse/calendar_month.html
  8. +1 −1 django/contrib/databrowse/templates/databrowse/calendar_year.html
  9. +1 −1 django/contrib/databrowse/templates/databrowse/choice_detail.html
  10. +1 −1 django/contrib/databrowse/templates/databrowse/choice_list.html
  11. +1 −1 django/contrib/databrowse/templates/databrowse/fieldchoice_detail.html
  12. +1 −1 django/contrib/databrowse/templates/databrowse/fieldchoice_homepage.html
  13. +1 −1 django/contrib/databrowse/templates/databrowse/fieldchoice_list.html
  14. +1 −1 django/contrib/databrowse/templates/databrowse/homepage.html
  15. +1 −1 django/contrib/databrowse/templates/databrowse/model_detail.html
  16. +2 −2 django/contrib/databrowse/templates/databrowse/object_detail.html
  17. 0 django/contrib/localflavor/ar/__init__.py
  18. +36 −0 django/contrib/localflavor/ar/ar_provinces.py
  19. +105 −0 django/contrib/localflavor/ar/forms.py
  20. +11 −0 django/core/paginator.py
  21. +1 −0 django/db/models/fields/__init__.py
  22. +8 −6 django/newforms/fields.py
  23. +6 −4 django/newforms/forms.py
  24. +22 −26 django/template/defaulttags.py
  25. +21 −11 django/views/generic/list_detail.py
  26. +21 −6 docs/generic_views.txt
  27. +34 −0 docs/newforms.txt
  28. +3 −0 docs/request_response.txt
  29. +3 −0 docs/sites.txt
  30. +18 −7 docs/templates.txt
  31. +19 −13 docs/templates_python.txt
  32. +5 −3 docs/testing.txt
  33. +4 −0 tests/modeltests/pagination/models.py
  34. +290 −0 tests/regressiontests/forms/localflavor.py
  35. +35 −8 tests/regressiontests/forms/tests.py
  36. +45 −0 tests/regressiontests/forms/util.py
  37. +8 −0 tests/regressiontests/templates/tests.py
View
@@ -127,6 +127,7 @@ answer newbie questions, and generally made Django that much better:
Dimitris Glezos <dimitris@glezos.com>
glin@seznam.cz
martin.glueck@gmail.com
+ Artyom Gnilov <boobsd@gmail.com>
GomoX <gomo@datafull.com>
Mario Gonzalez <gonzalemario@gmail.com>
pradeep.gowda@gmail.com
@@ -240,6 +241,7 @@ answer newbie questions, and generally made Django that much better:
Jan Rademaker
Michael Radziej <mir@noris.de>
Amit Ramon <amit.ramon@gmail.com>
+ Philippe Raoult <philippe.raoult@n2nsoft.com>
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
Brian Ray <http://brianray.chipy.org/>
remco@diji.biz
@@ -40,6 +40,9 @@ var RUSSIAN_MAP = {
'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
'Я':'Ya'
}
+var UKRAINIAN_MAP = {
+ 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
+}
var CZECH_MAP = {
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
'ž':'z'
@@ -51,7 +54,8 @@ ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
ALL_DOWNCODE_MAPS[2]=GREEK_MAP
ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
-ALL_DOWNCODE_MAPS[5]=CZECH_MAP
+ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
+ALL_DOWNCODE_MAPS[6]=CZECH_MAP
var Downcoder = new Object();
Downcoder.Initialize = function()
@@ -10,7 +10,7 @@
</thead>
<tbody>
{% for result in results %}
-<tr class="{% cycle row1,row2 %}">{% for item in result %}{{ item }}{% endfor %}</tr>
+<tr class="{% cycle 'row1' 'row2' %}">{% for item in result %}{{ item }}{% endfor %}</tr>
{% endfor %}
</tbody>
</table>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for field in field_list %}
-<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for year in date_list %}
-<li class="{% cycle odd,even %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for month in date_list %}
-<li class="{% cycle odd,even %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for choice in field.choices %}
-<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for field in field_list %}
-<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
-<li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
+<li class="{% cycle 'odd' 'even' %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
{% endfor %}
</ul>
@@ -7,7 +7,7 @@
{% block content %}
{% for model in model_list %}
- <div class="modelgroup {% cycle even,odd %}">
+ <div class="modelgroup {% cycle 'even' 'odd' %}">
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
<p>
{% for object in model.sample_objects %}
@@ -12,7 +12,7 @@
<ul class="objectlist">
{% for object in model.objects %}
- <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+ <li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
@@ -10,7 +10,7 @@
<table class="objectinfo">
{% for field in object.fields %}
-<tr class="{% cycle odd,even %}">
+<tr class="{% cycle 'odd' 'even' %}">
<th>{{ field.field.verbose_name|capfirst }}</th>
<td>
{% if field.urls %}
@@ -29,7 +29,7 @@
{% if related_object.object_list %}
<ul class="objectlist">
{% for object in related_object.object_list %}
- <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
+ <li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
{% else %}
No changes.
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+"""
+A list of Argentinean provinces and autonomous cities as `choices` in a
+formfield. From
+http://www.argentina.gov.ar/argentina/portal/paginas.dhtml?pagina=425
+
+This exists in this standalone file so that it's only imported into memory
+when explicitly needed.
+"""
+
+PROVINCE_CHOICES = (
+ ('B', u'Buenos Aires'),
+ ('K', u'Catamarca'),
+ ('H', u'Chaco'),
+ ('U', u'Chubut'),
+ ('C', u'Ciudad Autónoma de Buenos Aires'),
+ ('X', u'Córdoba'),
+ ('W', u'Corrientes'),
+ ('E', u'Entre Ríos'),
+ ('P', u'Formosa'),
+ ('Y', u'Jujuy'),
+ ('L', u'La Pampa'),
+ ('F', u'La Rioja'),
+ ('M', u'Mendoza'),
+ ('N', u'Misiones'),
+ ('Q', u'Neuquén'),
+ ('R', u'Río Negro'),
+ ('A', u'Salta'),
+ ('J', u'San Juan'),
+ ('D', u'San Luis'),
+ ('Z', u'Santa Cruz'),
+ ('S', u'Santa Fe'),
+ ('G', u'Santiago del Estero'),
+ ('V', u'Tierra del Fuego, Antártida e Islas del Atlántico Sur'),
+ ('T', u'Tucumán'),
+)
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+"""
+AR-specific Form helpers.
+"""
+
+from django.newforms import ValidationError
+from django.newforms.fields import RegexField, CharField, Select, EMPTY_VALUES
+from django.utils.encoding import smart_unicode
+from django.utils.translation import ugettext
+import re
+
+class ARProvinceSelect(Select):
+ """
+ A Select widget that uses a list of Argentinean provinces/autonomous cities
+ as its choices.
+ """
+ def __init__(self, attrs=None):
+ from ar_provinces import PROVINCE_CHOICES
+ super(ARProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
+
+class ARPostalCodeField(RegexField):
+ """
+ A field that accepts a `classic´ NNNN Postal Code or a CPA.
+
+ See http://www.correoargentino.com.ar/consulta_cpa/home.php
+ """
+ def __init__(self, *args, **kwargs):
+ super(ARPostalCodeField, self).__init__(r'^\d{4}$|^[A-HJ-NP-Za-hj-np-z]\d{4}\D{3}$',
+ min_length=4, max_length=8,
+ error_message=ugettext("Enter a postal code in the format NNNN or ANNNNAAA."),
+ *args, **kwargs)
+
+ def clean(self, value):
+ value = super(ARPostalCodeField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ if len(value) not in (4, 8):
+ raise ValidationError(ugettext("Enter a postal code in the format NNNN or ANNNNAAA."))
+ if len(value) == 8:
+ return u'%s%s%s' % (value[0].upper(), value[1:5], value[5:].upper())
+ return value
+
+class ARDNIField(CharField):
+ """
+ A field that validates `Documento Nacional de Identidad´ (DNI) numbers.
+ """
+ def __init__(self, *args, **kwargs):
+ super(ARDNIField, self).__init__(max_length=10, min_length=7, *args,
+ **kwargs)
+
+ def clean(self, value):
+ """
+ Value can be a string either in the [X]X.XXX.XXX or [X]XXXXXXX formats.
+ """
+ value = super(ARDNIField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ if not value.isdigit():
+ value = value.replace('.', '')
+ if not value.isdigit():
+ raise ValidationError(ugettext("This field requires only numbers."))
+ if len(value) not in (7, 8):
+ raise ValidationError(
+ ugettext("This field requires 7 or 8 digits."))
+
+ return value
+
+class ARCUITField(RegexField):
+ """
+ This field validates a CUIT (Código Único de Identificación Tributaria). A
+ CUIT is of the form XX-XXXXXXXX-V. The last digit is a check digit.
+ """
+ def __init__(self, *args, **kwargs):
+ super(ARCUITField, self).__init__(r'^\d{2}-?\d{8}-?\d$',
+ error_message=ugettext('Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'),
+ *args, **kwargs)
+
+ def clean(self, value):
+ """
+ Value can be either a string in the format XX-XXXXXXXX-X or an
+ 11-digit number.
+ """
+ value = super(ARCUITField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ value, cd = self._canon(value)
+ if self._calc_cd(value) != cd:
+ raise ValidationError(ugettext("Invalid CUIT."))
+ return self._format(value, cd)
+
+ def _canon(self, cuit):
+ cuit = cuit.replace('-', '')
+ return cuit[:-1], cuit[-1]
+
+ def _calc_cd(self, cuit):
+ mults = (5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
+ tmp = sum([m * int(cuit[idx]) for idx, m in enumerate(mults)])
+ return str(11 - tmp % 11)
+
+ def _format(self, cuit, check_digit=None):
+ if check_digit == None:
+ check_digit = cuit[-1]
+ cuit = cuit[:-1]
+ return u'%s-%s-%s' % (cuit[:2], cuit[2:], check_digit)
+
View
@@ -20,6 +20,7 @@ def __init__(self, query_set, num_per_page, orphans=0):
self.num_per_page = num_per_page
self.orphans = orphans
self._hits = self._pages = None
+ self._page_range = None
def validate_page_number(self, page_number):
try:
@@ -83,6 +84,16 @@ def _get_pages(self):
hits = 0
self._pages = hits // self.num_per_page + 1
return self._pages
+
+ def _get_page_range(self):
+ """
+ Returns a 1-based range of pages for iterating through within
+ a template for loop.
+ """
+ if self._page_range is None:
+ self._page_range = range(1, self._pages + 1)
+ return self._page_range
hits = property(_get_hits)
pages = property(_get_pages)
+ page_range = property(_get_page_range)
@@ -855,6 +855,7 @@ def save_file(self, new_data, new_object, original_object, change, rel, save=Tru
def formfield(self, **kwargs):
defaults = {'form_class': forms.ImageField}
+ defaults.update(kwargs)
return super(ImageField, self).formfield(**defaults)
class IntegerField(Field):
View
@@ -335,12 +335,6 @@ def __init__(self, max_length=None, min_length=None, *args, **kwargs):
RegexField.__init__(self, email_re, max_length, min_length,
ugettext(u'Enter a valid e-mail address.'), *args, **kwargs)
-url_re = re.compile(
- r'^https?://' # http:// or https://
- r'(?:[A-Z0-9-]+\.)+[A-Z]{2,6}' # domain
- r'(?::\d+)?' # optional port
- r'(?:/?|/\S+)$', re.IGNORECASE)
-
try:
from django.conf import settings
URL_VALIDATOR_USER_AGENT = settings.URL_VALIDATOR_USER_AGENT
@@ -399,6 +393,14 @@ def clean(self, data):
raise ValidationError(ugettext(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."))
return f
+url_re = re.compile(
+ r'^https?://' # http:// or https://
+ r'(?:(?:[A-Z0-9-]+\.)+[A-Z]{2,6}|' #domain...
+ r'localhost|' #localhost...
+ r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
+ r'(?::\d+)?' # optional port
+ r'(?:/?|/\S+)$', re.IGNORECASE)
+
class URLField(RegexField):
def __init__(self, max_length=None, min_length=None, verify_exists=False,
validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs):
Oops, something went wrong.

0 comments on commit fb6a0c8

Please sign in to comment.