1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

newforms-admin: Merged to [6332].

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6342 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Joseph Kocherhans 2007-09-15 22:25:52 +00:00
parent b266911382
commit 019e3c61e4
191 changed files with 25706 additions and 11009 deletions

23
AUTHORS
View File

@ -76,6 +76,7 @@ answer newbie questions, and generally made Django that much better:
Chris Chamberlin <dja@cdc.msbx.net>
Amit Chakradeo <http://amit.chakradeo.net/>
ChaosKCW
Sengtha Chay <sengtha@e-khmer.com>
ivan.chelubeev@gmail.com
Bryan Chow <bryan at verdjn dot com>
Michal Chruszcz <troll@pld-linux.org>
@ -113,6 +114,7 @@ answer newbie questions, and generally made Django that much better:
Ludvig Ericson <ludvig.ericson@gmail.com>
Dirk Eschler <dirk.eschler@gmx.net>
Marc Fargas <telenieko@telenieko.com>
Szilveszter Farkas <szilveszter.farkas@gmail.com>
favo@exoweb.net
Bill Fenner <fenner@gmail.com>
Stefane Fermgier <sf@fermigier.com>
@ -123,8 +125,10 @@ answer newbie questions, and generally made Django that much better:
gandalf@owca.info
Marc Garcia <marc.garcia@accopensys.com>
Baishampayan Ghose
Dimitris Glezos <dimitris@glezos.com>
glin@seznam.cz
martin.glueck@gmail.com
Artyom Gnilov <boobsd@gmail.com>
GomoX <gomo@datafull.com>
Mario Gonzalez <gonzalemario@gmail.com>
pradeep.gowda@gmail.com
@ -146,6 +150,7 @@ answer newbie questions, and generally made Django that much better:
Sung-Jin Hong <serialx.net@gmail.com>
Richard House <Richard.House@i-logue.com>
Robert Rock Howard <http://djangomojo.com/>
Rob Hudson <http://rob.cogit8.org/>
Jason Huggins <http://www.jrandolph.com/blog/>
Hyun Mi Ae
Tom Insam
@ -158,6 +163,7 @@ answer newbie questions, and generally made Django that much better:
jpellerin@gmail.com
junzhang.jn@gmail.com
Antti Kaihola <http://akaihola.blogspot.com/>
Nagy Károly <charlie@rendszergazda.com>
Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
Ian G. Kelly <ian.g.kelly@gmail.com>
Ben Khoo <khoobks@westnet.com.au>
@ -179,6 +185,7 @@ answer newbie questions, and generally made Django that much better:
lakin.wecker@gmail.com
Nick Lane <nick.lane.au@gmail.com>
Stuart Langridge <http://www.kryogenix.org/>
Paul Lanier <planier@google.com>
Nicola Larosa <nico@teknico.net>
Eugene Lazutkin <http://lazutkin.com/blog/>
Jeong-Min Lee <falsetru@gmail.com>
@ -194,6 +201,7 @@ answer newbie questions, and generally made Django that much better:
Petr Marhoun <petr.marhoun@gmail.com>
masonsimon+django@gmail.com
Manuzhai
Petr Marhoun <petr.marhoun@gmail.com>
Petar Marić <http://www.petarmaric.com/>
Nuno Mariz <nmariz@gmail.com>
Marijn Vriens <marijn@metronomo.cl>
@ -232,6 +240,7 @@ answer newbie questions, and generally made Django that much better:
phil@produxion.net
phil.h.smith@gmail.com
Gustavo Picon
pigletto
Luke Plant <http://lukeplant.me.uk/>
plisk
Daniel Poelzleithner <http://poelzi.org/>
@ -239,16 +248,20 @@ answer newbie questions, and generally made Django that much better:
Matthias Pronk <django@masida.nl>
Jyrki Pulliainen <jyrki.pulliainen@gmail.com>
Johann Queuniet <johann.queuniet@adh.naellia.eu>
J. Rademaker
Jan Rademaker
Michael Radziej <mir@noris.de>
Amit Ramon <amit.ramon@gmail.com>
Philippe Raoult <philippe.raoult@n2nsoft.com>
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
Brian Ray <http://brianray.chipy.org/>
remco@diji.biz
rhettg@gmail.com
Matt Riggott
Henrique Romano <onaiort@gmail.com>
Armin Ronacher
Brian Rosner <brosner@gmail.com>
Oliver Rutherfurd <http://rutherfurd.net/>
ryankanno
Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
Vinay Sajip <vinay_sajip@yahoo.co.uk>
David Schein
@ -259,8 +272,11 @@ answer newbie questions, and generally made Django that much better:
Jozko Skrablin <jozko.skrablin@gmail.com>
SmileyChris <smileychris@gmail.com>
smurf@smurf.noris.de
Vsevolod Solovyov
sopel
Leo Soto <leo.soto@gmail.com>
Wiliam Alves de Souza <wiliamsouza83@gmail.com>
Bjørn Stabell <bjorn@exoweb.net>
Georgi Stanojevski <glisha@gmail.com>
Vasiliy Stavenko <stavenko@gmail.com>
Thomas Steinacher <http://www.eggdrop.ch/>
@ -272,10 +288,13 @@ answer newbie questions, and generally made Django that much better:
Swaroop C H <http://www.swaroopch.info>
Aaron Swartz <http://www.aaronsw.com/>
Ville Säävuori <http://www.unessa.net/>
Tyler Tarabula <tyler.tarabula@gmail.com>
Tyson Tate <tyson@fallingbullets.com>
Frank Tegtmeyer <fte@fte.to>
thebjorn <bp@datakortet.no>
Zach Thompson <zthompson47@gmail.com>
Michael Thornhill
Deepak Thukral <deep.thukral@gmail.com>
tibimicu@gmax.net
tobias@neuyork.de
Tom Tobin
@ -288,10 +307,12 @@ answer newbie questions, and generally made Django that much better:
Amit Upadhyay
Geert Vanderkelen
viestards.lists@gmail.com
George Vilches <gav@thataddress.com>
Vlado <vlado@labath.org>
Milton Waddams
wam-djangobug@wamber.net
wangchun <yaohua2000@gmail.com>
Filip Wasilewski <filip.wasilewski@gmail.com>
Dan Watson <http://theidioteque.net/>
Chris Wesseling <Chris.Wesseling@cwi.nl>
James Wheare <django@sparemint.com>

View File

@ -112,6 +112,7 @@ class Settings(object):
# Move the time zone info into os.environ. See ticket #2315 for why
# we don't do this unconditionally (breaks Windows).
os.environ['TZ'] = self.TIME_ZONE
time.tzset()
def get_all_members(self):
return dir(self)

View File

