1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +00:00

boulder-oracle-sprint: Merged to [4989]

git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@4990 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Boulder Sprinters 2007-04-09 23:39:40 +00:00
parent a9b2c0686d
commit 8ceeb6d8cb
58 changed files with 7375 additions and 3218 deletions

View File

@ -88,11 +88,13 @@ answer newbie questions, and generally made Django that much better:
Dirk Eschler <dirk.eschler@gmx.net>
Marc Fargas <telenieko@telenieko.com>
favo@exoweb.net
Matthew Flanagan <http://wadofstuff.blogspot.com>
Eric Floehr <eric@intellovations.com>
Jorge Gajon <gajon@gajon.org>
gandalf@owca.info
Baishampayan Ghose
martin.glueck@gmail.com
GomoX <gomo@datafull.com>
Simon Greenhill <dev@simon.net.nz>
Owen Griffiths
Espen Grindhaug <http://grindhaug.org/>
@ -106,6 +108,7 @@ answer newbie questions, and generally made Django that much better:
Kieran Holland <http://www.kieranholland.com>
Robert Rock Howard <http://djangomojo.com/>
Jason Huggins <http://www.jrandolph.com/blog/>
Hyun Mi Ae
Tom Insam
Baurzhan Ismagulov <ibr@radix50.net>
jcrasta@gmail.com
@ -119,6 +122,7 @@ answer newbie questions, and generally made Django that much better:
Sune Kirkeby <http://ibofobi.dk/>
Bastian Kleineidam <calvin@debian.org>
Cameron Knight (ckknight)
Martin Kosír <martin@martinkosir.net>
Meir Kriheli <http://mksoft.co.il/>
Bruce Kroeze <http://coderseye.com/>
Joseph Kocherhans
@ -192,6 +196,7 @@ answer newbie questions, and generally made Django that much better:
Ville Säävuori <http://www.unessa.net/>
Tyson Tate <tyson@fallingbullets.com>
thebjorn <bp@datakortet.no>
Zach Thompson <zthompson47@gmail.com>
Tom Tobin
Joe Topjian <http://joe.terrarum.net/geek/code/python/django/>
torne-django@wolfpuppy.org.uk

View File

