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

View File

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

View File

@ -305,7 +305,7 @@ msgstr "Japon
#: conf/global_settings.py:58 #: conf/global_settings.py:58
msgid "Latvian" msgid "Latvian"
msgstr "" msgstr "Latvio"
#: conf/global_settings.py:59 #: conf/global_settings.py:59
msgid "Macedonian" msgid "Macedonian"
@ -611,7 +611,7 @@ msgstr "La URL %s no apunta a una imagen v
#, python-format #, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid." msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr "" 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." "no es válido."
#: core/validators.py:196 #: 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." msgid_plural "Please enter a valid decimal number with a whole part of at most %s digits."
msgstr[0] "" msgstr[0] ""
"Por favor, introduzca un número decimal válido con a lo más %s dígito en " "Por favor, introduzca un número decimal válido con a lo más %s dígito en "
"total." "su parte entera."
msgstr[1] "" msgstr[1] ""
"Por favor, introduzca un número decimal válido con a lo más %s dígitos en " "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 #: core/validators.py:426
#, python-format #, python-format
@ -958,7 +958,7 @@ msgid ""
"digits and underscores)." "digits and underscores)."
msgstr "" msgstr ""
"Requerido. 30 caracteres o menos. Sólo caracteres alfanuméricos (letras, " "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 #: contrib/auth/models.py:91
msgid "first name" msgid "first name"
@ -1107,7 +1107,7 @@ msgstr "Las contrase
#: contrib/auth/forms.py:124 #: contrib/auth/forms.py:124
msgid "Your old password was entered incorrectly. Please enter it again." msgid "Your old password was entered incorrectly. Please enter it again."
msgstr "" 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." "correctamente."
#: contrib/comments/models.py:67 contrib/comments/models.py:166 #: contrib/comments/models.py:67 contrib/comments/models.py:166
@ -1707,7 +1707,7 @@ msgid ""
msgstr "" msgstr ""
"Ha ocurrido un error. Se ha informado a los administradores del sitio " "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 " "mediante correo electrónico y debería arreglarse en breve. Gracias por su "
"paciencia" "paciencia."
#: contrib/admin/templates/admin/search_form.html:8 #: contrib/admin/templates/admin/search_form.html:8
msgid "Go" msgid "Go"
@ -1899,7 +1899,7 @@ msgid ""
"the appropriate user." "the appropriate user."
msgstr "" msgstr ""
"Algo va mal con la instalación de la base de datos. Asegúrate que las tablas " "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." "usuario apropiado."
#: contrib/admin/templates/admin/filter.html:2 #: 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 " "First, enter a username and password. Then, you'll be able to edit more user "
"options." "options."
msgstr "" 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." "editar el resto de opciones del usuario."
#: contrib/admin/templates/admin/auth/user/add_form.html:12 #: contrib/admin/templates/admin/auth/user/add_form.html:12
@ -2105,7 +2105,7 @@ msgstr "vista:"
#: contrib/admin/views/doc.py:164 #: contrib/admin/views/doc.py:164
#, python-format #, python-format
msgid "App %r not found" msgid "App %r not found"
msgstr "Applicación %r no encontrada" msgstr "Aplicación %r no encontrada"
#: contrib/admin/views/doc.py:171 #: contrib/admin/views/doc.py:171
#, python-format #, python-format
@ -2326,12 +2326,12 @@ msgstr "Cambiar clave: %s"
#: contrib/localflavor/usa/forms.py:17 #: contrib/localflavor/usa/forms.py:17
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX." 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 #: contrib/localflavor/uk/forms.py:18
msgid "Enter a postcode. A space is required between the two postcode parts." msgid "Enter a postcode. A space is required between the two postcode parts."
msgstr "" 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." "código."
#: contrib/sessions/models.py:51 #: 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 #: core/validators.py:206 core/validators.py:208
#, python-format #, python-format
msgid "The URL %s is a broken link." 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 #: core/validators.py:214
msgid "Enter a valid U.S. state abbreviation." 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 " "The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
"starts with \"%(start)s\".)" "starts with \"%(start)s\".)"
msgstr "" 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\".)" "starter med \"%(start)s\".)"
#: db/models/manipulators.py:302 #: 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 #: db/models/fields/__init__.py:40
#, python-format #, python-format
msgid "%(optname)s with this %(fieldname)s already exists." 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:114 db/models/fields/__init__.py:265
#: db/models/fields/__init__.py:542 db/models/fields/__init__.py:553 #: 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 "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: Django 1.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2005-12-18 19:38-0500\n" "POT-Creation-Date: 2007-04-01 19:21+0200\n"
"PO-Revision-Date: 2005-12-18 19:26-0500\n" "PO-Revision-Date: 2007-04-03 21:48+0200\n"
"Last-Translator: VLADO LABATH <vlado@labath.org>\n" "Last-Translator: <>\n"
"Language-Team: LANGUAGE <sk@li.org>\n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit"
#: contrib/admin/media/js/SelectFilter2.js:33 #: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format #, perl-format
@ -23,15 +18,15 @@ msgstr "Možný %s"
#: contrib/admin/media/js/SelectFilter2.js:41 #: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all" msgid "Choose all"
msgstr "Vyber všetko" msgstr "Vybr všetko"
#: contrib/admin/media/js/SelectFilter2.js:46 #: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add" msgid "Add"
msgstr "Pridaj" msgstr "Pridať"
#: contrib/admin/media/js/SelectFilter2.js:48 #: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove" msgid "Remove"
msgstr "Vymaž" msgstr "Vymazať"
#: contrib/admin/media/js/SelectFilter2.js:53 #: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format #, perl-format
@ -40,13 +35,13 @@ msgstr "Vybrané %s"
#: contrib/admin/media/js/SelectFilter2.js:54 #: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click " 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 #: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all" 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 #: contrib/admin/media/js/calendar.js:24
msgid "" msgid ""
"January February March April May June July August September October November " "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 " "Január Február Marec Apríl Máj Jún Júl August September Október November "
"December" "December"
#: contrib/admin/media/js/dateparse.js:27 #: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday" msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "Nedeľa Pondelok Utorok Streda Štvrtok Piatok Sobota" 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" msgid "S M T W T F S"
msgstr "N P U S Š P S" msgstr "N P U S Š P S"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45 #: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80 #: 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" msgid "Now"
msgstr "Práve teraz" msgstr "Práve teraz"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock" msgid "Clock"
msgstr "Hodiny" msgstr "Hodiny"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time" 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" msgid "Midnight"
msgstr "Polnoc" msgstr "Polnoc"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m." msgid "6 a.m."
msgstr "6 ráno" msgstr "6 ráno"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon" msgid "Noon"
msgstr "Poludnie" msgstr "Poludnie"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel" msgid "Cancel"
msgstr "Zruš" msgstr "Zruš"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today" msgid "Today"
msgstr "Dnes" msgstr "Dnes"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar" msgid "Calendar"
msgstr "Kalendár" msgstr "Kalendár"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday" msgid "Yesterday"
msgstr "Včera" msgstr "Včera"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Zajtra" 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 table p { margin-left:0; padding-left:0; }
form .aligned p.help { padding-left:38px; } form .aligned p.help { padding-left:38px; }
.aligned .vCheckboxLabel { float:none !important; display:inline; padding-left:4px; } .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; } .checkbox-row p.help { margin-left:0; padding-left:0 !important; }
/* WIDE FIELDSETS */ /* WIDE FIELDSETS */