@ -51,6 +51,7 @@ LANGUAGES = (
('fa', gettext_noop('Persian')),
('fi', gettext_noop('Finnish')),
('fr', gettext_noop('French')),
('ga', gettext_noop('Gaeilge')),
('gl', gettext_noop('Galician')),
('hu', gettext_noop('Hungarian')),
('he', gettext_noop('Hebrew')),
@ -59,6 +60,7 @@ LANGUAGES = (
('it', gettext_noop('Italian')),
('ja', gettext_noop('Japanese')),
('ko', gettext_noop('Korean')),
('km', gettext_noop('Khmer')),
('kn', gettext_noop('Kannada')),
('lv', gettext_noop('Latvian')),
('mk', gettext_noop('Macedonian')),

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,116 @@
# 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.
#
msgid ""
msgstr ""
"Project-Id-Version: django 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-09-14 12:33+0100\n"
"PO-Revision-Date: 2007-09-14 14:19+0100\n"
"Last-Translator: Michael Thornhill <michael.thornhill@gmail.com>\n"
"Language-Team: Gaeilge <ga@li.org>\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 ""
#: 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 ""
#: 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 ""
#: 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/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 ""
#: 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 ""
#: 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 ""

View File

@ -205,7 +205,7 @@ msgstr "פברואר"
#: utils/dates.py:14 utils/dates.py:27
msgid "March"
msgstr "מרץ"
msgstr "מרס"
#: utils/dates.py:14 utils/dates.py:27
msgid "April"
@ -241,11 +241,11 @@ msgstr "נובמבר"
#: utils/dates.py:16
msgid "December"
msgstr "תצבר"
msgstr "דצמבר"
#: utils/dates.py:19
msgid "jan"
msgstr "יאנ"
msgstr "ינו"
#: utils/dates.py:19
msgid "feb"
@ -253,7 +253,7 @@ msgstr "פבר"
#: utils/dates.py:19
msgid "mar"
msgstr "מרץ"
msgstr "מרס"
#: utils/dates.py:19
msgid "apr"
@ -293,7 +293,7 @@ msgstr "דצמ"
#: utils/dates.py:27
msgid "Jan."
msgstr "יאנ'"
msgstr "ינו'"
#: utils/dates.py:27
msgid "Feb."

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,21 @@
# translation of djangojs.po to Hungarian
# translation of djangojs.po to
# This file is distributed under the same license as the PACKAGE package.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
# Nagy Károly <charlie@rendszergazda.com>, 2006.
#
msgid ""
msgstr ""
"Project-Id-Version: djangojs\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
"PO-Revision-Date: 2006-05-10 11:59+0200\n"
"Last-Translator: Nagy Károly <charlie@rendszergazda.com>\n"
"Language-Team: <hu@li.org>\n"
"PO-Revision-Date: 2007-09-13 13:30+0200\n"
"Last-Translator: Szilveszter Farkas <szilveszter.farkas@gmail.com>\n"
"Language-Team: Hungarian <hu@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.9.1\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
@ -23,15 +24,15 @@ msgstr "Elérhető %s"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
msgstr "Mindent kijelöl"
msgstr "Mindet kijelölni"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
msgstr "Hozzáad"
msgstr "Hozzáadás"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
msgstr "Eltávolít"
msgstr "Eltávolítás"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
@ -40,7 +41,7 @@ msgstr "%s kiválasztva"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
msgstr "Válaszd ki a kért elemeket és kattints"
msgstr "Válassza ki a kért elemeket és kattintson"
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
@ -51,11 +52,11 @@ msgstr "Összes törlése"
msgid ""
"January February March April May June July August September October November "
"December"
msgstr "Január Február Március Április Május Június Július Szeptember Október November December"
msgstr "január február március április május június július augusztus szeptember október november december"
#: contrib/admin/media/js/dateparse.js:27
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "Vasárnap Hétfő Kedd Szerda Csütörtök Péntek Szombat"
msgstr "vasárnap hétfő kedd szerda csütörtök péntek szombat"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
@ -72,7 +73,7 @@ msgstr "Óra"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
msgid "Choose a time"
msgstr "Válaszd ki az időt"
msgstr "Válassza ki az időt"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Midnight"

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,108 @@
# 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.
#
msgid ""
msgstr ""
"Project-Id-Version: 01\n"
"Report-Msgid-Bugs-To: sengtha@e-khmer.com\n"
"POT-Creation-Date: 2007-01-15 15:43+0200\n"
"PO-Revision-Date: 2007-01-21 01:25+0900\n"
"Last-Translator: Chay Sengtha <sengtha@e-khmer.com>\n"
"Language-Team: Chay Sengtha <sengtha@e-khmer.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: 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/dateparse.js:26
#: contrib/admin/media/js/calendar.js:24
msgid "January February March April May June July August September October November December"
msgstr "January February March April May June July August September October November December"
#: contrib/admin/media/js/dateparse.js:27
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "S M T W T F S"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
msgid "Now"
msgstr "ឥឡូវនេះ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
msgid "Clock"
msgstr "នាឡិការ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
msgid "Choose a time"
msgstr "ជ្រើសរើសម៉ោង"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Midnight"
msgstr "អធ្រាត្រ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "6 a.m."
msgstr "ម៉ោង ៦ ព្រឹក"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "Noon"
msgstr "ពេលថ្ងែត្រង់"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
msgid "Cancel"
msgstr "លប់ចោល"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
msgid "Today"
msgstr "ថ្ងៃនេះ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
msgid "Calendar"
msgstr "ប្រក្រតិទិន"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
msgid "Yesterday"
msgstr "ម្សិលមិញ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
msgid "Tomorrow"
msgstr "ថ្ងៃស្អែក"

View File

@ -825,12 +825,12 @@ msgstr "%d 자 이상 입력해 주세요."
#: newforms/fields.py:130
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "%s 자 이하로 입력해 주세요."
msgstr "%s 이하의 값을 입력해 주세요."
#: newforms/fields.py:132
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "%s 이상 입력해 주세요."
msgstr "%s 이상의 값을 입력해 주세요."
#: newforms/fields.py:165
msgid "Enter a valid date."

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
# translation of djangojs.po to
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# translation of djangojs.po to norwegian
# Copyright (C) 2005 and beyond
# This file is distributed under the same license as the Django package.
# Espen Grindhaug <espen.grindhaug@mail.com>, 2006.
#
msgid ""
@ -8,16 +8,14 @@ msgstr ""
"Project-Id-Version: djangojs\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
"PO-Revision-Date: 2007-04-27 06:51+0200\n"
"Last-Translator: \n"
"Language-Team: <en@li.org>\n"
"PO-Revision-Date: 2007-08-29 18:22+0200\n"
"Last-Translator: jonklo\n"
"Language-Team: Norsk <no@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
msgstr "%s er tilgjengelige"
@ -34,13 +32,12 @@ msgid "Remove"
msgstr "Slett"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
msgid "Chosen %s"
msgstr "%s er valgt"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
msgstr "Velg ditt svaralternativ(er) og klikk"
msgstr "Velg ditt svaralternativ(er) og klikk "
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
@ -85,15 +82,15 @@ msgstr "Velg et klokkeslett"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Midnight"
msgstr "24.00"
msgstr "Midnatt"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "6 a.m."
msgstr "06.00"
msgstr "06:00"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "Noon"
msgstr "12.00"
msgstr "12:00"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168

View File

@ -14,7 +14,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=2; nplurals=n>1;"
"Plural-Forms: nplurals=2; plural=n>1;"
#: contrib/comments/models.py:67 contrib/comments/models.py:166
msgid "object ID"

View File

@ -107,3 +107,9 @@ msgstr "Dün"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
msgid "Tomorrow"
msgstr "Yarın"
msgid "Show"
msgstr "Göster"
msgid "Hide"
msgstr "Gizle"

View File

@ -24,7 +24,7 @@ DATABASE_PORT = '' # Set to empty string for default. Not used with
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1

View File

@ -0,0 +1 @@
/* Nothing to see here. Dummy file to feed to the high pass filter which hides CSS from IE5/win. Details: http://tantek.com/CSS/Examples/highpass.html */

View File

@ -43,7 +43,7 @@ p.file-upload { line-height:20px; margin:0; padding:0; color:#666; font-size:11p
/* CALENDARS & CLOCKS */
.calendarbox, .clockbox { margin:5px auto; font-size:11px; width:16em; text-align:center; background:white; position:relative; }
.clockbox { width:9em; }
.clockbox { width:auto; }
.calendar { margin:0; padding: 0; }
.calendar table { margin:0; padding:0; border-collapse:collapse; background:white; width:99%; }
.calendar caption, .calendarbox h2 { margin: 0; font-size:11px; text-align:center; border-top:none; }

View File

@ -58,7 +58,7 @@ var SelectFilter = {
quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
selector_filter.className = 'selector-filter';
quickElement('img', selector_filter, '', 'src', admin_media_prefix + 'img/admin/selector-add.gif', 'alt', 'Add');
quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? 'img/admin/selector_stacked-add.gif':'img/admin/selector-add.gif'), 'alt', 'Add');
var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
to_box.className = 'filtered';
var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');

View File

@ -195,6 +195,19 @@ var DateTimeShortcuts = {
openCalendar: function(num) {
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
var inp = DateTimeShortcuts.calendarInputs[num];
// Determine if the current value in the input has a valid date.
// If so, draw the calendar with that date's year and month.
if (inp.value) {
var date_parts = inp.value.split('-');
var year = date_parts[0];
var month = parseFloat(date_parts[1]);
if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) {
DateTimeShortcuts.calendars[num].drawDate(month, year);
}
}
// Recalculate the clockbox position
// is it left-to-right or right-to-left layout ?

View File

@ -1,5 +1,9 @@
// Core javascript helper functions
// basic browser identification & version
var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion);
var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]);
// Cross-browser event handlers.
function addEvent(obj, evType, fn) {
if (obj.addEventListener) {
@ -71,9 +75,13 @@ function findPosX(obj) {
var curleft = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curleft += obj.offsetLeft;
curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);
obj = obj.offsetParent;
}
// IE offsetParent does not include the top-level
if (isIE && obj.parentElement){
curleft += obj.offsetLeft - obj.scrollLeft;
}
} else if (obj.x) {
curleft += obj.x;
}
@ -84,9 +92,13 @@ function findPosY(obj) {
var curtop = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curtop += obj.offsetTop;
curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);
obj = obj.offsetParent;
}
// IE offsetParent does not include the top-level
if (isIE && obj.parentElement){
curtop += obj.offsetTop - obj.scrollTop;
}
} else if (obj.y) {
curtop += obj.y;
}