@ -55,6 +55,7 @@ LANGUAGES = (
('is', gettext_noop('Icelandic')),
('it', gettext_noop('Italian')),
('ja', gettext_noop('Japanese')),
('ko', gettext_noop('Korean')),
('kn', gettext_noop('Kannada')),
('lv', gettext_noop('Latvian')),
('mk', gettext_noop('Macedonian')),

View File

@ -305,7 +305,7 @@ msgstr "Japon
#: conf/global_settings.py:58
msgid "Latvian"
msgstr ""
msgstr "Latvio"
#: conf/global_settings.py:59
msgid "Macedonian"
@ -611,7 +611,7 @@ msgstr "La URL %s no apunta a una imagen v
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
"Los números de teléfono deben guardar el formato XXX-XXX-XXXX format. \"%s\" "
"Los números de teléfono deben guardar el formato XXX-XXX-XXXX. \"%s\" "
"no es válido."
#: core/validators.py:196
@ -726,10 +726,10 @@ msgid "Please enter a valid decimal number with a whole part of at most %s digit
msgid_plural "Please enter a valid decimal number with a whole part of at most %s digits."
msgstr[0] ""
"Por favor, introduzca un número decimal válido con a lo más %s dígito en "
"total."
"su parte entera."
msgstr[1] ""
"Por favor, introduzca un número decimal válido con a lo más %s dígitos en "
"total."
"su parte entera."
#: core/validators.py:426
#, python-format
@ -958,7 +958,7 @@ msgid ""
"digits and underscores)."
msgstr ""
"Requerido. 30 caracteres o menos. Sólo caracteres alfanuméricos (letras, "
"dígutos y guiones bajos)."
"dígitos y guiones bajos)."
#: contrib/auth/models.py:91
msgid "first name"
@ -1107,7 +1107,7 @@ msgstr "Las contrase
#: contrib/auth/forms.py:124
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr ""
"Tu contraseña antígua es incorrecta. Por favor, vuelve a introducirla "
"Tu contraseña antigua es incorrecta. Por favor, vuelve a introducirla "
"correctamente."
#: contrib/comments/models.py:67 contrib/comments/models.py:166
@ -1707,7 +1707,7 @@ msgid ""
msgstr ""
"Ha ocurrido un error. Se ha informado a los administradores del sitio "
"mediante correo electrónico y debería arreglarse en breve. Gracias por su "
"paciencia"
"paciencia."
#: contrib/admin/templates/admin/search_form.html:8
msgid "Go"
@ -1899,7 +1899,7 @@ msgid ""
"the appropriate user."
msgstr ""
"Algo va mal con la instalación de la base de datos. Asegúrate que las tablas "
"necesarias han sido creadas, y que la base de datos puede ser leida por el "
"necesarias han sido creadas, y que la base de datos puede ser leída por el "
"usuario apropiado."
#: contrib/admin/templates/admin/filter.html:2
@ -1912,7 +1912,7 @@ msgid ""
"First, enter a username and password. Then, you'll be able to edit more user "
"options."
msgstr ""
"Primero, introduzca un nombre de usuario y una contraseña. Luego, podrá "
"Primero introduzca un nombre de usuario y una contraseña. Luego podrá "
"editar el resto de opciones del usuario."
#: contrib/admin/templates/admin/auth/user/add_form.html:12
@ -2105,7 +2105,7 @@ msgstr "vista:"
#: contrib/admin/views/doc.py:164
#, python-format
msgid "App %r not found"
msgstr "Applicación %r no encontrada"
msgstr "Aplicación %r no encontrada"
#: contrib/admin/views/doc.py:171
#, python-format
@ -2326,12 +2326,12 @@ msgstr "Cambiar clave: %s"
#: contrib/localflavor/usa/forms.py:17
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
msgstr "Introduzca un código zip en el formato XXXXX o XXXX-XXXX."
msgstr "Introduzca un código postal en el formato XXXXX o XXXX-XXXX."
#: contrib/localflavor/uk/forms.py:18
msgid "Enter a postcode. A space is required between the two postcode parts."
msgstr ""
"Introduzca in código postal. Se necesita un espacio entre las dos partes del "
"Introduzca un código postal. Se necesita un espacio entre las dos partes del "
"código."
#: contrib/sessions/models.py:51

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,118 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-04-06 11:10+0900\n"
"PO-Revision-Date: 2007-04-06 11:15+0900\n"
"Last-Translator: Hyun Mi Ae <happyhyun@gmail.com>\n"
"Language-Team: Korean\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: contrib/admin/media/js/calendar.js:24
#: contrib/admin/media/js/dateparse.js:32
msgid ""
"January February March April May June July August September October November "
"December"
msgstr "1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "일 월 화 수 목 금 토"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "일요일 월요일 화요일 수요일 목요일 금요일 토요일"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
msgstr "이용 가능한 %s"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
msgstr "모두 선택"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
msgstr "추가"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
msgstr "삭제"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
msgid "Chosen %s"
msgstr "선택된 %s"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
msgstr "선택한 후 클릭하세요"
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
msgstr "모두 삭제"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
msgid "Show"
msgstr "보기"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
msgid "Hide"
msgstr "감추기"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Now"
msgstr "현재"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock"
msgstr "시계"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time"
msgstr "시간 선택"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "Midnight"
msgstr "자정"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m."
msgstr "오전 6시"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon"
msgstr "정오"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
msgstr "취소"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today"
msgstr "오늘"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar"
msgstr "달력"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday"
msgstr "어제"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
msgstr "내일"

File diff suppressed because it is too large Load Diff

View File

@ -1732,7 +1732,7 @@ msgstr "Ikke godkjent URL: %s"
#: core/validators.py:206 core/validators.py:208
#, python-format
msgid "The URL %s is a broken link."
msgstr "Internettadresse fører til en side som ikke virker."
msgstr "Internettadresse %s fører til en side som ikke virker."
#: core/validators.py:214
msgid "Enter a valid U.S. state abbreviation."
@ -1881,7 +1881,7 @@ msgid ""
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
"starts with \"%(start)s\".)"
msgstr ""
"\"%(attr)s\" tillegg på linje $(line)s har en ikke godkjent verdi. (Linjen "
"\"%(attr)s\" tillegg på linje %(line)s har en ikke godkjent verdi. (Linjen "
"starter med \"%(start)s\".)"
#: db/models/manipulators.py:302
@ -1892,7 +1892,7 @@ msgstr "%(object)s med %(type)s finnes allerede for angitt %(field)s."
#: db/models/fields/__init__.py:40
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "$(optname)s med %(fieldname)s finnes allerede."
msgstr "%(optname)s med %(fieldname)s finnes allerede."
#: db/models/fields/__init__.py:114 db/models/fields/__init__.py:265
#: db/models/fields/__init__.py:542 db/models/fields/__init__.py:553

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,15 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# VLADO LABATH <vlado@labath.org>, 2005.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: Django 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2005-12-18 19:38-0500\n"
"PO-Revision-Date: 2005-12-18 19:26-0500\n"
"Last-Translator: VLADO LABATH <vlado@labath.org>\n"
"Language-Team: LANGUAGE <sk@li.org>\n"
"POT-Creation-Date: 2007-04-01 19:21+0200\n"
"PO-Revision-Date: 2007-04-03 21:48+0200\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
@ -23,15 +18,15 @@ msgstr "Možný %s"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
msgstr "Vyber všetko"
msgstr "Vybr všetko"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
msgstr "Pridaj"
msgstr "Pridať"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
msgstr "Vymaž"
msgstr "Vymazať"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
@ -40,13 +35,13 @@ msgstr "Vybrané %s"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
msgstr "Vyber si svoju voľbu a klikni"
msgstr "Vyberte položku a kliknite"
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
msgstr "Vyčisti všetko"
msgstr "Odstrániť vybrané"
#: contrib/admin/media/js/dateparse.js:26
#: contrib/admin/media/js/dateparse.js:32
#: contrib/admin/media/js/calendar.js:24
msgid ""
"January February March April May June July August September October November "
@ -55,7 +50,7 @@ msgstr ""
"Január Február Marec Apríl Máj Jún Júl August September Október November "
"December"
#: contrib/admin/media/js/dateparse.js:27
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "Nedeľa Pondelok Utorok Streda Štvrtok Piatok Sobota"
@ -63,49 +58,59 @@ msgstr "Nedeľa Pondelok Utorok Streda Štvrtok Piatok Sobota"
msgid "S M T W T F S"
msgstr "N P U S Š P S"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
msgid "Show"
msgstr "Zobraziť"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
msgid "Hide"
msgstr "Skryť"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Now"
msgstr "Práve teraz"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock"
msgstr "Hodiny"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time"
msgstr "Vyber čas"
msgstr "Vybr čas"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "Midnight"
msgstr "Polnoc"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m."
msgstr "6 ráno"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon"
msgstr "Poludnie"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
msgstr "Zruš"
msgstr "Zruš"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today"
msgstr "Dnes"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar"
msgstr "Kalendár"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday"
msgstr "Včera"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
msgstr "Zajtra"

View File

@ -26,7 +26,7 @@ form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; }
form .aligned table p { margin-left:0; padding-left:0; }
form .aligned p.help { padding-left:38px; }
.aligned .vCheckboxLabel { float:none !important; display:inline; padding-left:4px; }
.colM .aligned .vLargeTextField, colM .aligned .vXMLLargeTextField { width:610px; }
.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { width:610px; }
.checkbox-row p.help { margin-left:0; padding-left:0 !important; }
/* WIDE FIELDSETS */

View File

