mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +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:
parent
b266911382
commit
019e3c61e4
23
AUTHORS
23
AUTHORS
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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')),
|
||||
|
Binary file not shown.
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.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/ga/LC_MESSAGES/django.mo
Normal file
BIN
django/conf/locale/ga/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
3443
django/conf/locale/ga/LC_MESSAGES/django.po
Normal file
3443
django/conf/locale/ga/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/ga/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/ga/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
116
django/conf/locale/ga/LC_MESSAGES/djangojs.po
Normal file
116
django/conf/locale/ga/LC_MESSAGES/djangojs.po
Normal 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 ""
|
||||
|
Binary file not shown.
@ -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."
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,20 +1,21 @@
|
||||
# translation of djangojs.po to
|
||||
# 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"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/km/LC_MESSAGES/django.mo
Normal file
BIN
django/conf/locale/km/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
2508
django/conf/locale/km/LC_MESSAGES/django.po
Normal file
2508
django/conf/locale/km/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/km/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/km/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
108
django/conf/locale/km/LC_MESSAGES/djangojs.po
Normal file
108
django/conf/locale/km/LC_MESSAGES/djangojs.po
Normal 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 "ថ្ងៃស្អែក"
|
||||
|
Binary file not shown.
@ -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."
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -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
|
||||
|
Binary file not shown.
@ -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"
|
||||
|
Binary file not shown.
@ -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"
|
||||
|
@ -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
|
||||
|
1
django/contrib/admin/media/css/null.css
Normal file
1
django/contrib/admin/media/css/null.css
Normal 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 */
|
@ -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; }
|
||||
|
@ -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");})()');
|
||||
|
@ -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 ?
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -40,6 +40,9 @@ var RUSSIAN_MAP = {
|
||||
'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
|
||||
'Я':'Ya'
|
||||
}
|
||||
var UKRAINIAN_MAP = {
|
||||
'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
|
||||
}
|
||||
var CZECH_MAP = {
|
||||
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
|
||||
'ž':'z'
|
||||
@ -51,7 +54,8 @@ ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
|
||||
ALL_DOWNCODE_MAPS[2]=GREEK_MAP
|
||||
ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
|
||||
ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
|
||||
ALL_DOWNCODE_MAPS[5]=CZECH_MAP
|
||||
ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
|
||||
ALL_DOWNCODE_MAPS[6]=CZECH_MAP
|
||||
|
||||
var Downcoder = new Object();
|
||||
Downcoder.Initialize = function()
|
||||
|
@ -10,7 +10,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for result in results %}
|
||||
<tr class="{% cycle row1,row2 %}">{% for item in result %}{{ item }}{% endfor %}</tr>
|
||||
<tr class="{% cycle 'row1' 'row2' %}">{% for item in result %}{{ item }}{% endfor %}</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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()
|
||||
[]
|
||||
"""
|
@ -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'):
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
model=opts.object_name.lower())
|
||||
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()
|
||||
|
@ -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
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for field in field_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for year in date_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for month in date_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for choice in field.choices %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for field in field_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
{% block content %}
|
||||
|
||||
{% for model in model_list %}
|
||||
<div class="modelgroup {% cycle even,odd %}">
|
||||
<div class="modelgroup {% cycle 'even' 'odd' %}">
|
||||
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
|
||||
<p>
|
||||
{% for object in model.sample_objects %}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in model.objects %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<table class="objectinfo">
|
||||
{% for field in object.fields %}
|
||||
<tr class="{% cycle odd,even %}">
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<th>{{ field.field.verbose_name|capfirst }}</th>
|
||||
<td>
|
||||
{% if field.urls %}
|
||||
@ -29,7 +29,7 @@
|
||||
{% if related_object.object_list %}
|
||||
<ul class="objectlist">
|
||||
{% for object in related_object.object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
|
@ -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
|
||||
|
0
django/contrib/localflavor/ar/__init__.py
Normal file
0
django/contrib/localflavor/ar/__init__.py
Normal file
36
django/contrib/localflavor/ar/ar_provinces.py
Normal file
36
django/contrib/localflavor/ar/ar_provinces.py
Normal 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'),
|
||||
)
|
105
django/contrib/localflavor/ar/forms.py
Normal file
105
django/contrib/localflavor/ar/forms.py
Normal 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)
|
||||
|
@ -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
|
||||
|
||||
|
0
django/contrib/localflavor/ca/__init__.py
Normal file
0
django/contrib/localflavor/ca/__init__.py
Normal file
57
django/contrib/localflavor/ca/ca_provinces.py
Normal file
57
django/contrib/localflavor/ca/ca_provinces.py
Normal 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',
|
||||
}
|
112
django/contrib/localflavor/ca/forms.py
Normal file
112
django/contrib/localflavor/ca/forms.py
Normal 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 )
|
0
django/contrib/localflavor/generic/__init__.py
Normal file
0
django/contrib/localflavor/generic/__init__.py
Normal file
38
django/contrib/localflavor/generic/forms.py
Normal file
38
django/contrib/localflavor/generic/forms.py
Normal 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)
|
0
django/contrib/localflavor/nl/__init__.py
Normal file
0
django/contrib/localflavor/nl/__init__.py
Normal file
92
django/contrib/localflavor/nl/forms.py
Normal file
92
django/contrib/localflavor/nl/forms.py
Normal 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
|
16
django/contrib/localflavor/nl/nl_provinces.py
Normal file
16
django/contrib/localflavor/nl/nl_provinces.py
Normal 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')),
|
||||
)
|
0
django/contrib/localflavor/pe/__init__.py
Normal file
0
django/contrib/localflavor/pe/__init__.py
Normal file
61
django/contrib/localflavor/pe/forms.py
Normal file
61
django/contrib/localflavor/pe/forms.py
Normal 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
|
||||
|
35
django/contrib/localflavor/pe/pe_department.py
Normal file
35
django/contrib/localflavor/pe/pe_department.py
Normal 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'),
|
||||
)
|
@ -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:
|
||||
|
@ -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.')
|
||||
|
@ -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)
|
||||
|
@ -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 *
|
||||
|
@ -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)
|
@ -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
|
||||
|
||||
|
@ -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=''))
|
||||
|
@ -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)
|
||||
|
@ -50,7 +50,11 @@ def make_msgid(idstring=None):
|
||||
"""
|
||||
timeval = time.time()
|
||||
utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval))
|
||||
pid = os.getpid()
|
||||
try:
|
||||
pid = os.getpid()
|
||||
except AttributeError:
|
||||
# Not getpid() in Jython, for example.
|
||||
pid = 1
|
||||
randint = random.randrange(100000)
|
||||
if idstring is None:
|
||||
idstring = ''
|
||||
|
@ -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)
|
||||
st = os.stat(filename)
|
||||
new_permissions = stat.S_IMODE(st.st_mode) | stat.S_IWUSR
|
||||
os.chmod(filename, new_permissions)
|
||||
|
||||
|
@ -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(),
|
||||
})
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user