View File

@ -40,6 +40,9 @@ var RUSSIAN_MAP = {
'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
'Я':'Ya'
}
var UKRAINIAN_MAP = {
'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
}
var CZECH_MAP = {
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
'ž':'z'
@ -51,7 +54,8 @@ ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
ALL_DOWNCODE_MAPS[2]=GREEK_MAP
ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
ALL_DOWNCODE_MAPS[5]=CZECH_MAP
ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
ALL_DOWNCODE_MAPS[6]=CZECH_MAP
var Downcoder = new Object();
Downcoder.Initialize = function()

View File

@ -10,7 +10,7 @@
</thead>
<tbody>
{% for result in results %}
<tr class="{% cycle row1,row2 %}">{% for item in result %}{{ item }}{% endfor %}</tr>
<tr class="{% cycle 'row1' 'row2' %}">{% for item in result %}{{ item }}{% endfor %}</tr>
{% endfor %}
</tbody>
</table>

View File

@ -1,8 +1,8 @@
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.http import HttpResponseRedirect
from urllib import quote
from django.utils.http import urlquote
def user_passes_test(test_func, login_url=None):
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
"""
Decorator for views that checks that the user passes the given test,
redirecting to the log-in page if necessary. The test should be a callable
@ -15,20 +15,25 @@ def user_passes_test(test_func, login_url=None):
def _checklogin(request, *args, **kwargs):
if test_func(request.user):
return view_func(request, *args, **kwargs)
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
return HttpResponseRedirect('%s?%s=%s' % (login_url, redirect_field_name, urlquote(request.get_full_path())))
_checklogin.__doc__ = view_func.__doc__
_checklogin.__dict__ = view_func.__dict__
return _checklogin
return _dec
login_required = user_passes_test(lambda u: u.is_authenticated())
login_required.__doc__ = (
def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
"""
Decorator for views that checks that the user is logged in, redirecting
to the log-in page if necessary.
"""
actual_decorator = user_passes_test(
lambda u: u.is_authenticated(),
redirect_field_name=redirect_field_name
)
if function:
return actual_decorator(function)
return actual_decorator
def permission_required(perm, login_url=None):
"""

View File

@ -10,6 +10,10 @@ def authenhandler(req, **kwargs):
# that so that the following import works
os.environ.update(req.subprocess_env)
# apache 2.2 requires a call to req.get_basic_auth_pw() before
# req.user and friends are available.
req.get_basic_auth_pw()
# check for PythonOptions
_str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes')

View File

@ -1,6 +1,7 @@
from django.core import validators
from django.core.exceptions import ImproperlyConfigured
from django.db import connection, models
from django.db.models.manager import EmptyManager
from django.contrib.contenttypes.models import ContentType
from django.utils.encoding import smart_str
from django.utils.translation import ugettext_lazy as _
@ -14,25 +15,43 @@ try:
except NameError:
from sets import Set as set # Python 2.3 fallback
def get_hexdigest(algorithm, salt, raw_password):
"""
Returns a string of the hexdigest of the given plaintext password and salt
using the given algorithm ('md5', 'sha1' or 'crypt').
"""
raw_password, salt = smart_str(raw_password), smart_str(salt)
if algorithm == 'crypt':
try:
import crypt
except ImportError:
raise ValueError('"crypt" password algorithm not supported in this environment')
return crypt.crypt(raw_password, salt)
# The rest of the supported algorithms are supported by hashlib, but
# hashlib is only available in Python 2.5.
try:
import hashlib
except ImportError:
if algorithm == 'md5':
import md5
return md5.new(salt + raw_password).hexdigest()
elif algorithm == 'sha1':
import sha
return sha.new(salt + raw_password).hexdigest()
else:
if algorithm == 'md5':
return hashlib.md5(salt + raw_password).hexdigest()
elif algorithm == 'sha1':
return hashlib.sha1(salt + raw_password).hexdigest()
raise ValueError("Got unknown password algorithm type in password.")
def check_password(raw_password, enc_password):
"""
Returns a boolean of whether the raw_password was correct. Handles
encryption formats behind the scenes.
"""
algo, salt, hsh = enc_password.split('$')
if algo == 'md5':
import md5
return hsh == md5.new(smart_str(salt + raw_password)).hexdigest()
elif algo == 'sha1':
import sha
return hsh == sha.new(smart_str(salt + raw_password)).hexdigest()
elif algo == 'crypt':
try:
import crypt
except ImportError:
raise ValueError, "Crypt password algorithm not supported in this environment."
return hsh == crypt.crypt(smart_str(raw_password), smart_str(salt))
raise ValueError, "Got unknown password algorithm type in password."
return hsh == get_hexdigest(algo, salt, raw_password)
class SiteProfileNotAvailable(Exception):
pass
@ -146,10 +165,10 @@ class User(models.Model):
return full_name.strip()
def set_password(self, raw_password):
import sha, random
import random
algo = 'sha1'
salt = sha.new(str(random.random())).hexdigest()[:5]
hsh = sha.new(salt + smart_str(raw_password)).hexdigest()
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
hsh = get_hexdigest(algo, salt, raw_password)
self.password = '%s$%s$%s' % (algo, salt, hsh)
def check_password(self, raw_password):
@ -160,8 +179,7 @@ class User(models.Model):
# Backwards-compatibility check. Older passwords won't include the
# algorithm or salt.
if '$' not in self.password:
import md5
is_correct = (self.password == md5.new(smart_str(raw_password)).hexdigest())
is_correct = (self.password == get_hexdigest('md5', '', raw_password))
if is_correct:
# Convert the password to the new, more secure format.
self.set_password(raw_password)
@ -278,6 +296,11 @@ class Message(models.Model):
class AnonymousUser(object):
id = None
username = ''
is_staff = False
is_active = True
is_superuser = False
_groups = EmptyManager()
_user_permissions = EmptyManager()
def __init__(self):
pass
@ -310,11 +333,11 @@ class AnonymousUser(object):
raise NotImplementedError
def _get_groups(self):
raise NotImplementedError
return self._groups
groups = property(_get_groups)
def _get_user_permissions(self):
raise NotImplementedError
return self._user_permissions
user_permissions = property(_get_user_permissions)
def has_perm(self, perm):

View File

@ -1,5 +1,5 @@
"""
>>> from models import User
>>> from models import User, AnonymousUser
>>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw')
>>> u.has_usable_password()
True
@ -16,4 +16,11 @@ False
>>> u2 = User.objects.create_user('testuser2', 'test2@example.com')
>>> u2.has_usable_password()
False
>>> a = AnonymousUser()
>>> a.is_staff
False
>>> a.groups.all()
[]
>>> a.user_permissions.all()
[]
"""

View File

@ -9,10 +9,10 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.utils.translation import ugettext as _
def login(request, template_name='registration/login.html'):
def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME):
"Displays the login form and handles the login action."
manipulator = AuthenticationForm(request)
redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '')
redirect_to = request.REQUEST.get(redirect_field_name, '')
if request.POST:
errors = manipulator.get_validation_errors(request.POST)
if not errors:
@ -35,7 +35,7 @@ def login(request, template_name='registration/login.html'):
return render_to_response(template_name, {
'form': oldforms.FormWrapper(manipulator, request.POST, errors),
REDIRECT_FIELD_NAME: redirect_to,
redirect_field_name: redirect_to,
'site_name': current_site.name,
}, context_instance=RequestContext(request))
@ -56,12 +56,12 @@ def logout_then_login(request, login_url=None):
login_url = settings.LOGIN_URL
return logout(request, login_url)
def redirect_to_login(next, login_url=None):
def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
"Redirects the user to the login page, passing the given 'next' page"
if not login_url:
from django.conf import settings
login_url = settings.LOGIN_URL
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next))
return HttpResponseRedirect('%s?%s=%s' % (login_url, redirect_field_name, next))
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
email_template_name='registration/password_reset_email.html'):

View File