@ -38,6 +38,7 @@ class Permission(models.Model):
name = models.CharField(_('name'), maxlength=50)
content_type = models.ForeignKey(ContentType)
codename = models.CharField(_('codename'), maxlength=100)
class Meta:
verbose_name = _('permission')
verbose_name_plural = _('permissions')
@ -56,10 +57,12 @@ class Group(models.Model):
"""
name = models.CharField(_('name'), maxlength=80, unique=True)
permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL)
class Meta:
verbose_name = _('group')
verbose_name_plural = _('groups')
ordering = ('name',)
class Admin:
search_fields = ('name',)
@ -95,16 +98,18 @@ class User(models.Model):
is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site."))
is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts."))
is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))
last_login = models.DateTimeField(_('last login'), default=models.LazyDate())
date_joined = models.DateTimeField(_('date joined'), default=models.LazyDate())
last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now)
date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now)
groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True,
help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."))
user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, filter_interface=models.HORIZONTAL)
objects = UserManager()
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
ordering = ('username',)
class Admin:
fields = (
(None, {'fields': ('username', 'password')}),

View File

@ -0,0 +1,17 @@
"""
An alphabetical list of states for use as `choices` in a formfield.
This exists in this standalone file so that it's only imported into memory
when explicitly needed.
"""
STATE_CHOICES = (
('ACT', 'Australian Capital Territory'),
('NSW', 'New South Wales'),
('NT', 'Northern Territory'),
('QLD', 'Queensland'),
('SA', 'South Australia'),
('TAS', 'Tasmania'),
('VIC', 'Victoria'),
('WA', 'Western Australia'),
)

View File

@ -0,0 +1,43 @@
"""
Australian-specific Form helpers
"""
from django.newforms import ValidationError
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
from django.newforms.util import smart_unicode
from django.utils.translation import gettext
import re
PHONE_DIGITS_RE = re.compile(r'^(\d{10})$')
class AUPostCodeField(RegexField):
"""Australian post code field."""
def __init__(self, *args, **kwargs):
super(AUPostCodeField, self).__init__(r'^\d{4}$',
max_length=None, min_length=None,
error_message=gettext(u'Enter a 4 digit post code.'),
*args, **kwargs)
class AUPhoneNumberField(Field):
"""Australian phone number field."""
def clean(self, value):
"""Validate a phone number. Strips parentheses, whitespace and
hyphens.
"""
super(AUPhoneNumberField, self).clean(value)
if value in EMPTY_VALUES:
return u''
value = re.sub('(\(|\)|\s+|-)', '', smart_unicode(value))
phone_match = PHONE_DIGITS_RE.search(value)
if phone_match:
return u'%s' % phone_match.group(1)
raise ValidationError(u'Phone numbers must contain 10 digits.')
class AUStateSelect(Select):
"""
A Select widget that uses a list of Australian states/territories as its
choices.
"""
def __init__(self, attrs=None):
from au_states import STATE_CHOICES # relative import
super(AUStateSelect, self).__init__(attrs, choices=STATE_CHOICES)

View File

@ -1,11 +1,9 @@
# -*- coding: utf-8 -*-
"""
A brazilian mapping of state misspellings/abbreviations to normalized
abbreviations, and an alphabetical list of states for use as `choices
in a formfield.
An alphabetical list of Brazilian states for use as `choices` in a formfield.
This exists in this standalone file so that it's only imported into
memory when explicitly needed.
This exists in this standalone file so that it's only imported into memory
when explicitly needed.
"""
STATE_CHOICES = (

View File

@ -43,10 +43,9 @@ class DEIdentityCardNumberField(Field):
parameter = 7
for i in range(len(given_number)):
fragment = str(int(given_number[i])*parameter)
fragment = str(int(given_number[i]) * parameter)
if fragment.isalnum():
calculated_checksum += int(fragment[-1])
if parameter == 1:
parameter = 7
elif parameter == 3:
@ -54,34 +53,27 @@ class DEIdentityCardNumberField(Field):
elif parameter ==7:
parameter = 3
if str(calculated_checksum)[-1] == given_checksum:
return True
return False
return str(calculated_checksum)[-1] == given_checksum
def clean(self, value):
super(DEIdentityCardNumberField, self).clean(value)
error_msg = gettext(u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format')
error_msg = gettext(u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.')
if value in EMPTY_VALUES:
return u''
match = re.match(id_re, value)
if not match:
raise ValidationError(error_msg)
residence, origin, birthday, validity, checksum = \
match.groupdict()['residence'], match.groupdict()['origin'], \
match.groupdict()['birthday'], match.groupdict()['validity'], \
match.groupdict()['checksum']
gd = match.groupdict()
residence, origin = gd['residence'], gd['origin']
birthday, validity, checksum = gd['birthday'], gd['validity'], gd['checksum']
if residence == '0000000000' or \
birthday == '0000000' or \
validity == '0000000':
if residence == '0000000000' or birthday == '0000000' or validity == '0000000':
raise ValidationError(error_msg)
all_digits = "%s%s%s%s" % (residence, birthday, validity, checksum)
if not self.has_valid_checksum(residence) or \
not self.has_valid_checksum(birthday) or \
not self.has_valid_checksum(validity) or \
not self.has_valid_checksum(all_digits):
if not self.has_valid_checksum(residence) or not self.has_valid_checksum(birthday) or \
not self.has_valid_checksum(validity) or not self.has_valid_checksum(all_digits):
raise ValidationError(error_msg)
return u'%s%s-%s-%s-%s' % (residence, origin, birthday, validity, checksum)

View File

@ -35,13 +35,11 @@ class FISocialSecurityNumber(Field):
(\d{2}))
[A+-]
(?P<serial>(\d{3}))
(?P<chechsum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE)
(?P<checksum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE)
if not result:
raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))
checksum = int(result.groupdict()['date'] + result.groupdict()['serial'])
if checkmarks[checksum % len(checkmarks)] == result.groupdict()['chechsum'].upper():
gd = result.groupdict()
checksum = int(gd['date'] + gd['serial'])
if checkmarks[checksum % len(checkmarks)] == gd['checksum'].upper():
return u'%s' % value.upper()
raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))

View File

@ -439,30 +439,10 @@ get_sql_initial_data.help_doc = "RENAMED: see 'sqlcustom'"
get_sql_initial_data.args = ''
def get_sql_sequence_reset(app):
"Returns a list of the SQL statements to reset PostgreSQL sequences for the given app."
"Returns a list of the SQL statements to reset sequences for the given app."
from django.db import backend, models
output = []
for model in models.get_models(app):
for f in model._meta.fields:
if isinstance(f, models.AutoField):
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD('%s_%s_seq' % (model._meta.db_table, f.column)),
style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(backend.quote_name(f.column)),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(backend.quote_name(model._meta.db_table))))
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD('%s_id_seq' % f.m2m_db_table()),
style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(backend.quote_name('id')),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
return output
get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting PostgreSQL sequences for the given app name(s)."
return backend.get_sql_sequence_reset(style, models.get_models(app))
get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting sequences for the given app name(s)."
get_sql_sequence_reset.args = APP_ARGS
def get_sql_indexes(app):
@ -843,11 +823,12 @@ def startapp(app_name, directory):
# Determine the project_name a bit naively -- by looking at the name of
# the parent directory.
project_dir = os.path.normpath(os.path.join(directory, '..'))
project_name = os.path.basename(project_dir)
if app_name == os.path.basename(directory):
parent_dir = os.path.basename(project_dir)
project_name = os.path.basename(directory)
if app_name == project_name:
sys.stderr.write(style.ERROR("Error: You cannot create an app with the same name (%r) as your project.\n" % app_name))
sys.exit(1)
_start_helper('app', app_name, directory, project_name)
_start_helper('app', app_name, directory, parent_dir)
startapp.help_doc = "Creates a Django app directory structure for the given app name in the current directory."
startapp.args = "[appname]"
@ -1367,12 +1348,13 @@ def load_data(fixture_labels, verbosity=1):
"Installs the provided fixture file(s) as data in the database."
from django.db.models import get_apps
from django.core import serializers
from django.db import connection, transaction
from django.db import connection, transaction, backend
from django.conf import settings
import sys
# Keep a count of the installed objects and fixtures
count = [0,0]
models = set()
humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
@ -1435,6 +1417,7 @@ def load_data(fixture_labels, verbosity=1):
objects = serializers.deserialize(format, fixture)
for obj in objects:
count[0] += 1
models.add(obj.object.__class__)
obj.save()
label_found = True
except Exception, e:
@ -1456,6 +1439,12 @@ def load_data(fixture_labels, verbosity=1):
else:
if verbosity > 0:
print "Installed %d object(s) from %d fixture(s)" % tuple(count)
sequence_sql = backend.get_sql_sequence_reset(style, models)
if sequence_sql:
if verbosity > 1:
print "Resetting sequences"
for line in sequence_sql:
cursor.execute(line)
transaction.commit()
transaction.leave_transaction_management()

View File

@ -156,7 +156,7 @@ def get_start_transaction_sql():
def get_autoinc_sql(table):
return None
def get_sql_flush(sql_styler, full_table_list):
def get_sql_flush(style, tables, sequences):
"""Return a list of SQL statements required to remove all data from
all tables in the database (without actually removing the tables
themselves) and put the database in an empty 'initial' state
@ -165,9 +165,14 @@ def get_sql_flush(sql_styler, full_table_list):
# TODO - SQL not actually tested against ADO MSSQL yet!
# TODO - autoincrement indices reset required? See other get_sql_flush() implementations
sql_list = ['%s %s;' % \
(sql_styler.SQL_KEYWORD('TRUNCATE'),
sql_styler.SQL_FIELD(quote_name(table))
) for table in full_table_list]
(style.SQL_KEYWORD('TRUNCATE'),
style.SQL_FIELD(quote_name(table))
) for table in tables]
def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []
OPERATOR_MAPPING = {
'exact': '= %s',

View File

@ -40,5 +40,6 @@ get_deferrable_sql = complain
get_fulltext_search_sql = complain
get_drop_foreignkey_sql = complain
get_sql_flush = complain
get_sql_sequence_reset = complain
OPERATOR_MAPPING = {}

View File

@ -233,6 +233,11 @@ def get_sql_flush(style, tables, sequences):
else:
return []
def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []
OPERATOR_MAPPING = {
'exact': '= %s',
'iexact': 'LIKE %s',

View File

@ -217,6 +217,11 @@ def get_sql_flush(style, tables, sequences):
else:
return []
def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []
OPERATOR_MAPPING = {
'exact': '= %s',
'iexact': 'LIKE %s',

View File

@ -81,7 +81,6 @@ class FormatStylePlaceholderCursor(Database.Cursor):
you'll need to use "%%s".
"""
def _rewrite_args(self, query, params=None):
from django.db.models import LazyDate
if params is None:
params = []
else:
@ -92,8 +91,6 @@ class FormatStylePlaceholderCursor(Database.Cursor):
params[i] = param.encode('utf-8')
except UnicodeError:
params[i] = str(param)
if type(param) == LazyDate:
params[i] = param.__get_value__()
args = [(':arg%d' % i) for i in range(len(params))]
query = query % tuple(args)
# cx_Oracle cannot execute a query with the closing ';'
@ -226,6 +223,11 @@ def get_sequence_name(table):
name_length = get_max_name_length() - 3
return '%s_SQ' % util.truncate_name(table, name_length).upper()
def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# TODO: Run ALTER statements to reset Oracle sequence w/out dropping it.
return []
def get_trigger_name(table):
name_length = get_max_name_length() - 3
return '%s_TR' % util.truncate_name(table, name_length).upper()

View File

@ -231,6 +231,31 @@ def get_sql_flush(style, tables, sequences):
else:
return []
def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
from django.db import models
output = []
for model in model_list:
for f in model._meta.fields:
if isinstance(f, models.AutoField):
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD('%s_%s_seq' % (model._meta.db_table, f.column)),
style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(quote_name(model._meta.db_table))))
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD('%s_id_seq' % f.m2m_db_table()),
style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('id')),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
return output
# Register these custom typecasts, because Django expects dates/times to be
# in Python's native (standard-library) datetime/time format, whereas psycopg
# use mx.DateTime by default.

View File

@ -188,6 +188,31 @@ def get_sql_flush(style, tables, sequences):
else:
return []
def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
from django.db import models
output = []
for model in model_list:
for f in model._meta.fields:
if isinstance(f, models.AutoField):
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD('%s_%s_seq' % (model._meta.db_table, f.column)),
style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name(f.column)),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(quote_name(model._meta.db_table))))
break # Only one AutoField is allowed per model, so don't bother continuing.
for f in model._meta.many_to_many:
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
(style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD('%s_id_seq' % f.m2m_db_table()),
style.SQL_KEYWORD('SELECT'),
style.SQL_FIELD(quote_name('id')),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
return output
OPERATOR_MAPPING = {
'exact': '= %s',
'iexact': 'ILIKE %s',

View File

@ -188,6 +188,11 @@ def get_sql_flush(style, tables, sequences):
# get_sql_flush() implementations). Just return SQL at this point
return sql
def get_sql_sequence_reset(style, model_list):
"Returns a list of the SQL statements to reset sequences for the given models."
# No sequence reset required
return []
def _sqlite_date_trunc(lookup_type, dt):
try:
dt = util.typecast_timestamp(dt)

View File

@ -27,32 +27,3 @@ def permalink(func):
viewname = bits[0]
return reverse(bits[0], None, *bits[1:3])
return inner
class LazyDate(object):
"""
Use in limit_choices_to to compare the field to dates calculated at run time
instead of when the model is loaded. For example::
... limit_choices_to = {'date__gt' : models.LazyDate(days=-3)} ...
which will limit the choices to dates greater than three days ago.
"""
def __init__(self, **kwargs):
self.delta = datetime.timedelta(**kwargs)
def __str__(self):
return str(self.__get_value__())
def __repr__(self):
return "<LazyDate: %s>" % self.delta
def __get_value__(self):
return (datetime.datetime.now() + self.delta).date()
def __getattr__(self, attr):
if attr == 'delta':
# To fix ticket #3377. Note that normal accesses to LazyDate.delta
# (after construction) will still work, because they don't go
# through __getattr__). This is mainly needed for unpickling.
raise AttributeError
return getattr(self.__get_value__(), attr)

View File

@ -782,7 +782,7 @@ class PhoneNumberField(IntegerField):
validators.isValidPhone(field_data, all_data)
def formfield(self, **kwargs):
from django.contrib.localflavor.usa.forms import USPhoneNumberField
from django.contrib.localflavor.us.forms import USPhoneNumberField
defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
defaults.update(kwargs)
return USPhoneNumberField(**defaults)

View File

@ -855,6 +855,8 @@ def parse_lookup(kwarg_items, opts):
# all uses of None as a query value.
if lookup_type != 'exact':
raise ValueError, "Cannot use None as a query value"
elif callable(value):
value = value()
joins2, where2, params2 = lookup_inner(path, lookup_type, value, opts, opts.db_table, None)
joins.update(joins2)

View File

@ -121,6 +121,12 @@ class FileInput(Input):
input_type = 'file'
class Textarea(Widget):
def __init__(self, attrs=None):
# The 'rows' and 'cols' attributes are required for HTML correctness.
self.attrs = {'cols': '40', 'rows': '10'}
if attrs:
self.attrs.update(attrs)
def render(self, name, value, attrs=None):
if value is None: value = ''
value = smart_unicode(value)

View File

@ -132,6 +132,7 @@ class RssFeed(SyndicationFeed):
handler.addQuickElement(u"category", cat)
if self.feed['feed_copyright'] is not None:
handler.addQuickElement(u"copyright", self.feed['feed_copyright'])
handler.addQuickElement(u"lastBuildDate", rfc2822_date(self.latest_post_date()).decode('ascii'))
self.write_items(handler)
self.endChannelElement(handler)
handler.endElement(u"rss")

View File

@ -144,6 +144,7 @@ def technical_404_response(request, exception):
t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template')
c = Context({
'root_urlconf': settings.ROOT_URLCONF,
'request_path': request.path[1:], # Trim leading slash
'urlpatterns': tried,
'reason': str(exception),
'request': request,
@ -591,7 +592,7 @@ TECHNICAL_404_TEMPLATE = """
<li>{{ pattern|escape }}</li>
{% endfor %}
</ol>
<p>The current URL, <code>{{ request.path|escape }}</code>, didn't match any of these.</p>
<p>The current URL, <code>{{ request_path|escape }}</code>, didn't match any of these.</p>
{% else %}
<p>{{ reason|escape }}</p>
{% endif %}

View File

@ -1,8 +1,8 @@
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.template import loader, RequestContext
from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseGone
def direct_to_template(request, template, extra_context={}, **kwargs):
def direct_to_template(request, template, extra_context={}, mimetype=None, **kwargs):
"""
Render a given template with any extra URL parameters in the context as
``{{ params }}``.
@ -13,7 +13,9 @@ def direct_to_template(request, template, extra_context={}, **kwargs):
dictionary[key] = value()
else:
dictionary[key] = value
return render_to_response(template, dictionary, context_instance=RequestContext(request))
c = RequestContext(request, dictionary)
t = loader.get_template(template)
return HttpResponse(t.render(c), mimetype=mimetype)
def redirect_to(request, url, **kwargs):
"""

View File

@ -29,6 +29,9 @@ Generally, when working on a single Django project, it's easier to use
``--settings`` command line option, if you need to switch between multiple
Django settings files.
The command-line examples throughout this document use ``django-admin.py`` to
be consistent, but any example can use ``manage.py`` just as well.
Usage
=====
@ -106,7 +109,8 @@ application(s).
By default, the database will be dumped in JSON format. If you want the output
to be in another format, use the ``--format`` option (e.g., ``format=xml``).
You may specify any Django serialization backend (including any user specified
serialization backends named in the ``SERIALIZATION_MODULES`` setting).
serialization backends named in the ``SERIALIZATION_MODULES`` setting). The
``--indent`` option can be used to pretty-print the output.
If no application name is provided, all installed applications will be dumped.
@ -217,6 +221,8 @@ one fixture can reference data in another fixture. If the database backend
supports row-level constraints, these constraints will be checked at the
end of the transaction.
The ``dumpdata`` command can be used to generate input for ``loaddata``.
.. admonition:: MySQL and Fixtures
Unfortunately, MySQL isn't capable of completely supporting all the
@ -366,7 +372,7 @@ Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given appnames.
sqlsequencereset [appname appname ...]
----------------------------------------------
Prints the SQL statements for resetting PostgreSQL sequences for the given
Prints the SQL statements for resetting sequences for the given
appnames.
See http://simon.incutio.com/archive/2004/04/21/postgres for more information.
@ -512,7 +518,8 @@ and `2` is verbose output.
------------
Example usage::
django-admin.py manage.py --adminmedia=/tmp/new-admin-style/
django-admin.py --adminmedia=/tmp/new-admin-style/
Tells Django where to find the various CSS and JavaScript files for the admin
interface when running the development server. Normally these files are served

View File

@ -42,25 +42,25 @@ On the Web
The most recent version of the Django documentation lives at
http://www.djangoproject.com/documentation/ . These HTML pages are generated
automatically from the text files in source control every 15 minutes. That
means they reflect the "latest and greatest" in Django -- they include the very
latest corrections and additions, and they discuss the latest Django features,
automatically from the text files in source control. That means they reflect
the "latest and greatest" in Django -- they include the very latest
corrections and additions, and they discuss the latest Django features,
which may only be available to users of the Django development version. (See
"Differences between versions" below.)
A key advantage of the Web-based documentation is the comment section at the
bottom of each document. This is an area for anybody to submit changes,
corrections and suggestions about the given document. The Django developers
frequently monitor the comments there and use them to improve the documentation
for everybody.
We encourage you to help improve the docs by submitting changes, corrections
and suggestions in the `ticket system`_. The Django developers actively monitor
the ticket system and use your feedback to improve the documentation for
everybody.
We encourage you to help improve the docs: it's easy! Note, however, that
comments should explicitly relate to the documentation, rather than asking
broad tech-support questions. If you need help with your particular Django
setup, try the `django-users mailing list`_ instead of posting a comment to the
documentation.
Note, however, that tickets should explicitly relate to the documentation,
rather than asking broad tech-support questions. If you need help with your
particular Django setup, try the `django-users mailing list`_ or the
`#django IRC channel`_ instead.
.. _ticket system: http://code.djangoproject.com/simpleticket?component=Documentation
.. _django-users mailing list: http://groups.google.com/group/django-users
.. _#django IRC channel: irc://irc.freenode.net/django
In plain text
-------------
@ -134,14 +134,6 @@ We follow this policy:
frozen document that says "These docs are frozen for Django version XXX"
and links to the current version of that document.
* Once a document is frozen for a Django release, we remove comments from
that page, in favor of having comments on the latest version of that
document. This is for the sake of maintainability and usability, so that
users have one, and only one, place to leave comments on a particular
document. We realize that some people may be stuck on a previous version
of Django, but we believe the usability problems with multiple versions
of a document the outweigh the benefits.
* The `main documentation Web page`_ includes links to documentation for
all previous versions.