View File

@ -38,6 +38,7 @@ class Permission(models.Model):
name = models.CharField(_('name'), maxlength=50) name = models.CharField(_('name'), maxlength=50)
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType)
codename = models.CharField(_('codename'), maxlength=100) codename = models.CharField(_('codename'), maxlength=100)
class Meta: class Meta:
verbose_name = _('permission') verbose_name = _('permission')
verbose_name_plural = _('permissions') verbose_name_plural = _('permissions')
@ -56,10 +57,12 @@ class Group(models.Model):
""" """
name = models.CharField(_('name'), maxlength=80, unique=True) name = models.CharField(_('name'), maxlength=80, unique=True)
permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL) permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL)
class Meta: class Meta:
verbose_name = _('group') verbose_name = _('group')
verbose_name_plural = _('groups') verbose_name_plural = _('groups')
ordering = ('name',) ordering = ('name',)
class Admin: class Admin:
search_fields = ('name',) 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_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_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.")) 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()) last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now)
date_joined = models.DateTimeField(_('date joined'), default=models.LazyDate()) date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now)
groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True, 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.")) 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) user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, filter_interface=models.HORIZONTAL)
objects = UserManager() objects = UserManager()
class Meta: class Meta:
verbose_name = _('user') verbose_name = _('user')
verbose_name_plural = _('users') verbose_name_plural = _('users')
ordering = ('username',) ordering = ('username',)
class Admin: class Admin:
fields = ( fields = (
(None, {'fields': ('username', 'password')}), (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 -*- # -*- coding: utf-8 -*-
""" """
A brazilian mapping of state misspellings/abbreviations to normalized An alphabetical list of Brazilian states for use as `choices` in a formfield.
abbreviations, and 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 This exists in this standalone file so that it's only imported into memory
memory when explicitly needed. when explicitly needed.
""" """
STATE_CHOICES = ( STATE_CHOICES = (

View File

@ -12,9 +12,9 @@ id_re = re.compile(r"^(?P<residence>\d{10})(?P<origin>\w{1,3})[-\ ]?(?P<birthday
class DEZipCodeField(RegexField): class DEZipCodeField(RegexField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(DEZipCodeField, self).__init__(r'^\d{5}$', super(DEZipCodeField, self).__init__(r'^\d{5}$',
max_length=None, min_length=None, max_length=None, min_length=None,
error_message=gettext(u'Enter a zip code in the format XXXXX.'), error_message=gettext(u'Enter a zip code in the format XXXXX.'),
*args, **kwargs) *args, **kwargs)
class DEStateSelect(Select): class DEStateSelect(Select):
""" """
@ -43,45 +43,37 @@ class DEIdentityCardNumberField(Field):
parameter = 7 parameter = 7
for i in range(len(given_number)): for i in range(len(given_number)):
fragment = str(int(given_number[i])*parameter) fragment = str(int(given_number[i]) * parameter)
if fragment.isalnum(): if fragment.isalnum():
calculated_checksum += int(fragment[-1]) calculated_checksum += int(fragment[-1])
if parameter == 1:
parameter = 7
elif parameter == 3:
parameter = 1
elif parameter ==7:
parameter = 3
if parameter == 1: return str(calculated_checksum)[-1] == given_checksum
parameter = 7
elif parameter == 3:
parameter = 1
elif parameter ==7:
parameter = 3
if str(calculated_checksum)[-1] == given_checksum:
return True
return False
def clean(self, value): def clean(self, value):
super(DEIdentityCardNumberField, self).clean(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: if value in EMPTY_VALUES:
return u'' return u''
match = re.match(id_re, value) match = re.match(id_re, value)
if not match: if not match:
raise ValidationError(error_msg) raise ValidationError(error_msg)
residence, origin, birthday, validity, checksum = \ gd = match.groupdict()
match.groupdict()['residence'], match.groupdict()['origin'], \ residence, origin = gd['residence'], gd['origin']
match.groupdict()['birthday'], match.groupdict()['validity'], \ birthday, validity, checksum = gd['birthday'], gd['validity'], gd['checksum']
match.groupdict()['checksum']
if residence == '0000000000' or \ if residence == '0000000000' or birthday == '0000000' or validity == '0000000':
birthday == '0000000' or \
validity == '0000000':
raise ValidationError(error_msg) raise ValidationError(error_msg)
all_digits = "%s%s%s%s" % (residence, birthday, validity, checksum) all_digits = "%s%s%s%s" % (residence, birthday, validity, checksum)
if not self.has_valid_checksum(residence) or \ if not self.has_valid_checksum(residence) or not self.has_valid_checksum(birthday) or \
not self.has_valid_checksum(birthday) or \ not self.has_valid_checksum(validity) or not self.has_valid_checksum(all_digits):
not self.has_valid_checksum(validity) or \
not self.has_valid_checksum(all_digits):
raise ValidationError(error_msg) raise ValidationError(error_msg)
return u'%s%s-%s-%s-%s' % (residence, origin, birthday, validity, checksum) return u'%s%s-%s-%s-%s' % (residence, origin, birthday, validity, checksum)

View File

@ -26,8 +26,8 @@ class FISocialSecurityNumber(Field):
def clean(self, value): def clean(self, value):
super(FISocialSecurityNumber, self).clean(value) super(FISocialSecurityNumber, self).clean(value)
if value in EMPTY_VALUES: if value in EMPTY_VALUES:
return u'' return u''
checkmarks = "0123456789ABCDEFHJKLMNPRSTUVWXY" checkmarks = "0123456789ABCDEFHJKLMNPRSTUVWXY"
result = re.match(r"""^ result = re.match(r"""^
(?P<date>([0-2]\d|3[01]) (?P<date>([0-2]\d|3[01])
@ -35,13 +35,11 @@ class FISocialSecurityNumber(Field):
(\d{2})) (\d{2}))
[A+-] [A+-]
(?P<serial>(\d{3})) (?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: if not result:
raise ValidationError(gettext(u'Enter a valid Finnish social security number.')) raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))
checksum = int(result.groupdict()['date'] + result.groupdict()['serial']) gd = result.groupdict()
checksum = int(gd['date'] + gd['serial'])
if checkmarks[checksum % len(checkmarks)] == result.groupdict()['chechsum'].upper(): if checkmarks[checksum % len(checkmarks)] == gd['checksum'].upper():
return u'%s' % value.upper() return u'%s' % value.upper()
raise ValidationError(gettext(u'Enter a valid Finnish social security number.')) 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 = '' get_sql_initial_data.args = ''
def get_sql_sequence_reset(app): 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 from django.db import backend, models
output = [] return backend.get_sql_sequence_reset(style, models.get_models(app))
for model in models.get_models(app): get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting sequences for the given app name(s)."
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)."
get_sql_sequence_reset.args = APP_ARGS get_sql_sequence_reset.args = APP_ARGS
def get_sql_indexes(app): 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 # Determine the project_name a bit naively -- by looking at the name of
# the parent directory. # the parent directory.
project_dir = os.path.normpath(os.path.join(directory, '..')) project_dir = os.path.normpath(os.path.join(directory, '..'))
project_name = os.path.basename(project_dir) parent_dir = os.path.basename(project_dir)
if app_name == os.path.basename(directory): 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.stderr.write(style.ERROR("Error: You cannot create an app with the same name (%r) as your project.\n" % app_name))
sys.exit(1) 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.help_doc = "Creates a Django app directory structure for the given app name in the current directory."
startapp.args = "[appname]" startapp.args = "[appname]"
@ -1367,13 +1348,14 @@ def load_data(fixture_labels, verbosity=1):
"Installs the provided fixture file(s) as data in the database." "Installs the provided fixture file(s) as data in the database."
from django.db.models import get_apps from django.db.models import get_apps
from django.core import serializers from django.core import serializers
from django.db import connection, transaction from django.db import connection, transaction, backend
from django.conf import settings from django.conf import settings
import sys import sys
# Keep a count of the installed objects and fixtures # Keep a count of the installed objects and fixtures
count = [0,0] count = [0,0]
models = set()
humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path' humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
# Get a cursor (even though we don't need one yet). This has # Get a cursor (even though we don't need one yet). This has
@ -1435,6 +1417,7 @@ def load_data(fixture_labels, verbosity=1):
objects = serializers.deserialize(format, fixture) objects = serializers.deserialize(format, fixture)
for obj in objects: for obj in objects:
count[0] += 1 count[0] += 1
models.add(obj.object.__class__)
obj.save() obj.save()
label_found = True label_found = True
except Exception, e: except Exception, e:
@ -1456,6 +1439,12 @@ def load_data(fixture_labels, verbosity=1):
else: else:
if verbosity > 0: if verbosity > 0:
print "Installed %d object(s) from %d fixture(s)" % tuple(count) 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.commit()
transaction.leave_transaction_management() transaction.leave_transaction_management()

View File

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

View File

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

View File

@ -233,6 +233,11 @@ def get_sql_flush(style, tables, sequences):
else: else:
return [] 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 = { OPERATOR_MAPPING = {
'exact': '= %s', 'exact': '= %s',
'iexact': 'LIKE %s', 'iexact': 'LIKE %s',

View File

@ -217,6 +217,11 @@ def get_sql_flush(style, tables, sequences):
else: else:
return [] 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 = { OPERATOR_MAPPING = {
'exact': '= %s', 'exact': '= %s',
'iexact': 'LIKE %s', 'iexact': 'LIKE %s',

View File

@ -81,7 +81,6 @@ class FormatStylePlaceholderCursor(Database.Cursor):
you'll need to use "%%s". you'll need to use "%%s".
""" """
def _rewrite_args(self, query, params=None): def _rewrite_args(self, query, params=None):
from django.db.models import LazyDate
if params is None: if params is None:
params = [] params = []
else: else:
@ -92,8 +91,6 @@ class FormatStylePlaceholderCursor(Database.Cursor):
params[i] = param.encode('utf-8') params[i] = param.encode('utf-8')
except UnicodeError: except UnicodeError:
params[i] = str(param) params[i] = str(param)
if type(param) == LazyDate:
params[i] = param.__get_value__()
args = [(':arg%d' % i) for i in range(len(params))] args = [(':arg%d' % i) for i in range(len(params))]
query = query % tuple(args) query = query % tuple(args)
# cx_Oracle cannot execute a query with the closing ';' # 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 name_length = get_max_name_length() - 3
return '%s_SQ' % util.truncate_name(table, name_length).upper() 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): def get_trigger_name(table):
name_length = get_max_name_length() - 3 name_length = get_max_name_length() - 3
return '%s_TR' % util.truncate_name(table, name_length).upper() return '%s_TR' % util.truncate_name(table, name_length).upper()

View File

@ -231,6 +231,31 @@ def get_sql_flush(style, tables, sequences):
else: else:
return [] 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 # Register these custom typecasts, because Django expects dates/times to be
# in Python's native (standard-library) datetime/time format, whereas psycopg # in Python's native (standard-library) datetime/time format, whereas psycopg
# use mx.DateTime by default. # use mx.DateTime by default.

View File

@ -188,6 +188,31 @@ def get_sql_flush(style, tables, sequences):
else: else:
return [] 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 = { OPERATOR_MAPPING = {
'exact': '= %s', 'exact': '= %s',
'iexact': 'ILIKE %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 # get_sql_flush() implementations). Just return SQL at this point
return sql 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): def _sqlite_date_trunc(lookup_type, dt):
try: try:
dt = util.typecast_timestamp(dt) dt = util.typecast_timestamp(dt)

View File

@ -27,32 +27,3 @@ def permalink(func):
viewname = bits[0] viewname = bits[0]
return reverse(bits[0], None, *bits[1:3]) return reverse(bits[0], None, *bits[1:3])
return inner 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) validators.isValidPhone(field_data, all_data)
def formfield(self, **kwargs): 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 = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
defaults.update(kwargs) defaults.update(kwargs)
return USPhoneNumberField(**defaults) return USPhoneNumberField(**defaults)

View File

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

View File

@ -121,6 +121,12 @@ class FileInput(Input):
input_type = 'file' input_type = 'file'
class Textarea(Widget): 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): def render(self, name, value, attrs=None):
if value is None: value = '' if value is None: value = ''
value = smart_unicode(value) value = smart_unicode(value)

View File

@ -132,6 +132,7 @@ class RssFeed(SyndicationFeed):
handler.addQuickElement(u"category", cat) handler.addQuickElement(u"category", cat)
if self.feed['feed_copyright'] is not None: if self.feed['feed_copyright'] is not None:
handler.addQuickElement(u"copyright", self.feed['feed_copyright']) 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.write_items(handler)
self.endChannelElement(handler) self.endChannelElement(handler)
handler.endElement(u"rss") 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') t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template')
c = Context({ c = Context({
'root_urlconf': settings.ROOT_URLCONF, 'root_urlconf': settings.ROOT_URLCONF,
'request_path': request.path[1:], # Trim leading slash
'urlpatterns': tried, 'urlpatterns': tried,
'reason': str(exception), 'reason': str(exception),
'request': request, 'request': request,
@ -591,7 +592,7 @@ TECHNICAL_404_TEMPLATE = """
<li>{{ pattern|escape }}</li> <li>{{ pattern|escape }}</li>
{% endfor %} {% endfor %}
</ol> </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 %} {% else %}
<p>{{ reason|escape }}</p> <p>{{ reason|escape }}</p>
{% endif %} {% endif %}

View File

@ -1,8 +1,8 @@
from django.shortcuts import render_to_response 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 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 Render a given template with any extra URL parameters in the context as
``{{ params }}``. ``{{ params }}``.
@ -13,7 +13,9 @@ def direct_to_template(request, template, extra_context={}, **kwargs):
dictionary[key] = value() dictionary[key] = value()
else: else:
dictionary[key] = value 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): 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 ``--settings`` command line option, if you need to switch between multiple
Django settings files. 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 Usage
===== =====
@ -100,23 +103,24 @@ if you're ever curious to see the full list of defaults.
dumpdata [appname appname ...] dumpdata [appname appname ...]
------------------------------ ------------------------------
Output to standard output all data in the database associated with the named Output to standard output all data in the database associated with the named
application(s). application(s).
By default, the database will be dumped in JSON format. If you want the output 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``). to be in another format, use the ``--format`` option (e.g., ``format=xml``).
You may specify any Django serialization backend (including any user specified 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. If no application name is provided, all installed applications will be dumped.
The output of ``dumpdata`` can be used as input for ``loaddata``. The output of ``dumpdata`` can be used as input for ``loaddata``.
flush flush
----- -----
Return the database to the state it was in immediately after syncdb was Return the database to the state it was in immediately after syncdb was
executed. This means that all data will be removed from the database, any executed. This means that all data will be removed from the database, any
post-synchronization handlers will be re-executed, and the ``initial_data`` post-synchronization handlers will be re-executed, and the ``initial_data``
fixture will be re-installed. fixture will be re-installed.
@ -178,37 +182,37 @@ Django will search in three locations for fixtures:
3. In the literal path named by the fixture 3. In the literal path named by the fixture
Django will load any and all fixtures it finds in these locations that match Django will load any and all fixtures it finds in these locations that match
the provided fixture names. the provided fixture names.
If the named fixture has a file extension, only fixtures of that type If the named fixture has a file extension, only fixtures of that type
will be loaded. For example:: will be loaded. For example::
django-admin.py loaddata mydata.json django-admin.py loaddata mydata.json
would only load JSON fixtures called ``mydata``. The fixture extension would only load JSON fixtures called ``mydata``. The fixture extension
must correspond to the registered name of a serializer (e.g., ``json`` or must correspond to the registered name of a serializer (e.g., ``json`` or
``xml``). ``xml``).
If you omit the extension, Django will search all available fixture types If you omit the extension, Django will search all available fixture types
for a matching fixture. For example:: for a matching fixture. For example::
django-admin.py loaddata mydata django-admin.py loaddata mydata
would look for any fixture of any fixture type called ``mydata``. If a fixture would look for any fixture of any fixture type called ``mydata``. If a fixture
directory contained ``mydata.json``, that fixture would be loaded directory contained ``mydata.json``, that fixture would be loaded
as a JSON fixture. However, if two fixtures with the same name but different as a JSON fixture. However, if two fixtures with the same name but different
fixture type are discovered (for example, if ``mydata.json`` and fixture type are discovered (for example, if ``mydata.json`` and
``mydata.xml`` were found in the same fixture directory), fixture ``mydata.xml`` were found in the same fixture directory), fixture
installation will be aborted, and any data installed in the call to installation will be aborted, and any data installed in the call to
``loaddata`` will be removed from the database. ``loaddata`` will be removed from the database.
The fixtures that are named can include directory components. These The fixtures that are named can include directory components. These
directories will be included in the search path. For example:: directories will be included in the search path. For example::
django-admin.py loaddata foo/bar/mydata.json django-admin.py loaddata foo/bar/mydata.json
would search ``<appname>/fixtures/foo/bar/mydata.json`` for each installed would search ``<appname>/fixtures/foo/bar/mydata.json`` for each installed
application, ``<dirname>/foo/bar/mydata.json`` for each directory in application, ``<dirname>/foo/bar/mydata.json`` for each directory in
``FIXTURE_DIRS``, and the literal path ``foo/bar/mydata.json``. ``FIXTURE_DIRS``, and the literal path ``foo/bar/mydata.json``.
Note that the order in which fixture files are processed is undefined. However, Note that the order in which fixture files are processed is undefined. However,
@ -217,16 +221,18 @@ one fixture can reference data in another fixture. If the database backend
supports row-level constraints, these constraints will be checked at the supports row-level constraints, these constraints will be checked at the
end of the transaction. end of the transaction.
The ``dumpdata`` command can be used to generate input for ``loaddata``.
.. admonition:: MySQL and Fixtures .. admonition:: MySQL and Fixtures
Unfortunately, MySQL isn't capable of completely supporting all the Unfortunately, MySQL isn't capable of completely supporting all the
features of Django fixtures. If you use MyISAM tables, MySQL doesn't features of Django fixtures. If you use MyISAM tables, MySQL doesn't
support transactions or constraints, so you won't get a rollback if support transactions or constraints, so you won't get a rollback if
multiple transaction files are found, or validation of fixture data. multiple transaction files are found, or validation of fixture data.
If you use InnoDB tables, you won't be able to have any forward If you use InnoDB tables, you won't be able to have any forward
references in your data files - MySQL doesn't provide a mechanism to references in your data files - MySQL doesn't provide a mechanism to
defer checking of row constraints until a transaction is committed. defer checking of row constraints until a transaction is committed.
reset [appname appname ...] reset [appname appname ...]
--------------------------- ---------------------------
Executes the equivalent of ``sqlreset`` for the given appnames. Executes the equivalent of ``sqlreset`` for the given appnames.
@ -366,7 +372,7 @@ Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given appnames.
sqlsequencereset [appname appname ...] 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. appnames.
See http://simon.incutio.com/archive/2004/04/21/postgres for more information. See http://simon.incutio.com/archive/2004/04/21/postgres for more information.
@ -397,8 +403,8 @@ this command to install the default apps.
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
give you the option of creating a superuser immediately. give you the option of creating a superuser immediately.
``syncdb`` will also search for and install any fixture named ``initial_data``. ``syncdb`` will also search for and install any fixture named ``initial_data``.
See the documentation for ``loaddata`` for details on the specification of See the documentation for ``loaddata`` for details on the specification of
fixture data files. fixture data files.
test test
@ -471,7 +477,7 @@ Example usage::
django-admin.py dumpdata --indent=4 django-admin.py dumpdata --indent=4
Specifies the number of spaces that will be used for indentation when Specifies the number of spaces that will be used for indentation when
pretty-printing output. By default, output will *not* be pretty-printed. pretty-printing output. By default, output will *not* be pretty-printed.
Pretty-printing will only be enabled if the indent option is provided. Pretty-printing will only be enabled if the indent option is provided.
@ -512,7 +518,8 @@ and `2` is verbose output.
------------ ------------
Example usage:: 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 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 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 The most recent version of the Django documentation lives at
http://www.djangoproject.com/documentation/ . These HTML pages are generated http://www.djangoproject.com/documentation/ . These HTML pages are generated
automatically from the text files in source control every 15 minutes. That automatically from the text files in source control. That means they reflect
means they reflect the "latest and greatest" in Django -- they include the very the "latest and greatest" in Django -- they include the very latest
latest corrections and additions, and they discuss the latest Django features, corrections and additions, and they discuss the latest Django features,
which may only be available to users of the Django development version. (See which may only be available to users of the Django development version. (See
"Differences between versions" below.) "Differences between versions" below.)
A key advantage of the Web-based documentation is the comment section at the We encourage you to help improve the docs by submitting changes, corrections
bottom of each document. This is an area for anybody to submit changes, and suggestions in the `ticket system`_. The Django developers actively monitor
corrections and suggestions about the given document. The Django developers the ticket system and use your feedback to improve the documentation for
frequently monitor the comments there and use them to improve the documentation everybody.
for everybody.
We encourage you to help improve the docs: it's easy! Note, however, that Note, however, that tickets should explicitly relate to the documentation,
comments should explicitly relate to the documentation, rather than asking rather than asking broad tech-support questions. If you need help with your
broad tech-support questions. If you need help with your particular Django particular Django setup, try the `django-users mailing list`_ or the
setup, try the `django-users mailing list`_ instead of posting a comment to the `#django IRC channel`_ instead.
documentation.
.. _ticket system: http://code.djangoproject.com/simpleticket?component=Documentation
.. _django-users mailing list: http://groups.google.com/group/django-users .. _django-users mailing list: http://groups.google.com/group/django-users
.. _#django IRC channel: irc://irc.freenode.net/django
In plain text In plain text
------------- -------------
@ -134,14 +134,6 @@ We follow this policy:
frozen document that says "These docs are frozen for Django version XXX" frozen document that says "These docs are frozen for Django version XXX"
and links to the current version of that document. 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 * The `main documentation Web page`_ includes links to documentation for
all previous versions. 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 Django comes with a utility that can create models by introspecting an existing
database. You can view the output by running this command:: 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:: 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 This feature is meant as a shortcut, not as definitive model generation. See
the `django-admin.py documentation`_ for more information. 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 Next, run the ``manage.py syncdb`` command to install any extra needed database
records such as admin permissions and content types:: records such as admin permissions and content types::
django-admin.py init --settings=path.to.settings python manage.py syncdb
See whether it worked 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 ``limit_choices_to`` A dictionary of lookup arguments and values (see
the `Database API reference`_) that limit the the `Database API reference`_) that limit the
available admin choices for this object. Use this available admin choices for this object. Use this
with ``models.LazyDate`` to limit choices of objects with functions from the Python ``datetime`` module
by date. For example:: 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 only allows the choice of related objects with a
``pub_date`` before the current date/time to be ``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:: .. 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 This string is passed through Python's string parser twice, so you need to
escape each backslash **twice**:: escape each backslash **twice**::
PythonPath "['c:\\\\path\\\\to\\\\project'] + sys.path" PythonPath "['c:\\\\path\\\\to\\\\project'] + sys.path"
or use raw strings:: Or, use raw strings::
PythonPath "[r'c:\\path\\to\\project'] + sys.path" PythonPath "[r'c:\\path\\to\\project'] + sys.path"
You can also add directives such as ``PythonAutoReload Off`` for performance. You can also add directives such as ``PythonAutoReload Off`` for performance.
See the `mod_python documentation`_ for a full list of options. 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 ``VirtualHost`` as Django, here's how you can turn off mod_python for a
particular part of the site:: particular part of the site::
<Location "/media/"> <Location "/media">
SetHandler None SetHandler None
</Location> </Location>
@ -178,7 +177,7 @@ the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
SetEnv DJANGO_SETTINGS_MODULE mysite.settings SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location> </Location>
<Location "media"> <Location "/media">
SetHandler None SetHandler None
</Location> </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 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. 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 The 404 (page not found) view
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -114,6 +114,9 @@ Note:
`object-relational mapper`_, ``items()`` doesn't have to return model `object-relational mapper`_, ``items()`` doesn't have to return model
instances. Although you get a few bits of functionality "for free" by instances. Although you get a few bits of functionality "for free" by
using Django models, ``items()`` can return any type of object you want. 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>``, 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 ``<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 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 class and set the ``feed_type`` to something different. Then update your
URLconf to add the extra versions. URLconf to add the extra versions.
@ -318,6 +321,20 @@ Here's a full example::
class AtomSiteNewsFeed(RssSiteNewsFeed): class AtomSiteNewsFeed(RssSiteNewsFeed):
feed_type = Atom1Feed 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:: 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 :alt: Django admin index page
:target: http://media.djangoproject.com/img/doc/tutorial/admin02.png :target: http://media.djangoproject.com/img/doc/tutorial/admin02.png
By default, you should see two types of editable content: groups and users. You should see a few other types of editable content, including groups, users
These are core features Django ships with by default. and sites. These are core features Django ships with by default.
.. _"I can't log in" questions: ../faq/#the-admin-site .. _"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 url
--- ---
**New in development version**
The ``url()`` function can be used instead of a tuple as an argument to **New in Django development version**
``patterns()``. This is convenient if you wish to specify a name without the
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:: optional extra arguments dictionary. For example::
urlpatterns = patterns('', urlpatterns = patterns('',
@ -498,26 +499,40 @@ the view prefix (as explained in "The view prefix" above) will have no effect.
Naming URL patterns 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 It's 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, your URLconf. For example, these two URL patterns both point to the ``archive``
because the ``permalink()`` decorator and ``{% url %}`` template tag use the view::
name of the view function to find a match.
To solve this problem, you can give a name to each of your URL patterns in urlpatterns = patterns('',
order to distinguish them from other patterns using the same views and (r'/archive/(\d{4})/$', archive),
parameters. You can then use this name wherever you would otherwise use the (r'/archive-summary/(\d{4})/$', archive, {'summary': True}),
name of the view function. For example, if you URLConf contains:: )
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('', urlpatterns = patterns('',
url(r'/archive/(\d{4})/$', archive, name="full-archive"), url(r'/archive/(\d{4})/$', archive, name="full-archive"),
url(r'/archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"), 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 arch-summary 1945 %}
{% url full-archive 2007 %}
Even though both URL patterns refer to the ``archive`` view here, using the 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. ``name`` parameter to ``url()`` allows you to tell them apart in templates.
@ -527,11 +542,12 @@ not restricted to valid Python names.
.. note:: .. note::
Make sure that when you name your URLs, you use names that are unlikely to When you name your URL patterns, make sure you use names that are unlikely
clash with any other application's choice of names. If you call your URL 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 pattern ``comment``, and another application does the same thing, there's
guarantee which URL will be inserted into your template when you use this no guarantee which URL will be inserted into your template when you use
name. Putting a prefix on your URL names, perhaps derived from this name.
the application name, will decrease the chances of collision. Something
like *myapp-comment* is recommended over simply *comment*.
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="1">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></td></tr> </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"> <tr><th>Categories:</th><td><select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</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="1" selected="selected">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></li> </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"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</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="1" selected="selected">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></li> </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"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1" selected="selected">Entertainment</option> <option value="1" selected="selected">Entertainment</option>
<option value="2">It&#39;s a test</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="1">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></li> </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"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</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="2">Bob Woodward</option>
<option value="3">Carl Bernstein</option> <option value="3">Carl Bernstein</option>
</select></li> </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"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</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()
"""}

File diff suppressed because one or more lines are too long

View File

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