@ -155,7 +155,7 @@ class PublicFreeCommentManipulator(oldforms.Manipulator):
c.save()
return c
def post_comment(request):
def post_comment(request, extra_context=None, context_processors=None):
"""
Post a comment
@ -185,6 +185,7 @@ def post_comment(request):
rating_choices
choice of ratings
"""
if extra_context is None: extra_context = {}
if not request.POST:
raise Http404, _("Only POSTs are allowed")
try:
@ -244,7 +245,7 @@ def post_comment(request):
'ratings_required': RATINGS_REQUIRED in option_list,
'rating_range': rating_range,
'rating_choices': rating_choices,
}, context_instance=RequestContext(request))
}, context_instance=RequestContext(request, extra_context, context_processors))
elif 'post' in request.POST:
# If the IP is banned, mail the admins, do NOT save the comment, and
# serve up the "Thanks for posting" page as if the comment WAS posted.
@ -257,7 +258,7 @@ def post_comment(request):
else:
raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
def post_free_comment(request):
def post_free_comment(request, extra_context=None, context_processors=None):
"""
Post a free comment (not requiring a log in)
@ -277,6 +278,7 @@ def post_free_comment(request):
security hash (must be included in a posted form to succesfully
post a comment).
"""
if extra_context is None: extra_context = {}
if not request.POST:
raise Http404, _("Only POSTs are allowed")
try:
@ -307,7 +309,7 @@ def post_free_comment(request):
'options': options,
'target': target,
'hash': security_hash,
}, context_instance=RequestContext(request))
}, context_instance=RequestContext(request, extra_context, context_processors))
elif 'post' in request.POST:
# If the IP is banned, mail the admins, do NOT save the comment, and
# serve up the "Thanks for posting" page as if the comment WAS posted.
@ -321,7 +323,7 @@ def post_free_comment(request):
else:
raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
def comment_was_posted(request):
def comment_was_posted(request, extra_context=None, context_processors=None):
"""
Display "comment was posted" success page
@ -330,6 +332,7 @@ def comment_was_posted(request):
object
The object the comment was posted on
"""
if extra_context is None: extra_context = {}
obj = None
if 'c' in request.GET:
content_type_id, object_id = request.GET['c'].split(':')
@ -338,4 +341,5 @@ def comment_was_posted(request):
obj = content_type.get_object_for_this_type(pk=object_id)
except ObjectDoesNotExist:
pass
return render_to_response('comments/posted.html', {'object': obj}, context_instance=RequestContext(request))
return render_to_response('comments/posted.html', {'object': obj},
context_instance=RequestContext(request, extra_context, context_processors))

View File

@ -4,7 +4,7 @@ from django.template import RequestContext
from django.contrib.comments.models import Comment, KarmaScore
from django.utils.translation import ugettext as _
def vote(request, comment_id, vote):
def vote(request, comment_id, vote, extra_context=None, context_processors=None):
"""
Rate a comment (+1 or -1)
@ -13,6 +13,7 @@ def vote(request, comment_id, vote):
comment
`comments.comments` object being rated
"""
if extra_context is None: extra_context = {}
rating = {'up': 1, 'down': -1}.get(vote, False)
if not rating:
raise Http404, "Invalid vote"
@ -27,4 +28,5 @@ def vote(request, comment_id, vote):
KarmaScore.objects.vote(request.user.id, comment_id, rating)
# Reload comment to ensure we have up to date karma count
comment = Comment.objects.get(pk=comment_id)
return render_to_response('comments/karma_vote_accepted.html', {'comment': comment}, context_instance=RequestContext(request))
return render_to_response('comments/karma_vote_accepted.html', {'comment': comment},
context_instance=RequestContext(request, extra_context, context_processors))

View File

@ -6,7 +6,7 @@ from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from django.conf import settings
def flag(request, comment_id):
def flag(request, comment_id, extra_context=None, context_processors=None):
"""
Flags a comment. Confirmation on GET, action on POST.
@ -15,18 +15,22 @@ def flag(request, comment_id):
comment
the flagged `comments.comments` object
"""
if extra_context is None: extra_context = {}
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
if request.POST:
UserFlag.objects.flag(comment, request.user)
return HttpResponseRedirect('%sdone/' % request.path)
return render_to_response('comments/flag_verify.html', {'comment': comment}, context_instance=RequestContext(request))
return render_to_response('comments/flag_verify.html', {'comment': comment},
context_instance=RequestContext(request, extra_context, context_processors))
flag = login_required(flag)
def flag_done(request, comment_id):
def flag_done(request, comment_id, extra_context=None, context_processors=None):
if extra_context is None: extra_context = {}
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
return render_to_response('comments/flag_done.html', {'comment': comment}, context_instance=RequestContext(request))
return render_to_response('comments/flag_done.html', {'comment': comment},
context_instance=RequestContext(request, extra_context, context_processors))
def delete(request, comment_id):
def delete(request, comment_id, extra_context=None, context_processors=None):
"""
Deletes a comment. Confirmation on GET, action on POST.
@ -35,6 +39,7 @@ def delete(request, comment_id):
comment
the flagged `comments.comments` object
"""
if extra_context is None: extra_context = {}
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
if not Comment.objects.user_is_moderator(request.user):
raise Http404
@ -46,9 +51,12 @@ def delete(request, comment_id):
m = ModeratorDeletion(None, request.user.id, comment.id, None)
m.save()
return HttpResponseRedirect('%sdone/' % request.path)
return render_to_response('comments/delete_verify.html', {'comment': comment}, context_instance=RequestContext(request))
return render_to_response('comments/delete_verify.html', {'comment': comment},
context_instance=RequestContext(request, extra_context, context_processors))
delete = login_required(delete)
def delete_done(request, comment_id):
def delete_done(request, comment_id, extra_context=None, context_processors=None):
if extra_context is None: extra_context = {}
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
return render_to_response('comments/delete_done.html', {'comment': comment}, context_instance=RequestContext(request))
return render_to_response('comments/delete_done.html', {'comment': comment},
context_instance=RequestContext(request, extra_context, context_processors))

View File

@ -1,34 +1,43 @@
"""
Creates content types for all installed models.
"""
from django.contrib.contenttypes.models import ContentType
from django.dispatch import dispatcher
from django.db.models import get_apps, get_models, signals
from django.utils.encoding import smart_unicode
def create_contenttypes(app, created_models, verbosity=2):
from django.contrib.contenttypes.models import ContentType
def update_contenttypes(app, created_models, verbosity=2):
"""
Creates content types for models in the given app, removing any model
entries that no longer have a matching model class.
"""
ContentType.objects.clear_cache()
content_types = list(ContentType.objects.filter(app_label=app.__name__.split('.')[-2]))
app_models = get_models(app)
if not app_models:
return
for klass in app_models:
opts = klass._meta
try:
ContentType.objects.get(app_label=opts.app_label,
ct = ContentType.objects.get(app_label=opts.app_label,
model=opts.object_name.lower())
content_types.remove(ct)
except ContentType.DoesNotExist:
ct = ContentType(name=smart_unicode(opts.verbose_name_raw),
app_label=opts.app_label, model=opts.object_name.lower())
ct.save()
if verbosity >= 2:
print "Adding content type '%s | %s'" % (ct.app_label, ct.model)
# The presence of any remaining content types means the supplied app has an
# undefined model and can safely be removed, which cascades to also remove
# related permissions.
for ct in content_types:
if verbosity >= 2:
print "Deleting stale content type '%s | %s'" % (ct.app_label, ct.model)
ct.delete()
def create_all_contenttypes(verbosity=2):
def update_all_contenttypes(verbosity=2):
for app in get_apps():
create_contenttypes(app, None, verbosity)
update_contenttypes(app, None, verbosity)
dispatcher.connect(create_contenttypes, signal=signals.post_syncdb)
dispatcher.connect(update_contenttypes, signal=signals.post_syncdb)
if __name__ == "__main__":
create_all_contenttypes()
update_all_contenttypes()

View File

@ -25,7 +25,7 @@ class ContentTypeManager(models.Manager):
"""
Clear out the content-type cache. This needs to happen during database
flushes to prevent caching of "stale" content type IDs (see
django.contrib.contenttypes.management.create_contenttypes for where
django.contrib.contenttypes.management.update_contenttypes for where
this gets called).
"""
global CONTENT_TYPE_CACHE

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for field in field_list %}
<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for year in date_list %}
<li class="{% cycle odd,even %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for month in date_list %}
<li class="{% cycle odd,even %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for choice in field.choices %}
<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for field in field_list %}
<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<ul class="objectlist">
{% for object in object_list %}
<li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
{% endfor %}
</ul>