View File

@ -39,11 +39,11 @@ Auto-generate the models
Django comes with a utility that can create models by introspecting an existing
database. You can view the output by running this command::
django-admin.py inspectdb --settings=path.to.settings
python manage.py inspectdb
Save this as a file by using standard Unix output redirection::
django-admin.py inspectdb --settings=path.to.settings > models.py
python manage.py inspectdb > models.py
This feature is meant as a shortcut, not as definitive model generation. See
the `django-admin.py documentation`_ for more information.
@ -60,7 +60,7 @@ Install the core Django tables
Next, run the ``manage.py syncdb`` command to install any extra needed database
records such as admin permissions and content types::
django-admin.py init --settings=path.to.settings
python manage.py syncdb
See whether it worked
=====================

View File

@ -734,10 +734,10 @@ relationship should work. All are optional:
``limit_choices_to`` A dictionary of lookup arguments and values (see
the `Database API reference`_) that limit the
available admin choices for this object. Use this
with ``models.LazyDate`` to limit choices of objects
by date. For example::
with functions from the Python ``datetime`` module
to limit choices of objects by date. For example::
limit_choices_to = {'pub_date__lte': models.LazyDate()}
limit_choices_to = {'pub_date__lte': datetime.now}
only allows the choice of related objects with a
``pub_date`` before the current date/time to be