View File

@ -7,7 +7,7 @@
{% block content %}
{% for model in model_list %}
<div class="modelgroup {% cycle even,odd %}">
<div class="modelgroup {% cycle 'even' 'odd' %}">
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
<p>
{% for object in model.sample_objects %}

View File

@ -12,7 +12,7 @@
<ul class="objectlist">
{% for object in model.objects %}
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>

View File

@ -10,7 +10,7 @@
<table class="objectinfo">
{% for field in object.fields %}
<tr class="{% cycle odd,even %}">
<tr class="{% cycle 'odd' 'even' %}">
<th>{{ field.field.verbose_name|capfirst }}</th>
<td>
{% if field.urls %}
@ -29,7 +29,7 @@
{% if related_object.object_list %}
<ul class="objectlist">
{% for object in related_object.object_list %}
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
{% endfor %}
</ul>
{% else %}

View File

@ -1,47 +1,5 @@
"""
Formtools Preview application.
This is an abstraction of the following workflow:
"Display an HTML form, force a preview, then do something with the submission."
Given a django.newforms.Form object that you define, this takes care of the
following:
* Displays the form as HTML on a Web page.
* Validates the form data once it's submitted via POST.
* If it's valid, displays a preview page.
* If it's not valid, redisplays the form with error messages.
* At the preview page, if the preview confirmation button is pressed, calls
a hook that you define -- a done() method.
The framework enforces the required preview by passing a shared-secret hash to
the preview page. If somebody tweaks the form parameters on the preview page,
the form submission will fail the hash comparison test.
Usage
=====
Subclass FormPreview and define a done() method:
def done(self, request, cleaned_data):
# ...
This method takes an HttpRequest object and a dictionary of the form data after
it has been validated and cleaned. It should return an HttpResponseRedirect.
Then, just instantiate your FormPreview subclass by passing it a Form class,
and pass that to your URLconf, like so:
(r'^post/$', MyFormPreview(MyForm)),
The FormPreview class has a few other hooks. See the docstrings in the source
code below.
The framework also uses two templates: 'formtools/preview.html' and
'formtools/form.html'. You can override these by setting 'preview_template' and
'form_template' attributes on your FormPreview subclass. See
django/contrib/formtools/templates for the default templates.
"""
from django.conf import settings

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""
A list of Argentinean provinces and autonomous cities as `choices` in a
formfield. From
http://www.argentina.gov.ar/argentina/portal/paginas.dhtml?pagina=425
This exists in this standalone file so that it's only imported into memory
when explicitly needed.
"""
PROVINCE_CHOICES = (
('B', u'Buenos Aires'),
('K', u'Catamarca'),
('H', u'Chaco'),
('U', u'Chubut'),
('C', u'Ciudad Autónoma de Buenos Aires'),
('X', u'Córdoba'),
('W', u'Corrientes'),
('E', u'Entre Ríos'),
('P', u'Formosa'),
('Y', u'Jujuy'),
('L', u'La Pampa'),
('F', u'La Rioja'),
('M', u'Mendoza'),
('N', u'Misiones'),
('Q', u'Neuquén'),
('R', u'Río Negro'),
('A', u'Salta'),
('J', u'San Juan'),
('D', u'San Luis'),
('Z', u'Santa Cruz'),
('S', u'Santa Fe'),
('G', u'Santiago del Estero'),
('V', u'Tierra del Fuego, Antártida e Islas del Atlántico Sur'),
('T', u'Tucumán'),
)

View File

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
"""
AR-specific Form helpers.
"""
from django.newforms import ValidationError
from django.newforms.fields import RegexField, CharField, Select, EMPTY_VALUES
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext
import re
class ARProvinceSelect(Select):
"""
A Select widget that uses a list of Argentinean provinces/autonomous cities
as its choices.
"""
def __init__(self, attrs=None):
from ar_provinces import PROVINCE_CHOICES
super(ARProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
class ARPostalCodeField(RegexField):
"""
A field that accepts a `classic´ NNNN Postal Code or a CPA.
See http://www.correoargentino.com.ar/consulta_cpa/home.php
"""
def __init__(self, *args, **kwargs):
super(ARPostalCodeField, self).__init__(r'^\d{4}$|^[A-HJ-NP-Za-hj-np-z]\d{4}\D{3}$',
min_length=4, max_length=8,
error_message=ugettext("Enter a postal code in the format NNNN or ANNNNAAA."),
*args, **kwargs)
def clean(self, value):
value = super(ARPostalCodeField, self).clean(value)
if value in EMPTY_VALUES:
return u''
if len(value) not in (4, 8):
raise ValidationError(ugettext("Enter a postal code in the format NNNN or ANNNNAAA."))
if len(value) == 8:
return u'%s%s%s' % (value[0].upper(), value[1:5], value[5:].upper())
return value
class ARDNIField(CharField):
"""
A field that validates `Documento Nacional de Identidad´ (DNI) numbers.
"""
def __init__(self, *args, **kwargs):
super(ARDNIField, self).__init__(max_length=10, min_length=7, *args,
**kwargs)
def clean(self, value):
"""
Value can be a string either in the [X]X.XXX.XXX or [X]XXXXXXX formats.
"""
value = super(ARDNIField, self).clean(value)
if value in EMPTY_VALUES:
return u''
if not value.isdigit():
value = value.replace('.', '')
if not value.isdigit():
raise ValidationError(ugettext("This field requires only numbers."))
if len(value) not in (7, 8):
raise ValidationError(
ugettext("This field requires 7 or 8 digits."))
return value
class ARCUITField(RegexField):
"""
This field validates a CUIT (Código Único de Identificación Tributaria). A
CUIT is of the form XX-XXXXXXXX-V. The last digit is a check digit.
"""
def __init__(self, *args, **kwargs):
super(ARCUITField, self).__init__(r'^\d{2}-?\d{8}-?\d$',
error_message=ugettext('Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'),
*args, **kwargs)
def clean(self, value):
"""
Value can be either a string in the format XX-XXXXXXXX-X or an
11-digit number.
"""
value = super(ARCUITField, self).clean(value)
if value in EMPTY_VALUES:
return u''
value, cd = self._canon(value)
if self._calc_cd(value) != cd:
raise ValidationError(ugettext("Invalid CUIT."))
return self._format(value, cd)
def _canon(self, cuit):
cuit = cuit.replace('-', '')
return cuit[:-1], cuit[-1]
def _calc_cd(self, cuit):
mults = (5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
tmp = sum([m * int(cuit[idx]) for idx, m in enumerate(mults)])
return str(11 - tmp % 11)
def _format(self, cuit, check_digit=None):
if check_digit == None:
check_digit = cuit[-1]
cuit = cuit[:-1]
return u'%s-%s-%s' % (cuit[:2], cuit[2:], check_digit)

View File

@ -6,16 +6,21 @@ BR-specific Form helpers
from django.newforms import ValidationError
from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext
from django.utils.translation import ugettext as _
import re
try:
set
except NameError:
from sets import Set as set # For Python 2.3
phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
class BRZipCodeField(RegexField):
def __init__(self, *args, **kwargs):
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
max_length=None, min_length=None,
error_message=ugettext('Enter a zip code in the format XXXXX-XXX.'),
error_message=_('Enter a zip code in the format XXXXX-XXX.'),
*args, **kwargs)
class BRPhoneNumberField(Field):
@ -27,7 +32,7 @@ class BRPhoneNumberField(Field):
m = phone_digits_re.search(value)
if m:
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
raise ValidationError(ugettext('Phone numbers must be in XX-XXXX-XXXX format.'))
raise ValidationError(_('Phone numbers must be in XX-XXXX-XXXX format.'))
class BRStateSelect(Select):
"""
@ -38,6 +43,32 @@ class BRStateSelect(Select):
from br_states import STATE_CHOICES
super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
class BRStateChoiceField(Field):
"""
A choice field that uses a list of Brazilian states as its choices.
"""
widget = Select
def __init__(self, required=True, widget=None, label=None,
initial=None, help_text=None):
super(BRStateChoiceField, self).__init__(required, widget, label,
initial, help_text)
from br_states import STATE_CHOICES
self.widget.choices = STATE_CHOICES
def clean(self, value):
value = super(BRStateChoiceField, self).clean(value)
if value in EMPTY_VALUES:
value = u''
value = smart_unicode(value)
if value == u'':
return value
valid_values = set([smart_unicode(k) for k, v in self.widget.choices])
if value not in valid_values:
raise ValidationError(_(u'Select a valid brazilian state.'
u' That state is not one'
u' of the available states.'))
return value
def DV_maker(v):
if v >= 2:
@ -69,9 +100,9 @@ class BRCPFField(CharField):
try:
int(value)
except ValueError:
raise ValidationError(ugettext("This field requires only numbers."))
raise ValidationError(_("This field requires only numbers."))
if len(value) != 11:
raise ValidationError(ugettext("This field requires at most 11 digits or 14 characters."))
raise ValidationError(_("This field requires at most 11 digits or 14 characters."))
orig_dv = value[-2:]
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
@ -81,7 +112,7 @@ class BRCPFField(CharField):
new_2dv = DV_maker(new_2dv % 11)
value = value[:-1] + str(new_2dv)
if value[-2:] != orig_dv:
raise ValidationError(ugettext("Invalid CPF number."))
raise ValidationError(_("Invalid CPF number."))
return orig_value
@ -103,7 +134,7 @@ class BRCNPJField(Field):
raise ValidationError("This field requires only numbers.")
if len(value) != 14:
raise ValidationError(
ugettext("This field requires at least 14 digits"))
_("This field requires at least 14 digits"))
orig_dv = value[-2:]
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
@ -113,7 +144,7 @@ class BRCNPJField(Field):
new_2dv = DV_maker(new_2dv % 11)
value = value[:-1] + str(new_2dv)
if value[-2:] != orig_dv:
raise ValidationError(ugettext("Invalid CNPJ number."))
raise ValidationError(_("Invalid CNPJ number."))
return orig_value