View File

@ -57,17 +57,16 @@ on it, you'll need to tell mod_python::
.. caution::
Is you are using Windows, remember that the path will contain backslashes.
If you're using Windows, remember that the path will contain backslashes.
This string is passed through Python's string parser twice, so you need to
escape each backslash **twice**::
PythonPath "['c:\\\\path\\\\to\\\\project'] + sys.path"
or use raw strings::
Or, use raw strings::
PythonPath "[r'c:\\path\\to\\project'] + sys.path"
You can also add directives such as ``PythonAutoReload Off`` for performance.
See the `mod_python documentation`_ for a full list of options.
@ -161,7 +160,7 @@ If, however, you have no option but to serve media files on the same Apache
``VirtualHost`` as Django, here's how you can turn off mod_python for a
particular part of the site::
<Location "/media/">
<Location "/media">
SetHandler None
</Location>
@ -178,7 +177,7 @@ the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location>
<Location "media">
<Location "/media">
SetHandler None
</Location>

View File

@ -483,8 +483,8 @@ In order to use the ``Http404`` exception to its fullest, you should create a
template that is displayed when a 404 error is raised. This template should be
called ``404.html`` and located in the top level of your template tree.
Customing error views
---------------------
Customizing error views
-----------------------
The 404 (page not found) view
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -114,6 +114,9 @@ Note:
`object-relational mapper`_, ``items()`` doesn't have to return model
instances. Although you get a few bits of functionality "for free" by
using Django models, ``items()`` can return any type of object you want.
* If you're creating an Atom feed, rather than an RSS feed, set the
``subtitle`` attribute instead of the ``description`` attribute. See
`Publishing Atom and RSS feeds in tandem`_, later, for an example.
One thing's left to do. In an RSS feed, each ``<item>`` has a ``<title>``,
``<link>`` and ``<description>``. We need to tell the framework what data to
@ -298,7 +301,7 @@ Publishing Atom and RSS feeds in tandem
---------------------------------------
Some developers like to make available both Atom *and* RSS versions of their
feeds. That's easy to do with Django: Just create a subclass of your ``feed``
feeds. That's easy to do with Django: Just create a subclass of your ``Feed``
class and set the ``feed_type`` to something different. Then update your
URLconf to add the extra versions.
@ -318,6 +321,20 @@ Here's a full example::
class AtomSiteNewsFeed(RssSiteNewsFeed):
feed_type = Atom1Feed
subtitle = RssSiteNewsFeed.description
.. Note::
In this example, the RSS feed uses a ``description`` while the Atom feed
uses a ``subtitle``. That's because Atom feeds don't provide for a
feed-level "description," but they *do* provide for a "subtitle."
If you provide a ``description`` in your ``Feed`` class, Django will *not*
automatically put that into the ``subtitle`` element, because a subtitle
and description are not necessarily the same thing. Instead, you should
define a ``subtitle`` attribute.
In the above example, we simply set the Atom feed's ``subtitle`` to the
RSS feed's ``description``, because it's quite short already.
And the accompanying URLconf::

View File

@ -61,8 +61,8 @@ tutorial, remember?) You should see the Django admin index page:
:alt: Django admin index page
:target: http://media.djangoproject.com/img/doc/tutorial/admin02.png
By default, you should see two types of editable content: groups and users.
These are core features Django ships with by default.
You should see a few other types of editable content, including groups, users
and sites. These are core features Django ships with by default.
.. _"I can't log in" questions: ../faq/#the-admin-site

View File

@ -192,10 +192,11 @@ The remaining arguments should be tuples in this format::
url
---
**New in development version**
The ``url()`` function can be used instead of a tuple as an argument to
``patterns()``. This is convenient if you wish to specify a name without the
**New in Django development version**
You can use the ``url()`` function, instead of a tuple, as an argument to
``patterns()``. This is convenient if you want to specify a name without the
optional extra arguments dictionary. For example::
urlpatterns = patterns('',
@ -498,26 +499,40 @@ the view prefix (as explained in "The view prefix" above) will have no effect.
Naming URL patterns
===================
**New in development version**
**New in Django development version**
It is fairly common to use the same view function in multiple URL patterns in
your URLConf. This leads to problems when you come to do reverse URL matching,
because the ``permalink()`` decorator and ``{% url %}`` template tag use the
name of the view function to find a match.
It's fairly common to use the same view function in multiple URL patterns in
your URLconf. For example, these two URL patterns both point to the ``archive``
view::
To solve this problem, you can give a name to each of your URL patterns in
order to distinguish them from other patterns using the same views and
parameters. You can then use this name wherever you would otherwise use the
name of the view function. For example, if you URLConf contains::
urlpatterns = patterns('',
(r'/archive/(\d{4})/$', archive),
(r'/archive-summary/(\d{4})/$', archive, {'summary': True}),
)
This is completely valid, but it leads to problems when you try to do reverse
URL matching (through the ``permalink()`` decorator or the ``{% url %}``
template tag). Continuing this example, if you wanted to retrieve the URL for
the ``archive`` view, Django's reverse URL matcher would get confused, because
*two* URLpatterns point at that view.
To solve this problem, Django supports **named URL patterns**. That is, you can
give a name to a URL pattern in order to distinguish it from other patterns
using the same view and parameters. Then, you can use this name in reverse URL
matching.
Here's the above example, rewritten to used named URL patterns::
urlpatterns = patterns('',
url(r'/archive/(\d{4})/$', archive, name="full-archive"),
url(r'/archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
)
...you could refer to either the summary archive view in a template as::
With these names in place (``full-archive`` and ``arch-summary``), you can
target each pattern individually by using its name::
{% url arch-summary 1945 %}
{% url full-archive 2007 %}
Even though both URL patterns refer to the ``archive`` view here, using the
``name`` parameter to ``url()`` allows you to tell them apart in templates.
@ -527,11 +542,12 @@ not restricted to valid Python names.
.. note::
Make sure that when you name your URLs, you use names that are unlikely to
clash with any other application's choice of names. If you call your URL
pattern *comment* and another application does the same thing, there is no
guarantee which URL will be inserted into your template when you use this
name. Putting a prefix on your URL names, perhaps derived from
the application name, will decrease the chances of collision. Something
like *myapp-comment* is recommended over simply *comment*.
When you name your URL patterns, make sure you use names that are unlikely
to clash with any other application's choice of names. If you call your URL
pattern ``comment``, and another application does the same thing, there's
no guarantee which URL will be inserted into your template when you use
this name.
Putting a prefix on your URL names, perhaps derived from the application
name, will decrease the chances of collision. We recommend something like
``myapp-comment`` instead of ``comment``.

View File

@ -159,7 +159,7 @@ represented by a ChoiceField.
<option value="1">Mike Royko</option>
<option value="2">Bob Woodward</option>
</select></td></tr>
<tr><th>Article:</th><td><textarea name="article"></textarea></td></tr>
<tr><th>Article:</th><td><textarea rows="10" cols="40" name="article"></textarea></td></tr>
<tr><th>Categories:</th><td><select multiple="multiple" name="categories">
<option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option>
@ -199,7 +199,7 @@ current values are inserted as 'initial' data in each Field.
<option value="1" selected="selected">Mike Royko</option>
<option value="2">Bob Woodward</option>
</select></li>
<li>Article: <textarea name="article">Hello.</textarea></li>
<li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li>
<li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option>
@ -231,7 +231,7 @@ Add some categories and test the many-to-many form output.
<option value="1" selected="selected">Mike Royko</option>
<option value="2">Bob Woodward</option>
</select></li>
<li>Article: <textarea name="article">Hello.</textarea></li>
<li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li>
<li>Categories: <select multiple="multiple" name="categories">
<option value="1" selected="selected">Entertainment</option>
<option value="2">It&#39;s a test</option>
@ -309,7 +309,7 @@ the data in the database when the form is instantiated.
<option value="1">Mike Royko</option>
<option value="2">Bob Woodward</option>
</select></li>
<li>Article: <textarea name="article"></textarea></li>
<li>Article: <textarea rows="10" cols="40" name="article"></textarea></li>
<li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option>
@ -328,7 +328,7 @@ the data in the database when the form is instantiated.
<option value="2">Bob Woodward</option>
<option value="3">Carl Bernstein</option>
</select></li>
<li>Article: <textarea name="article"></textarea></li>
<li>Article: <textarea rows="10" cols="40" name="article"></textarea></li>
<li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option>

View File

@ -0,0 +1,10 @@
[
{
"pk": "1",
"model": "fixtures_regress.animal",
"fields": {
"name": "Lion",
"latin_name": "Panthera leo"
}
}
]

View File

@ -0,0 +1,22 @@
from django.db import models
class Animal(models.Model):
name = models.CharField(maxlength=150)
latin_name = models.CharField(maxlength=150)
def __str__(self):
return self.common_name
__test__ = {'API_TESTS':"""
>>> from django.core import management
# Load a fixture that uses PK=1
>>> management.load_data(['sequence'], verbosity=0)
# Create a new animal. Without a sequence reset, this new object
# will take a PK of 1 (on Postgres), and the save will fail.
# This is a regression test for ticket #3790.
>>> animal = Animal(name='Platypus', latin_name='Ornithorhynchus anatinus')
>>> animal.save()
"""}

View File

@ -6,7 +6,7 @@ localflavor_tests = r"""
USZipCodeField validates that the data is either a five-digit U.S. zip code or
a zip+4.
>>> from django.contrib.localflavor.usa.forms import USZipCodeField
>>> from django.contrib.localflavor.us.forms import USZipCodeField
>>> f = USZipCodeField()
>>> f.clean('60606')
u'60606'
@ -67,7 +67,7 @@ u''
USPhoneNumberField validates that the data is a valid U.S. phone number,
including the area code. It's normalized to XXX-XXX-XXXX format.
>>> from django.contrib.localflavor.usa.forms import USPhoneNumberField
>>> from django.contrib.localflavor.us.forms import USPhoneNumberField
>>> f = USPhoneNumberField()
>>> f.clean('312-555-1212')
u'312-555-1212'
@ -136,7 +136,7 @@ u''
USStateField validates that the data is either an abbreviation or name of a
U.S. state.
>>> from django.contrib.localflavor.usa.forms import USStateField
>>> from django.contrib.localflavor.us.forms import USStateField
>>> f = USStateField()
>>> f.clean('il')
u'IL'
@ -181,7 +181,7 @@ u''
USStateSelect is a Select widget that uses a list of U.S. states/territories
as its choices.
>>> from django.contrib.localflavor.usa.forms import USStateSelect
>>> from django.contrib.localflavor.us.forms import USStateSelect
>>> w = USStateSelect()
>>> print w.render('state', 'IL')
<select name="state">
@ -247,7 +247,7 @@ as its choices.
</select>
# USSocialSecurityNumberField #################################################
>>> from django.contrib.localflavor.usa.forms import USSocialSecurityNumberField
>>> from django.contrib.localflavor.us.forms import USSocialSecurityNumberField
>>> f = USSocialSecurityNumberField()
>>> f.clean('987-65-4330')
u'987-65-4330'
@ -881,5 +881,135 @@ u'9786324830D-6104243-0910271-2'
>>> f.clean('0434657485D-6407276-0508137-9')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format']
ValidationError: [u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.']
## AUPostCodeField ##########################################################
A field that accepts a four digit Australian post code.
>>> from django.contrib.localflavor.au.forms import AUPostCodeField
>>> f = AUPostCodeField()
>>> f.clean('1234')
u'1234'
>>> f.clean('2000')
u'2000'
>>> f.clean('abcd')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> f.clean('20001')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean('')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f = AUPostCodeField(required=False)
>>> f.clean('1234')
u'1234'
>>> f.clean('2000')
u'2000'
>>> f.clean('abcd')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> f.clean('20001')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> f.clean(None)
u''
>>> f.clean('')
u''
## AUPhoneNumberField ########################################################
A field that accepts a 10 digit Australian phone number.
llows spaces and parentheses around area code.
>>> from django.contrib.localflavor.au.forms import AUPhoneNumberField
>>> f = AUPhoneNumberField()
>>> f.clean('1234567890')
u'1234567890'
>>> f.clean('0213456789')
u'0213456789'
>>> f.clean('02 13 45 67 89')
u'0213456789'
>>> f.clean('(02) 1345 6789')
u'0213456789'
>>> f.clean('(02) 1345-6789')
u'0213456789'
>>> f.clean('(02)1345-6789')
u'0213456789'
>>> f.clean('0408 123 456')
u'0408123456'
>>> f.clean('123')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> f.clean('1800DJANGO')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean('')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f = AUPhoneNumberField(required=False)
>>> f.clean('1234567890')
u'1234567890'
>>> f.clean('0213456789')
u'0213456789'
>>> f.clean('02 13 45 67 89')
u'0213456789'
>>> f.clean('(02) 1345 6789')
u'0213456789'
>>> f.clean('(02) 1345-6789')
u'0213456789'
>>> f.clean('(02)1345-6789')
u'0213456789'
>>> f.clean('0408 123 456')
u'0408123456'
>>> f.clean('123')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> f.clean('1800DJANGO')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> f.clean(None)
u''
>>> f.clean('')
u''
## AUStateSelect #############################################################
AUStateSelect is a Select widget that uses a list of Australian
states/territories as its choices.
>>> from django.contrib.localflavor.au.forms import AUStateSelect
>>> f = AUStateSelect()
>>> print f.render('state', 'NSW')
<select name="state">
<option value="ACT">Australian Capital Territory</option>
<option value="NSW" selected="selected">New South Wales</option>
<option value="NT">Northern Territory</option>
<option value="QLD">Queensland</option>
<option value="SA">South Australia</option>
<option value="TAS">Tasmania</option>
<option value="VIC">Victoria</option>
<option value="WA">Western Australia</option>
</select>
"""

View File

@ -193,30 +193,30 @@ u'<input type="file" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u01
>>> w = Textarea()
>>> w.render('msg', '')
u'<textarea name="msg"></textarea>'
u'<textarea rows="10" cols="40" name="msg"></textarea>'
>>> w.render('msg', None)
u'<textarea name="msg"></textarea>'
u'<textarea rows="10" cols="40" name="msg"></textarea>'
>>> w.render('msg', 'value')
u'<textarea name="msg">value</textarea>'
u'<textarea rows="10" cols="40" name="msg">value</textarea>'
>>> w.render('msg', 'some "quoted" & ampersanded value')
u'<textarea name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>'
>>> w.render('msg', 'value', attrs={'class': 'pretty'})
u'<textarea name="msg" class="pretty">value</textarea>'
u'<textarea rows="10" cols="40" name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>'
>>> w.render('msg', 'value', attrs={'class': 'pretty', 'rows': 20})
u'<textarea class="pretty" rows="20" cols="40" name="msg">value</textarea>'
You can also pass 'attrs' to the constructor:
>>> w = Textarea(attrs={'class': 'pretty'})
>>> w.render('msg', '')
u'<textarea class="pretty" name="msg"></textarea>'
u'<textarea rows="10" cols="40" name="msg" class="pretty"></textarea>'
>>> w.render('msg', 'example')
u'<textarea class="pretty" name="msg">example</textarea>'
u'<textarea rows="10" cols="40" name="msg" class="pretty">example</textarea>'
'attrs' passed to render() get precedence over those passed to the constructor:
>>> w = Textarea(attrs={'class': 'pretty'})
>>> w.render('msg', '', attrs={'class': 'special'})
u'<textarea class="special" name="msg"></textarea>'
u'<textarea rows="10" cols="40" name="msg" class="special"></textarea>'
>>> w.render('msg', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
u'<textarea class="fun" name="msg">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>'
u'<textarea rows="10" cols="40" name="msg" class="fun">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>'
# CheckboxInput Widget ########################################################
@ -1966,12 +1966,12 @@ Any Field can have a Widget class passed to its constructor:
>>> print f['subject']
<input type="text" name="subject" />
>>> print f['message']
<textarea name="message"></textarea>
<textarea rows="10" cols="40" name="message"></textarea>
as_textarea(), as_text() and as_hidden() are shortcuts for changing the output
widget type:
>>> f['subject'].as_textarea()
u'<textarea name="subject"></textarea>'
u'<textarea rows="10" cols="40" name="subject"></textarea>'
>>> f['message'].as_text()
u'<input type="text" name="message" />'
>>> f['message'].as_hidden()
@ -1991,7 +1991,7 @@ as_hidden():
u'<input type="text" name="message" />'
>>> f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False)
>>> f['subject'].as_textarea()
u'<textarea name="subject">Hello</textarea>'
u'<textarea rows="10" cols="40" name="subject">Hello</textarea>'
>>> f['message'].as_text()
u'<input type="text" name="message" value="I love you." />'
>>> f['message'].as_hidden()