View File

@ -0,0 +1,57 @@
"""
An alphabetical list of provinces and territories for use as `choices`
in a formfield., and a mapping of province misspellings/abbreviations to
normalized abbreviations
Source: http://www.canada.gc.ca/othergov/prov_e.html
This exists in this standalone file so that it's only imported into memory
when explicitly needed.
"""
PROVINCE_CHOICES = (
('AB', 'Alberta'),
('BC', 'British Columbia'),
('MB', 'Manitoba'),
('NB', 'New Brunswick'),
('NF', 'Newfoundland and Labrador'),
('NT', 'Northwest Territories'),
('NS', 'Nova Scotia'),
('NU', 'Nunavut'),
('ON', 'Ontario'),
('PE', 'Prince Edward Island'),
('QC', 'Quebec'),
('SK', 'Saskatchewan'),
('YK', 'Yukon')
)
PROVINCES_NORMALIZED = {
'ab': 'AB',
'alberta': 'AB',
'bc': 'BC',
'b.c.': 'BC',
'british columbia': 'BC',
'mb': 'MB',
'manitoba': 'MB',
'nf': 'NF',
'newfoundland': 'NF',
'newfoundland and labrador': 'NF',
'nt': 'NT',
'northwest territories': 'NT',
'ns': 'NS',
'nova scotia': 'NS',
'nu': 'NU',
'nunavut': 'NU',
'on': 'ON',
'ontario': 'ON',
'pe': 'PE',
'pei': 'PE',
'p.e.i.': 'PE',
'prince edward island': 'PE',
'qc': 'QC',
'quebec': 'QC',
'sk': 'SK',
'saskatchewan': 'SK',
'yk': 'YK',
'yukon': 'YK',
}

View File

@ -0,0 +1,112 @@
"""
Canada-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, ugettext
import re
phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
sin_re = re.compile(r"^(\d{3})-(\d{3})-(\d{3})$")
class CAPostalCodeField(RegexField):
"""Canadian postal code field."""
def __init__(self, *args, **kwargs):
super(CAPostalCodeField, self).__init__(r'^[ABCEGHJKLMNPRSTVXYZ]\d[A-Z] \d[A-Z]\d$',
max_length=None, min_length=None,
error_message=gettext(u'Enter a postal code in the format XXX XXX.'),
*args, **kwargs)
class CAPhoneNumberField(Field):
"""Canadian phone number field."""
def clean(self, value):
"""Validate a phone number.
"""
super(CAPhoneNumberField, self).clean(value)
if value in EMPTY_VALUES:
return u''
value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
m = phone_digits_re.search(value)
if m:
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
raise ValidationError(u'Phone numbers must be in XXX-XXX-XXXX format.')
class CAProvinceField(Field):
"""
A form field that validates its input is a Canadian province name or abbreviation.
It normalizes the input to the standard two-leter postal service
abbreviation for the given province.
"""
def clean(self, value):
from ca_provinces import PROVINCES_NORMALIZED
super(CAProvinceField, self).clean(value)
if value in EMPTY_VALUES:
return u''
try:
value = value.strip().lower()
except AttributeError:
pass
else:
try:
return PROVINCES_NORMALIZED[value.strip().lower()].decode('ascii')
except KeyError:
pass
raise ValidationError(u'Enter a Canadian province or territory.')
class CAProvinceSelect(Select):
"""
A Select widget that uses a list of Canadian provinces and
territories as its choices.
"""
def __init__(self, attrs=None):
from ca_provinces import PROVINCE_CHOICES # relative import
super(CAProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
class CASocialInsuranceNumberField(Field):
"""
A Canadian Social Insurance Number (SIN).
Checks the following rules to determine whether the number is valid:
* Conforms to the XXX-XXX-XXXX format.
* Passes the check digit process "Luhn Algorithm"
See: http://en.wikipedia.org/wiki/Social_Insurance_Number
"""
def clean(self, value):
super(CASocialInsuranceNumberField, self).clean(value)
if value in EMPTY_VALUES:
return u''
msg = ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.')
match = re.match(sin_re, value)
if not match:
raise ValidationError(msg)
number = u'%s-%s-%s' % (match.group(1), match.group(2), match.group(3))
check_number = u'%s%s%s' % (match.group(1), match.group(2), match.group(3))
if not self.luhn_checksum_is_valid(check_number):
raise ValidationError(msg)
return number
def luhn_checksum_is_valid(self, number):
"""
Checks to make sure that the SIN passes a luhn mod-10 checksum
See: http://en.wikipedia.org/wiki/Luhn_algorithm
"""
sum = 0
num_digits = len(number)
oddeven = num_digits & 1
for count in range(0, num_digits):
digit = int(number[count])
if not (( count & 1 ) ^ oddeven ):
digit = digit * 2
if digit > 9:
digit = digit - 9
sum = sum + digit
return ( (sum % 10) == 0 )

View File

@ -0,0 +1,38 @@
from django import newforms as forms
DEFAULT_DATE_INPUT_FORMATS = (
'%Y-%m-%d', '%d/%m/%Y', '%d/%m/%y', # '2006-10-25', '25/10/2006', '25/10/06'
'%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
'%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
'%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
'%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
)
DEFAULT_DATETIME_INPUT_FORMATS = (
'%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59'
'%Y-%m-%d %H:%M', # '2006-10-25 14:30'
'%Y-%m-%d', # '2006-10-25'
'%d/%m/%Y %H:%M:%S', # '25/10/2006 14:30:59'
'%d/%m/%Y %H:%M', # '25/10/2006 14:30'
'%d/%m/%Y', # '25/10/2006'
'%d/%m/%y %H:%M:%S', # '25/10/06 14:30:59'
'%d/%m/%y %H:%M', # '25/10/06 14:30'
'%d/%m/%y', # '25/10/06'
)
class DateField(forms.DateField):
"""
A date input field which uses non-US date input formats by default.
"""
def __init__(self, input_formats=None, *args, **kwargs):
input_formats = input_formats or DEFAULT_DATE_INPUT_FORMATS
super(DateField, self).__init__(input_formats=input_formats, *args, **kwargs)
class DateTimeField(forms.DateTimeField):
"""
A date and time input field which uses non-US date and time input formats
by default.
"""
def __init__(self, input_formats=None, *args, **kwargs):
input_formats = input_formats or DEFAULT_DATETIME_INPUT_FORMATS
super(DateTimeField, self).__init__(input_formats=input_formats, *args, **kwargs)

View File

@ -0,0 +1,92 @@
"""
NL-specific Form helpers
"""
import re
from django.newforms import ValidationError
from django.newforms.fields import Field, Select, EMPTY_VALUES
from django.utils.translation import ugettext as _
from django.utils.encoding import smart_unicode
pc_re = re.compile('^\d{4}[A-Z]{2}$')
sofi_re = re.compile('^\d{9}$')
numeric_re = re.compile('^\d+$')
class NLZipCodeField(Field):
"""
A Dutch postal code field.
"""
def clean(self, value):
super(NLZipCodeField, self).clean(value)
if value in EMPTY_VALUES:
return u''
msg = _('Enter a valid postal code')
value = value.strip().upper().replace(' ', '')
if not pc_re.search(value):
raise ValidationError(msg)
if int(value[:4]) < 1000:
raise ValidationError(msg)
return u'%s %s' % (value[:4], value[4:])
class NLProvinceSelect(Select):
"""
A Select widget that uses a list of provinces of the Netherlands as its
choices.
"""
def __init__(self, attrs=None):
from nl_provinces import PROVINCE_CHOICES
super(NLProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
class NLPhoneNumberField(Field):
"""
A Dutch telephone number field.
"""
def clean(self, value):
super(NLPhoneNumberField, self).clean(value)
if value in EMPTY_VALUES:
return u''
msg = _('Enter a valid phone number')
phone_nr = re.sub('[\-\s\(\)]', '', smart_unicode(value))
if len(phone_nr) == 10 and numeric_re.search(phone_nr):
return value
if phone_nr[:3] == '+31' and len(phone_nr) == 12 and \
numeric_re.search(phone_nr[3:]):
return value
raise ValidationError(msg)
class NLSoFiNumberField(Field):
"""
A Dutch social security number (SoFi/BSN) field.
http://nl.wikipedia.org/wiki/Sofinummer
"""
def clean(self, value):
super(NLSoFiNumberField, self).clean(value)
if value in EMPTY_VALUES:
return u''
msg = _('Enter a valid SoFi number')
if not sofi_re.search(value):
raise ValidationError(msg)
if int(value) == 0:
raise ValidationError(msg)
checksum = 0
for i in range(9, 1, -1):
checksum += int(value[9-i]) * i
checksum -= int(value[-1])
if checksum % 11 != 0:
raise ValidationError(msg)
return value

View File

@ -0,0 +1,16 @@
from django.utils.translation import ugettext_lazy as _
PROVINCE_CHOICES = (
('DR', _('Drente')),
('FL', _('Flevoland')),
('FR', _('Friesland')),
('GL', _('Gelderland')),
('GR', _('Groningen')),
('LB', _('Limburg')),
('NB', _('Noord-Brabant')),
('NH', _('Noord-Holland')),
('OV', _('Overijssel')),
('UT', _('Utrecht')),
('ZE', _('Zeeland')),
('ZH', _('Zuid-Holland')),
)

View File

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
"""
PE-specific Form helpers.
"""
from django.newforms import ValidationError
from django.newforms.fields import RegexField, CharField, Select, EMPTY_VALUES
from django.utils.translation import ugettext
class PEDepartmentSelect(Select):
"""
A Select widget that uses a list of Peruvian Departments as its choices.
"""
def __init__(self, attrs=None):
from pe_department import DEPARTMENT_CHOICES
super(PEDepartmentSelect, self).__init__(attrs, choices=DEPARTMENT_CHOICES)
class PEDNIField(CharField):
"""
A field that validates `Documento Nacional de IdentidadŽ (DNI) numbers.
"""
def __init__(self, *args, **kwargs):
super(PEDNIField, self).__init__(max_length=8, min_length=8, *args,
**kwargs)
def clean(self, value):
"""
Value must be a string in the XXXXXXXX formats.
"""
value = super(PEDNIField, self).clean(value)
if value in EMPTY_VALUES:
return u''
if not value.isdigit():
raise ValidationError(ugettext("This field requires only numbers."))
if len(value) != 8:
raise ValidationError(ugettext("This field requires 8 digits."))
return value
class PERUCField(RegexField):
"""
This field validates a RUC (Registro Unico de Contribuyentes). A RUC is of
the form XXXXXXXXXXX.
"""
def __init__(self, *args, **kwargs):
super(PERUCField, self).__init__(max_length=11, min_length=11, *args,
**kwargs)
def clean(self, value):
"""
Value must be an 11-digit number.
"""
value = super(PERUCField, self).clean(value)
if value in EMPTY_VALUES:
return u''
if not value.isdigit():
raise ValidationError(ugettext("This field requires only numbers."))
if len(value) != 11:
raise ValidationError(ugettext("This field requires 11 digits."))
return value

View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
"""
A list of Peru departaments as `choices` in a
formfield.
This exists in this standalone file so that it's only imported into memory
when explicitly needed.
"""
DEPARTMENT_CHOICES = (
('AMA', u'Amazonas'),
('ANC', u'Ancash'),
('APU', u'Apurímac'),
('ARE', u'Arequipa'),
('AYA', u'Ayacucho'),
('CAJ', u'Cajamarca'),
('CUS', u'Cusco'),
('HUV', u'Huancavelica'),
('HUC', u'Huánuco'),
('ICA', u'Ica'),
('JUN', u'Junín'),
('LAL', u'La Libertad'),
('LAM', u'Lambayeque'),
('LIM', u'Lima'),
('LOR', u'Loreto'),
('MDD', u'Madre de Dios'),
('MOQ', u'Moquegua'),
('PAS', u'Pasco'),
('PIU', u'Piura'),
('PUN', u'Puno'),
('SAM', u'San Martín'),
('TAC', u'Tacna'),
('TUM', u'Tumbes'),
('UCA', u'Ucayali'),
)

View File

@ -15,8 +15,13 @@ class SessionManager(models.Manager):
"Returns session key that isn't being used."
# The random module is seeded when this Apache child is created.
# Use SECRET_KEY as added salt.
try:
pid = os.getpid()
except AttributeError:
# No getpid() in Jython, for example
pid = 1
while 1:
session_key = md5.new("%s%s%s%s" % (random.randint(0, sys.maxint - 1), os.getpid(), time.time(), settings.SECRET_KEY)).hexdigest()
session_key = md5.new("%s%s%s%s" % (random.randint(0, sys.maxint - 1), pid, time.time(), settings.SECRET_KEY)).hexdigest()
try:
self.get(session_key=session_key)
except self.model.DoesNotExist:

View File

@ -1,15 +1,32 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
SITE_CACHE = {}
class SiteManager(models.Manager):
def get_current(self):
"""
Returns the current ``Site`` based on the SITE_ID in the
project's settings. The ``Site`` object is cached the first
time it's retrieved from the database.
"""
from django.conf import settings
try:
sid = settings.SITE_ID
except AttributeError:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured("You're using the Django \"sites framework\" without having set the SITE_ID setting. Create a site in your database and set the SITE_ID setting to fix this error.")
return self.get(pk=sid)
try:
current_site = SITE_CACHE[sid]
except KeyError:
current_site = self.get(pk=sid)
SITE_CACHE[sid] = current_site
return current_site
def clear_cache(self):
"""Clears the ``Site`` object cache."""
global SITE_CACHE
SITE_CACHE = {}
class Site(models.Model):
domain = models.CharField(_('domain name'), max_length=100)
@ -46,7 +63,10 @@ class RequestSite(object):
The save() and delete() methods raise NotImplementedError.
"""
def __init__(self, request):
self.domain = self.name = request.META['SERVER_NAME']
self.domain = self.name = request.get_host()
def __unicode__(self):
return self.domain
def save(self):
raise NotImplementedError('RequestSite cannot be saved.')

View File

@ -62,6 +62,6 @@ def lorem(parser, token):
count = '1'
count = parser.compile_filter(count)
if len(bits) != 1:
raise TemplateSyntaxError("Incorrect format for %r tag" % tagname)
raise template.TemplateSyntaxError("Incorrect format for %r tag" % tagname)
return LoremNode(count, method, common)
lorem = register.tag(lorem)

View File

@ -7,6 +7,10 @@ u'lorem ipsum dolor sit amet consectetur adipisicing'
>>> paragraphs(1)
['Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.']
>>> from django.template import loader, Context
>>> t = loader.get_template_from_string("{% load webdesign %}{% lorem 3 w %}")
>>> t.render(Context({}))
u'lorem ipsum dolor'
"""
from django.contrib.webdesign.lorem_ipsum import *

View File

@ -1,11 +0,0 @@
# This module is DEPRECATED!
#
# You should no longer be pointing your mod_python configuration
# at "django.core.handler".
#
# Use "django.core.handlers.modpython" instead.
from django.core.handlers.modpython import ModPythonHandler
def handler(req):
return ModPythonHandler()(req)

View File

@ -50,6 +50,10 @@ class BaseHandler(object):
def get_response(self, request):
"Returns an HttpResponse object for the given HttpRequest"
response = self._real_get_response(request)
return fix_location_header(request, response)
def _real_get_response(self, request):
from django.core import exceptions, urlresolvers
from django.core.mail import mail_admins
from django.conf import settings
@ -112,7 +116,7 @@ class BaseHandler(object):
else:
# Get the exception info now, in case another exception is thrown later.
exc_info = sys.exc_info()
receivers = dispatcher.send(signal=signals.got_request_exception)
receivers = dispatcher.send(signal=signals.got_request_exception, request=request)
# When DEBUG is False, send an error message to the admins.
subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
try:
@ -129,3 +133,16 @@ class BaseHandler(object):
"Helper function to return the traceback as a string"
import traceback
return '\n'.join(traceback.format_exception(*(exc_info or sys.exc_info())))
def fix_location_header(request, response):
"""
Ensure that we always use an absolute URI in any location header in the
response. This is required by RFC 2616, section 14.30.
Code constructing response objects is free to insert relative paths and
this function converts them to absolute paths.
"""
if 'Location' in response and request.get_host():
response['Location'] = request.build_absolute_uri(response['Location'])
return response

View File

@ -159,8 +159,8 @@ class ModPythonHandler(BaseHandler):
# Convert our custom HttpResponse object back into the mod_python req.
req.content_type = response['Content-Type']
for key, value in response.headers.items():
if key != 'Content-Type':
for key, value in response.items():
if key != 'content-type':
req.headers_out[str(key)] = str(value)
for c in response.cookies.values():
req.headers_out.add('Set-Cookie', c.output(header=''))

View File

@ -208,7 +208,7 @@ class WSGIHandler(BaseHandler):
except KeyError:
status_text = 'UNKNOWN STATUS CODE'
status = '%s %s' % (response.status_code, status_text)
response_headers = [(str(k), str(v)) for k, v in response.headers.items()]
response_headers = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append(('Set-Cookie', str(c.output(header=''))))
start_response(status, response_headers)

View File

@ -50,7 +50,11 @@ def make_msgid(idstring=None):
"""
timeval = time.time()
utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval))
try:
pid = os.getpid()
except AttributeError:
# Not getpid() in Jython, for example.
pid = 1
randint = random.randrange(100000)
if idstring is None:
idstring = ''

View File

@ -206,7 +206,11 @@ def copy_helper(style, app_or_project, name, directory, other_name=''):
def _make_writeable(filename):
"Makes sure that the file is writeable. Useful if our source is read-only."
import stat
if sys.platform.startswith('java'):
# On Jython there is no os.access()
return
if not os.access(filename, os.W_OK):
st = os.stat(filename)
new_permissions = stat.S_IMODE(st.st_mode) | stat.S_IWUSR
os.chmod(filename, new_permissions)

View File

@ -1,4 +1,5 @@
from django.core.management.base import AppCommand
from django.utils.encoding import force_unicode
from django.utils.text import capfirst
MODULE_TEMPLATE = ''' {%% if perms.%(app)s.%(addperm)s or perms.%(app)s.%(changeperm)s %%}
@ -24,7 +25,7 @@ class Command(AppCommand):
output.append(MODULE_TEMPLATE % {
'app': app_label,
'mod': model._meta.module_name,
'name': capfirst(model._meta.verbose_name_plural),
'name': force_unicode(capfirst(model._meta.verbose_name_plural)),
'addperm': model._meta.get_add_permission(),
'changeperm': model._meta.get_change_permission(),
})

View File

@ -1,3 +1,4 @@
import os
from django.core.management.base import NoArgsCommand
from optparse import make_option
@ -43,4 +44,16 @@ class Command(NoArgsCommand):
import rlcompleter
readline.set_completer(rlcompleter.Completer(imported_objects).complete)
readline.parse_and_bind("tab:complete")
# We want to honor both $PYTHONSTARTUP and .pythonrc.py, so follow system
# conventions and get $PYTHONSTARTUP first then import user.
if not use_plain:
pythonrc = os.environ.get("PYTHONSTARTUP")
if pythonrc and os.path.isfile(pythonrc):
try:
execfile(pythonrc)
except NameError:
pass
# This will import .pythonrc.py as a side-effect
import user
code.interact(local=imported_objects)

View File

@ -38,16 +38,16 @@ class Command(NoArgsCommand):
cursor = connection.cursor()
# Get a list of all existing database tables,
# so we know what needs to be added.
table_list = table_list()
if connection.features.uses_case_insensitive_names:
table_name_converter = str.upper
table_name_converter = lambda x: x.upper()
else:
table_name_converter = lambda x: x
# Get a list of all existing database tables, so we know what needs to
# be added.
tables = [table_name_converter(name) for name in table_list()]
# Get a list of already installed *models* so that references work right.
seen_models = installed_models(table_list)
seen_models = installed_models(tables)
created_models = set()
pending_references = {}
@ -59,7 +59,7 @@ class Command(NoArgsCommand):
# Create the model's database table, if it doesn't already exist.
if verbosity >= 2:
print "Processing %s.%s model" % (app_name, model._meta.object_name)
if table_name_converter(model._meta.db_table) in table_list:
if table_name_converter(model._meta.db_table) in tables:
continue
sql, references = sql_model_create(model, self.style, seen_models)
seen_models.add(model)
@ -71,7 +71,7 @@ class Command(NoArgsCommand):
print "Creating table %s" % model._meta.db_table
for statement in sql:
cursor.execute(statement)
table_list.append(table_name_converter(model._meta.db_table))
tables.append(table_name_converter(model._meta.db_table))
# Create the m2m tables. This must be done after all tables have been created
# to ensure that all referred tables will exist.

View File

@ -7,6 +7,9 @@ class Command(BaseCommand):
make_option('--verbosity', action='store', dest='verbosity', default='1',
type='choice', choices=['0', '1', '2'],
help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
make_option('--addrport', action='store', dest='addrport',
type='string', default='',
help='port number or ipaddr:port to run the server on'),
)
help = 'Runs a development server with data from the given fixture(s).'
args = '[fixture ...]'
@ -19,6 +22,7 @@ class Command(BaseCommand):
from django.test.utils import create_test_db
verbosity = int(options.get('verbosity', 1))
addrport = options.get('addrport')
# Create a test database.
db_name = create_test_db(verbosity=verbosity)
@ -30,4 +34,4 @@ class Command(BaseCommand):
# a strange error -- it causes this handle() method to be called
# multiple times.
shutdown_message = '\nServer stopped.\nNote that the test database, %r, has not been deleted. You can explore it on your own.' % db_name
call_command('runserver', shutdown_message=shutdown_message, use_reloader=False)
call_command('runserver', addrport=addrport, shutdown_message=shutdown_message, use_reloader=False)

View File

@ -130,7 +130,7 @@ def sql_delete(app, style):
else:
table_names = []
if connection.features.uses_case_insensitive_names:
table_name_converter = str.upper
table_name_converter = lambda x: x.upper()
else:
table_name_converter = lambda x: x
@ -302,7 +302,8 @@ def sql_model_create(model, style, known_models=set()):
if opts.has_auto_field:
# Add any extra SQL needed to support auto-incrementing primary keys.
autoinc_sql = connection.ops.autoinc_sql(opts.db_table)
auto_column = opts.auto_field.db_column or opts.auto_field.name
autoinc_sql = connection.ops.autoinc_sql(opts.db_table, auto_column)
if autoinc_sql:
for stmt in autoinc_sql:
final_output.append(stmt)
@ -385,7 +386,7 @@ def many_to_many_sql_for_model(model, style):
final_output.append('\n'.join(table_output))
# Add any extra SQL needed to support auto-incrementing PKs
autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table())
autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table(), 'id')
if autoinc_sql:
for stmt in autoinc_sql:
final_output.append(stmt)

View File

@ -1,5 +1,6 @@
import sys
from django.core.management.color import color_style
from django.utils.itercompat import is_iterable
class ModelErrorCollection:
def __init__(self, outfile=sys.stdout):
@ -49,7 +50,7 @@ def get_validation_errors(outfile, app=None):
except ImportError:
e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name)
if f.choices:
if not hasattr(f.choices, '__iter__'):
if isinstance(f.choices, basestring) or not is_iterable(f.choices):
e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name)
else:
for c in f.choices:

Some files were not shown because too many files have changed in this diff Show More