mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
gis: Made necessary modifications for unicode, manage refactor, backend refactor and merged 5584-6000 via svnmerge from [repos:django/trunk trunk].
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6018 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a7297a255f
commit
2052b508eb
46
AUTHORS
46
AUTHORS
@ -44,6 +44,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
alang@bright-green.com
|
||||
Marty Alchin <gulopine@gamemusic.org>
|
||||
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
|
||||
AgarFu <heaven@croasanaso.sytes.net>
|
||||
Andreas
|
||||
andy@jadedplanet.net
|
||||
Fabrice Aneche <akh@nobugware.com>
|
||||
@ -56,15 +57,21 @@ answer newbie questions, and generally made Django that much better:
|
||||
Ned Batchelder <http://www.nedbatchelder.com/>
|
||||
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
||||
Esdras Beleza <linux@esdrasbeleza.com>
|
||||
Chris Bennett <chrisrbennett@yahoo.com>
|
||||
James Bennett
|
||||
Ben <afternoon@uk2.net>
|
||||
Paul Bissex <http://e-scribe.com/>
|
||||
Simon Blanchard
|
||||
Matt Boersma <ogghead@gmail.com>
|
||||
boobsd@gmail.com
|
||||
Andrew Brehaut <http://brehaut.net/blog>
|
||||
brut.alll@gmail.com
|
||||
Jonathan Buchanan <jonathan.buchanan@gmail.com>
|
||||
Trevor Caira <trevor@caira.com>
|
||||
Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
|
||||
Antonio Cavedoni <http://cavedoni.com/>
|
||||
C8E
|
||||
cedric@terramater.net
|
||||
Chris Chamberlin <dja@cdc.msbx.net>
|
||||
Amit Chakradeo <http://amit.chakradeo.net/>
|
||||
ChaosKCW
|
||||
@ -72,6 +79,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Bryan Chow <bryan at verdjn dot com>
|
||||
Michal Chruszcz <troll@pld-linux.org>
|
||||
Ian Clelland <clelland@gmail.com>
|
||||
colin@owlfish.com
|
||||
crankycoder@gmail.com
|
||||
Pete Crosier <pete.crosier@gmail.com>
|
||||
Matt Croydon <http://www.postneo.com/>
|
||||
@ -91,10 +99,14 @@ answer newbie questions, and generally made Django that much better:
|
||||
Maximillian Dornseif <md@hudora.de>
|
||||
Jeremy Dunck <http://dunck.us/>
|
||||
Andrew Durdin <adurdin@gmail.com>
|
||||
dusk@woofle.net
|
||||
Andy Dustman <farcepest@gmail.com>
|
||||
Clint Ecker
|
||||
Nick Efford <nick@efford.org>
|
||||
eibaan@gmail.com
|
||||
enlight
|
||||
Enrico <rico.bl@gmail.com>
|
||||
A. Murat Eren <meren@pardus.org.tr>
|
||||
Ludvig Ericson <ludvig.ericson@gmail.com>
|
||||
Dirk Eschler <dirk.eschler@gmx.net>
|
||||
Marc Fargas <telenieko@telenieko.com>
|
||||
@ -106,19 +118,26 @@ answer newbie questions, and generally made Django that much better:
|
||||
Eric Floehr <eric@intellovations.com>
|
||||
Jorge Gajon <gajon@gajon.org>
|
||||
gandalf@owca.info
|
||||
Marc Garcia <marc.garcia@accopensys.com>
|
||||
Baishampayan Ghose
|
||||
glin@seznam.cz
|
||||
martin.glueck@gmail.com
|
||||
GomoX <gomo@datafull.com>
|
||||
Mario Gonzalez <gonzalemario@gmail.com>
|
||||
pradeep.gowda@gmail.com
|
||||
Simon Greenhill <dev@simon.net.nz>
|
||||
Owen Griffiths
|
||||
Espen Grindhaug <http://grindhaug.org/>
|
||||
Thomas Güttler <hv@tbz-pariv.de>
|
||||
dAniel hAhler
|
||||
Brian Harring <ferringb@gmail.com>
|
||||
Brant Harris
|
||||
Hawkeye
|
||||
Joe Heck <http://www.rhonabwy.com/wp/>
|
||||
Joel Heenan <joelh-django@planetjoel.com>
|
||||
hipertracker@gmail.com
|
||||
Deryck Hodge <http://www.devurandom.org/>
|
||||
Brett Hoerner <bretthoerner@bretthoerner.com>
|
||||
Ian Holsman <http://feh.holsman.net/>
|
||||
Kieran Holland <http://www.kieranholland.com>
|
||||
Sung-Jin Hong <serialx.net@gmail.com>
|
||||
@ -128,6 +147,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Hyun Mi Ae
|
||||
Tom Insam
|
||||
Baurzhan Ismagulov <ibr@radix50.net>
|
||||
james_027@yahoo.com
|
||||
jcrasta@gmail.com
|
||||
Zak Johnson <zakj@nox.cx>
|
||||
Michael Josephson <http://www.sdjournal.com/>
|
||||
@ -135,18 +155,23 @@ answer newbie questions, and generally made Django that much better:
|
||||
junzhang.jn@gmail.com
|
||||
Antti Kaihola <http://akaihola.blogspot.com/>
|
||||
Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
|
||||
ian.g.kelly@gmail.com
|
||||
Ian G. Kelly <ian.g.kelly@gmail.com>
|
||||
Ben Khoo <khoobks@westnet.com.au>
|
||||
Garth Kidd <http://www.deadlybloodyserious.com/>
|
||||
kilian <kilian.cavalotti@lip6.fr>
|
||||
Sune Kirkeby <http://ibofobi.dk/>
|
||||
Bastian Kleineidam <calvin@debian.org>
|
||||
Cameron Knight (ckknight)
|
||||
Nena Kojadin <nena@kiberpipa.org>
|
||||
Igor Kolar <ike@email.si>
|
||||
Gasper Koren
|
||||
Martin Kosír <martin@martinkosir.net>
|
||||
Meir Kriheli <http://mksoft.co.il/>
|
||||
Bruce Kroeze <http://coderseye.com/>
|
||||
krzysiek.pawlik@silvermedia.pl
|
||||
Joseph Kocherhans
|
||||
konrad@gwu.edu
|
||||
kurtiss@meetro.com
|
||||
lakin.wecker@gmail.com
|
||||
Nick Lane <nick.lane.au@gmail.com>
|
||||
Stuart Langridge <http://www.kryogenix.org/>
|
||||
@ -158,13 +183,14 @@ answer newbie questions, and generally made Django that much better:
|
||||
lerouxb@gmail.com
|
||||
Waylan Limberg <waylan@gmail.com>
|
||||
limodou
|
||||
Philip Lindborg <philip.lindborg@gmail.com>
|
||||
Matt McClanahan <http://mmcc.cx/>
|
||||
Martin Maney <http://www.chipy.org/Martin_Maney>
|
||||
masonsimon+django@gmail.com
|
||||
Manuzhai
|
||||
Petar Marić <http://www.petarmaric.com/>
|
||||
Nuno Mariz <nmariz@gmail.com>
|
||||
marijn@metronomo.cl
|
||||
Marijn Vriens <marijn@metronomo.cl>
|
||||
mark@junklight.com
|
||||
Yasushi Masuda <whosaysni@gmail.com>
|
||||
mattycakes@gmail.com
|
||||
@ -172,9 +198,13 @@ answer newbie questions, and generally made Django that much better:
|
||||
mccutchen@gmail.com
|
||||
michael.mcewan@gmail.com
|
||||
mikko@sorl.net
|
||||
Slawek Mikula <slawek dot mikula at gmail dot com>
|
||||
mitakummaa@gmail.com
|
||||
mmarshall
|
||||
Andreas Mock <andreas.mock@web.de>
|
||||
Reza Mohammadi <reza@zeerak.ir>
|
||||
Aljosa Mohorovic <aljosa.mohorovic@gmail.com>
|
||||
Ramiro Morales <rm0@gmx.net>
|
||||
Eric Moritz <http://eric.themoritzfamily.com/>
|
||||
mrmachine <real.human@mrmachine.net>
|
||||
Robin Munn <http://www.geekforgod.com/>
|
||||
@ -184,6 +214,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Fraser Nevett <mail@nevett.org>
|
||||
Sam Newman <http://www.magpiebrain.com/>
|
||||
Neal Norwitz <nnorwitz@google.com>
|
||||
Todd O'Bryan <toddobryan@mac.com>
|
||||
oggie rob <oz.robharvey@gmail.com>
|
||||
Jay Parlar <parlar@gmail.com>
|
||||
pavithran s <pavithran.s@gmail.com>
|
||||
@ -198,22 +229,26 @@ answer newbie questions, and generally made Django that much better:
|
||||
plisk
|
||||
Daniel Poelzleithner <http://poelzi.org/>
|
||||
polpak@yahoo.com
|
||||
Jyrki Pulliainen <jyrki.pulliainen@gmail.com>
|
||||
Johann Queuniet <johann.queuniet@adh.naellia.eu>
|
||||
J. Rademaker
|
||||
Michael Radziej <mir@noris.de>
|
||||
Ramiro Morales <rm0@gmx.net>
|
||||
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
||||
Brian Ray <http://brianray.chipy.org/>
|
||||
remco@diji.biz
|
||||
rhettg@gmail.com
|
||||
Henrique Romano <onaiort@gmail.com>
|
||||
Armin Ronacher
|
||||
Brian Rosner <brosner@gmail.com>
|
||||
Oliver Rutherfurd <http://rutherfurd.net/>
|
||||
Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
|
||||
Vinay Sajip <vinay_sajip@yahoo.co.uk>
|
||||
David Schein
|
||||
scott@staplefish.com
|
||||
serbaut@gmail.com
|
||||
John Shaffer <jshaffer2112@gmail.com>
|
||||
Pete Shinners <pete@shinners.org>
|
||||
Jozko Skrablin <jozko.skrablin@gmail.com>
|
||||
SmileyChris <smileychris@gmail.com>
|
||||
smurf@smurf.noris.de
|
||||
sopel
|
||||
@ -222,6 +257,8 @@ answer newbie questions, and generally made Django that much better:
|
||||
Vasiliy Stavenko <stavenko@gmail.com>
|
||||
Thomas Steinacher <http://www.eggdrop.ch/>
|
||||
nowell strite
|
||||
Sundance
|
||||
SuperJared
|
||||
Radek Švarz <http://www.svarz.cz/translate/>
|
||||
Swaroop C H <http://www.swaroopch.info>
|
||||
Aaron Swartz <http://www.aaronsw.com/>
|
||||
@ -231,10 +268,12 @@ answer newbie questions, and generally made Django that much better:
|
||||
thebjorn <bp@datakortet.no>
|
||||
Zach Thompson <zthompson47@gmail.com>
|
||||
tibimicu@gmax.net
|
||||
tobias@neuyork.de
|
||||
Tom Tobin
|
||||
Joe Topjian <http://joe.terrarum.net/geek/code/python/django/>
|
||||
torne-django@wolfpuppy.org.uk
|
||||
Karen Tracey <graybark@bellsouth.net>
|
||||
tstromberg@google.com
|
||||
Makoto Tsuyuki <mtsuyuki@gmail.com>
|
||||
tt@gurgle.no
|
||||
Amit Upadhyay
|
||||
@ -250,6 +289,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
charly.wilhelm@gmail.com
|
||||
Rachel Willmer <http://www.willmer.com/kb/>
|
||||
Gary Wilson <gary.wilson@gmail.com>
|
||||
Jakub Wiśniowski <restless.being@gmail.com>
|
||||
wojtek
|
||||
ye7cakf02@sneakemail.com
|
||||
ymasuda@ethercube.com
|
||||
|
@ -4,5 +4,6 @@ def get_version():
|
||||
"Returns the version as a human-format string."
|
||||
v = '.'.join([str(i) for i in VERSION[:-1]])
|
||||
if VERSION[-1]:
|
||||
v += '-' + VERSION[-1]
|
||||
from django.utils.version import get_svn_revision
|
||||
v = '%s-%s-%s' % (v, VERSION[-1], get_svn_revision())
|
||||
return v
|
||||
|
@ -9,6 +9,7 @@ import re
|
||||
import os
|
||||
import sys
|
||||
import getopt
|
||||
from itertools import dropwhile
|
||||
|
||||
pythonize_re = re.compile(r'\n\s*//')
|
||||
|
||||
@ -83,7 +84,7 @@ def make_messages():
|
||||
thefile = '%s.py' % file
|
||||
cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
|
||||
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
|
||||
(stdin, stdout, stderr) = os.popen3(cmd, 'b')
|
||||
(stdin, stdout, stderr) = os.popen3(cmd, 't')
|
||||
msgs = stdout.read()
|
||||
errors = stderr.read()
|
||||
if errors:
|
||||
@ -100,12 +101,13 @@ def make_messages():
|
||||
thefile = file
|
||||
if file.endswith('.html'):
|
||||
src = open(os.path.join(dirpath, file), "rb").read()
|
||||
open(os.path.join(dirpath, '%s.py' % file), "wb").write(templatize(src))
|
||||
thefile = '%s.py' % file
|
||||
if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
|
||||
cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
|
||||
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
|
||||
(stdin, stdout, stderr) = os.popen3(cmd, 'b')
|
||||
open(os.path.join(dirpath, thefile), "wb").write(templatize(src))
|
||||
if verbose:
|
||||
sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
|
||||
cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
|
||||
domain, os.path.join(dirpath, thefile))
|
||||
(stdin, stdout, stderr) = os.popen3(cmd, 't')
|
||||
msgs = stdout.read()
|
||||
errors = stderr.read()
|
||||
if errors:
|
||||
@ -116,13 +118,18 @@ def make_messages():
|
||||
old = '#: '+os.path.join(dirpath, thefile)[2:]
|
||||
new = '#: '+os.path.join(dirpath, file)[2:]
|
||||
msgs = msgs.replace(old, new)
|
||||
if os.path.exists(potfile):
|
||||
# Strip the header
|
||||
msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
|
||||
else:
|
||||
msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
|
||||
if msgs:
|
||||
open(potfile, 'ab').write(msgs)
|
||||
if thefile != file:
|
||||
os.unlink(os.path.join(dirpath, thefile))
|
||||
|
||||
if os.path.exists(potfile):
|
||||
(stdin, stdout, stderr) = os.popen3('msguniq "%s"' % potfile, 'b')
|
||||
(stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%s"' % potfile, 'b')
|
||||
msgs = stdout.read()
|
||||
errors = stderr.read()
|
||||
if errors:
|
||||
|
@ -37,6 +37,8 @@ class LazySettings(object):
|
||||
# __setattr__(), which would be an infinite loop.
|
||||
self.__dict__['_target'] = value
|
||||
else:
|
||||
if self._target is None:
|
||||
self._import_settings()
|
||||
setattr(self._target, name, value)
|
||||
|
||||
def _import_settings(self):
|
||||
|
@ -25,12 +25,12 @@ ADMINS = ()
|
||||
INTERNAL_IPS = ()
|
||||
|
||||
# Local time zone for this installation. All choices can be found here:
|
||||
# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name (although not all
|
||||
# systems may support all possibilities).
|
||||
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://blogs.law.harvard.edu/tech/stories/storyReader$15
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
# Languages we provide translations for, out of the box. The language name
|
||||
@ -54,6 +54,7 @@ LANGUAGES = (
|
||||
('gl', gettext_noop('Galician')),
|
||||
('hu', gettext_noop('Hungarian')),
|
||||
('he', gettext_noop('Hebrew')),
|
||||
('hr', gettext_noop('Croatian')),
|
||||
('is', gettext_noop('Icelandic')),
|
||||
('it', gettext_noop('Italian')),
|
||||
('ja', gettext_noop('Japanese')),
|
||||
@ -81,7 +82,7 @@ LANGUAGES = (
|
||||
)
|
||||
|
||||
# Languages using BiDi (right-to-left) layout
|
||||
LANGUAGES_BIDI = ("he", "ar")
|
||||
LANGUAGES_BIDI = ("he", "ar", "fa")
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
@ -97,6 +98,9 @@ MANAGERS = ADMINS
|
||||
DEFAULT_CONTENT_TYPE = 'text/html'
|
||||
DEFAULT_CHARSET = 'utf-8'
|
||||
|
||||
# Encoding of files read from disk (template and initial SQL files).
|
||||
FILE_CHARSET = 'utf-8'
|
||||
|
||||
# E-mail address that error messages come from.
|
||||
SERVER_EMAIL = 'root@localhost'
|
||||
|
||||
@ -280,6 +284,7 @@ SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether sessions expire when a user
|
||||
# possible values.
|
||||
CACHE_BACKEND = 'simple://'
|
||||
CACHE_MIDDLEWARE_KEY_PREFIX = ''
|
||||
CACHE_MIDDLEWARE_SECONDS = 600
|
||||
|
||||
####################
|
||||
# COMMENTS #
|
||||
|
Binary file not shown.
@ -237,7 +237,7 @@ msgstr "Coreà"
|
||||
|
||||
#: conf/global_settings.py:61
|
||||
msgid "Kannada"
|
||||
msgstr ""
|
||||
msgstr "Canès"
|
||||
|
||||
#: conf/global_settings.py:62
|
||||
msgid "Latvian"
|
||||
@ -1230,7 +1230,7 @@ msgstr "Pot editar-lo de nou abaix."
|
||||
|
||||
#: contrib/admin/views/auth.py:30
|
||||
msgid "Add user"
|
||||
msgstr "Agregar usuari"
|
||||
msgstr "Afegir usuari"
|
||||
|
||||
#: contrib/admin/views/auth.py:57
|
||||
msgid "Password changed successfully."
|
||||
@ -1248,12 +1248,12 @@ msgstr "Lloc administratiu"
|
||||
#: contrib/admin/views/main.py:276 contrib/admin/views/main.py:361
|
||||
#, python-format
|
||||
msgid "You may add another %s below."
|
||||
msgstr "Pot agregar un altre %s abaix."
|
||||
msgstr "Pot afegir un altre %s a baix."
|
||||
|
||||
#: contrib/admin/views/main.py:294
|
||||
#, python-format
|
||||
msgid "Add %s"
|
||||
msgstr "Agregar %s"
|
||||
msgstr "Afegir %s"
|
||||
|
||||
#: contrib/admin/views/main.py:340
|
||||
#, python-format
|
||||
|
Binary file not shown.
@ -3,10 +3,10 @@
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django 1.0\n"
|
||||
""
|
||||
msgstr "Project-Id-Version: Django 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-04-09 22:42+0200\n"
|
||||
"POT-Creation-Date: 2007-07-28 12:33+0200\n"
|
||||
"PO-Revision-Date: 2007-02-05 03:19+0100\n"
|
||||
"Last-Translator: Jannis Leidel <jl@websushi.org>\n"
|
||||
"Language-Team: \n"
|
||||
@ -19,591 +19,590 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: conf/global_settings.py:39
|
||||
#:conf/global_settings.py:38
|
||||
msgid "Arabic"
|
||||
msgstr "Arabisch"
|
||||
|
||||
#: conf/global_settings.py:40
|
||||
#:conf/global_settings.py:39
|
||||
msgid "Bengali"
|
||||
msgstr "Bengali"
|
||||
|
||||
#: conf/global_settings.py:41
|
||||
#:conf/global_settings.py:40
|
||||
msgid "Bulgarian"
|
||||
msgstr "Bulgarisch"
|
||||
|
||||
#:conf/global_settings.py:41
|
||||
msgid "Catalan"
|
||||
msgstr "Katalanisch"
|
||||
|
||||
#: conf/global_settings.py:42
|
||||
#:conf/global_settings.py:42
|
||||
msgid "Czech"
|
||||
msgstr "Tschechisch"
|
||||
|
||||
#: conf/global_settings.py:43
|
||||
#:conf/global_settings.py:43
|
||||
msgid "Welsh"
|
||||
msgstr "Walisisch"
|
||||
|
||||
#: conf/global_settings.py:44
|
||||
#:conf/global_settings.py:44
|
||||
msgid "Danish"
|
||||
msgstr "Dänisch"
|
||||
|
||||
#: conf/global_settings.py:45
|
||||
#:conf/global_settings.py:45
|
||||
msgid "German"
|
||||
msgstr "Deutsch"
|
||||
|
||||
#: conf/global_settings.py:46
|
||||
#:conf/global_settings.py:46
|
||||
msgid "Greek"
|
||||
msgstr "Griechisch"
|
||||
|
||||
#: conf/global_settings.py:47
|
||||
#:conf/global_settings.py:47
|
||||
msgid "English"
|
||||
msgstr "Englisch"
|
||||
|
||||
#: conf/global_settings.py:48
|
||||
#:conf/global_settings.py:48
|
||||
msgid "Spanish"
|
||||
msgstr "Spanisch"
|
||||
|
||||
#: conf/global_settings.py:49
|
||||
#:conf/global_settings.py:49
|
||||
msgid "Argentinean Spanish"
|
||||
msgstr "Argentinisches Spanisch"
|
||||
|
||||
#: conf/global_settings.py:50
|
||||
#:conf/global_settings.py:50
|
||||
msgid "Persian"
|
||||
msgstr "Persisch"
|
||||
|
||||
#:conf/global_settings.py:51
|
||||
msgid "Finnish"
|
||||
msgstr "Finnisch"
|
||||
|
||||
#: conf/global_settings.py:51
|
||||
#:conf/global_settings.py:52
|
||||
msgid "French"
|
||||
msgstr "Französisch"
|
||||
|
||||
#: conf/global_settings.py:52
|
||||
#:conf/global_settings.py:53
|
||||
msgid "Galician"
|
||||
msgstr "Galicisch"
|
||||
|
||||
#: conf/global_settings.py:53
|
||||
#:conf/global_settings.py:54
|
||||
msgid "Hungarian"
|
||||
msgstr "Ungarisch"
|
||||
|
||||
#: conf/global_settings.py:54
|
||||
#:conf/global_settings.py:55
|
||||
msgid "Hebrew"
|
||||
msgstr "Hebräisch"
|
||||
|
||||
#: conf/global_settings.py:55
|
||||
#:conf/global_settings.py:56
|
||||
msgid "Icelandic"
|
||||
msgstr "Isländisch"
|
||||
|
||||
#: conf/global_settings.py:56
|
||||
#:conf/global_settings.py:57
|
||||
msgid "Italian"
|
||||
msgstr "Italienisch"
|
||||
|
||||
#: conf/global_settings.py:57
|
||||
#:conf/global_settings.py:58
|
||||
msgid "Japanese"
|
||||
msgstr "Japanisch"
|
||||
|
||||
#: conf/global_settings.py:58
|
||||
#:conf/global_settings.py:59
|
||||
msgid "Korean"
|
||||
msgstr "Koreanisch"
|
||||
|
||||
#: conf/global_settings.py:59
|
||||
#:conf/global_settings.py:60
|
||||
msgid "Kannada"
|
||||
msgstr "Kannada"
|
||||
|
||||
#: conf/global_settings.py:60
|
||||
#:conf/global_settings.py:61
|
||||
msgid "Latvian"
|
||||
msgstr "Lettisch"
|
||||
|
||||
#: conf/global_settings.py:61
|
||||
#:conf/global_settings.py:62
|
||||
msgid "Macedonian"
|
||||
msgstr "Mazedonisch"
|
||||
|
||||
#: conf/global_settings.py:62
|
||||
#:conf/global_settings.py:63
|
||||
msgid "Dutch"
|
||||
msgstr "Holländisch"
|
||||
|
||||
#: conf/global_settings.py:63
|
||||
#:conf/global_settings.py:64
|
||||
msgid "Norwegian"
|
||||
msgstr "Norwegisch"
|
||||
|
||||
#: conf/global_settings.py:64
|
||||
#:conf/global_settings.py:65
|
||||
msgid "Polish"
|
||||
msgstr "Polnisch"
|
||||
|
||||
#: conf/global_settings.py:65
|
||||
#:conf/global_settings.py:66
|
||||
msgid "Portugese"
|
||||
msgstr "Portugiesisch"
|
||||
|
||||
#: conf/global_settings.py:66
|
||||
#:conf/global_settings.py:67
|
||||
msgid "Brazilian"
|
||||
msgstr "Brasilianisches Portugiesisch"
|
||||
|
||||
#: conf/global_settings.py:67
|
||||
#:conf/global_settings.py:68
|
||||
msgid "Romanian"
|
||||
msgstr "Rumänisch"
|
||||
|
||||
#: conf/global_settings.py:68
|
||||
#:conf/global_settings.py:69
|
||||
msgid "Russian"
|
||||
msgstr "Russisch"
|
||||
|
||||
#: conf/global_settings.py:69
|
||||
#:conf/global_settings.py:70
|
||||
msgid "Slovak"
|
||||
msgstr "Slowakisch"
|
||||
|
||||
#: conf/global_settings.py:70
|
||||
#:conf/global_settings.py:71
|
||||
msgid "Slovenian"
|
||||
msgstr "Slowenisch"
|
||||
|
||||
#: conf/global_settings.py:71
|
||||
#:conf/global_settings.py:72
|
||||
msgid "Serbian"
|
||||
msgstr "Serbisch"
|
||||
|
||||
#: conf/global_settings.py:72
|
||||
#:conf/global_settings.py:73
|
||||
msgid "Swedish"
|
||||
msgstr "Schwedisch"
|
||||
|
||||
#: conf/global_settings.py:73
|
||||
#:conf/global_settings.py:74
|
||||
msgid "Tamil"
|
||||
msgstr "Tamilisch"
|
||||
|
||||
#: conf/global_settings.py:74
|
||||
#:conf/global_settings.py:75
|
||||
msgid "Telugu"
|
||||
msgstr "Telugisch"
|
||||
|
||||
#: conf/global_settings.py:75
|
||||
#:conf/global_settings.py:76
|
||||
msgid "Turkish"
|
||||
msgstr "Türkisch"
|
||||
|
||||
#: conf/global_settings.py:76
|
||||
#:conf/global_settings.py:77
|
||||
msgid "Ukrainian"
|
||||
msgstr "Ukrainisch"
|
||||
|
||||
#: conf/global_settings.py:77
|
||||
#:conf/global_settings.py:78
|
||||
msgid "Simplified Chinese"
|
||||
msgstr "Vereinfachtes Chinesisch"
|
||||
|
||||
#: conf/global_settings.py:78
|
||||
#:conf/global_settings.py:79
|
||||
msgid "Traditional Chinese"
|
||||
msgstr "Traditionelles Chinesisch"
|
||||
|
||||
#: contrib/admin/filterspecs.py:40
|
||||
#, python-format
|
||||
#:contrib/admin/filterspecs.py:42
|
||||
#,python-format
|
||||
msgid ""
|
||||
"<h3>By %s:</h3>\n"
|
||||
"<ul>\n"
|
||||
msgstr ""
|
||||
"<h3>Nach %s:</h3>\n"
|
||||
msgstr "<h3>Nach %s:</h3>\n"
|
||||
"<ul>\n"
|
||||
|
||||
#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88
|
||||
#: contrib/admin/filterspecs.py:143 contrib/admin/filterspecs.py:169
|
||||
#:contrib/admin/filterspecs.py:72 contrib/admin/filterspecs.py:90
|
||||
#:contrib/admin/filterspecs.py:145 contrib/admin/filterspecs.py:171
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: contrib/admin/filterspecs.py:109
|
||||
#:contrib/admin/filterspecs.py:111
|
||||
msgid "Any date"
|
||||
msgstr "Alle Daten"
|
||||
|
||||
#: contrib/admin/filterspecs.py:110
|
||||
#:contrib/admin/filterspecs.py:112
|
||||
msgid "Today"
|
||||
msgstr "Heute"
|
||||
|
||||
#: contrib/admin/filterspecs.py:113
|
||||
#:contrib/admin/filterspecs.py:115
|
||||
msgid "Past 7 days"
|
||||
msgstr "Letzte 7 Tage"
|
||||
|
||||
#: contrib/admin/filterspecs.py:115
|
||||
#:contrib/admin/filterspecs.py:117
|
||||
msgid "This month"
|
||||
msgstr "Diesen Monat"
|
||||
|
||||
#: contrib/admin/filterspecs.py:117
|
||||
#:contrib/admin/filterspecs.py:119
|
||||
msgid "This year"
|
||||
msgstr "Dieses Jahr"
|
||||
|
||||
#: contrib/admin/filterspecs.py:143 newforms/widgets.py:180
|
||||
#: oldforms/__init__.py:577
|
||||
#:contrib/admin/filterspecs.py:145 newforms/widgets.py:181
|
||||
#:oldforms/__init__.py:587
|
||||
msgid "Yes"
|
||||
msgstr "Ja"
|
||||
|
||||
#: contrib/admin/filterspecs.py:143 newforms/widgets.py:180
|
||||
#: oldforms/__init__.py:577
|
||||
#:contrib/admin/filterspecs.py:145 newforms/widgets.py:181
|
||||
#:oldforms/__init__.py:587
|
||||
msgid "No"
|
||||
msgstr "Nein"
|
||||
|
||||
#: contrib/admin/filterspecs.py:150 newforms/widgets.py:180
|
||||
#: oldforms/__init__.py:577
|
||||
#:contrib/admin/filterspecs.py:152 newforms/widgets.py:181
|
||||
#:oldforms/__init__.py:587
|
||||
msgid "Unknown"
|
||||
msgstr "Unbekannt"
|
||||
|
||||
#: contrib/admin/models.py:16
|
||||
#:contrib/admin/models.py:17
|
||||
msgid "action time"
|
||||
msgstr "Zeitpunkt der Aktion"
|
||||
|
||||
#: contrib/admin/models.py:19
|
||||
#:contrib/admin/models.py:20
|
||||
msgid "object id"
|
||||
msgstr "Objekt-ID"
|
||||
|
||||
#: contrib/admin/models.py:20
|
||||
#:contrib/admin/models.py:21
|
||||
msgid "object repr"
|
||||
msgstr "Objekt Darst."
|
||||
|
||||
#: contrib/admin/models.py:21
|
||||
#:contrib/admin/models.py:22
|
||||
msgid "action flag"
|
||||
msgstr "Aktionskennzeichen"
|
||||
|
||||
#: contrib/admin/models.py:22
|
||||
#:contrib/admin/models.py:23
|
||||
msgid "change message"
|
||||
msgstr "Änderungsmeldung"
|
||||
|
||||
#: contrib/admin/models.py:25
|
||||
#:contrib/admin/models.py:26
|
||||
msgid "log entry"
|
||||
msgstr "Logeintrag"
|
||||
|
||||
#: contrib/admin/models.py:26
|
||||
#:contrib/admin/models.py:27
|
||||
msgid "log entries"
|
||||
msgstr "Logeinträge"
|
||||
|
||||
#: contrib/admin/templates/admin/404.html:4
|
||||
#: contrib/admin/templates/admin/404.html:8
|
||||
#:contrib/admin/templates/admin/404.html:4
|
||||
#:contrib/admin/templates/admin/404.html:8
|
||||
msgid "Page not found"
|
||||
msgstr "Seite nicht gefunden"
|
||||
|
||||
#: contrib/admin/templates/admin/404.html:10
|
||||
#:contrib/admin/templates/admin/404.html:10
|
||||
msgid "We're sorry, but the requested page could not be found."
|
||||
msgstr ""
|
||||
"Es tut uns leid, aber die angeforderte Seite konnte nicht gefunden werden."
|
||||
msgstr "Es tut uns leid, aber die angeforderte Seite konnte nicht gefunden werden."
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:4
|
||||
#: contrib/admin/templates/admin/base.html:30
|
||||
#: contrib/admin/templates/admin/change_form.html:13
|
||||
#: contrib/admin/templates/admin/change_list.html:6
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:6
|
||||
#: contrib/admin/templates/admin/invalid_setup.html:4
|
||||
#: contrib/admin/templates/admin/object_history.html:5
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:12
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
|
||||
#: contrib/admin/templates/registration/logged_out.html:4
|
||||
#: contrib/admin/templates/registration/password_change_done.html:4
|
||||
#: contrib/admin/templates/registration/password_change_form.html:4
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:4
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:4
|
||||
#:contrib/admin/templates/admin/500.html:4
|
||||
#:contrib/admin/templates/admin/base.html:30
|
||||
#:contrib/admin/templates/admin/change_form.html:13
|
||||
#:contrib/admin/templates/admin/change_list.html:6
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:6
|
||||
#:contrib/admin/templates/admin/invalid_setup.html:4
|
||||
#:contrib/admin/templates/admin/object_history.html:5
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:12
|
||||
#:contrib/admin/templates/admin_doc/bookmarklets.html:3
|
||||
#:contrib/admin/templates/registration/logged_out.html:4
|
||||
#:contrib/admin/templates/registration/password_change_done.html:4
|
||||
#:contrib/admin/templates/registration/password_change_form.html:4
|
||||
#:contrib/admin/templates/registration/password_reset_done.html:4
|
||||
#:contrib/admin/templates/registration/password_reset_form.html:4
|
||||
msgid "Home"
|
||||
msgstr "Start"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:4
|
||||
#:contrib/admin/templates/admin/500.html:4
|
||||
msgid "Server error"
|
||||
msgstr "Serverfehler"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:6
|
||||
#:contrib/admin/templates/admin/500.html:6
|
||||
msgid "Server error (500)"
|
||||
msgstr "Serverfehler (500)"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:9
|
||||
#:contrib/admin/templates/admin/500.html:9
|
||||
msgid "Server Error <em>(500)</em>"
|
||||
msgstr "Serverfehler <em>(500)</em>"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:10
|
||||
#:contrib/admin/templates/admin/500.html:10
|
||||
msgid ""
|
||||
"There's been an error. It's been reported to the site administrators via e-"
|
||||
"mail and should be fixed shortly. Thanks for your patience."
|
||||
msgstr ""
|
||||
"Ein Fehler ist aufgetreten. Dieser Fehler wurde an die Serververwalter per E-"
|
||||
msgstr "Ein Fehler ist aufgetreten. Dieser Fehler wurde an die Serververwalter per E-"
|
||||
"Mail weitergegeben und sollte bald behoben sein. Vielen Dank für Ihr "
|
||||
"Verständnis."
|
||||
|
||||
#: contrib/admin/templates/admin/base.html:25
|
||||
#:contrib/admin/templates/admin/base.html:25
|
||||
msgid "Welcome,"
|
||||
msgstr "Willkommen,"
|
||||
|
||||
#: contrib/admin/templates/admin/base.html:25
|
||||
#: contrib/admin/templates/admin/change_form.html:10
|
||||
#: contrib/admin/templates/admin/change_list.html:5
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:3
|
||||
#: contrib/admin/templates/admin/object_history.html:3
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:9
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
|
||||
#: contrib/admin/templates/registration/password_change_done.html:3
|
||||
#: contrib/admin/templates/registration/password_change_form.html:3
|
||||
#:contrib/admin/templates/admin/base.html:25
|
||||
#:contrib/admin/templates/admin/change_form.html:10
|
||||
#:contrib/admin/templates/admin/change_list.html:5
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:3
|
||||
#:contrib/admin/templates/admin/object_history.html:3
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:9
|
||||
#:contrib/admin/templates/admin_doc/bookmarklets.html:3
|
||||
#:contrib/admin/templates/registration/password_change_done.html:3
|
||||
#:contrib/admin/templates/registration/password_change_form.html:3
|
||||
msgid "Documentation"
|
||||
msgstr "Dokumentation"
|
||||
|
||||
#: contrib/admin/templates/admin/base.html:25
|
||||
#: contrib/admin/templates/admin/change_form.html:10
|
||||
#: contrib/admin/templates/admin/change_list.html:5
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:3
|
||||
#: contrib/admin/templates/admin/object_history.html:3
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:9
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:15
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:46
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:4
|
||||
#: contrib/admin/templates/admin_doc/index.html:4
|
||||
#: contrib/admin/templates/admin_doc/missing_docutils.html:4
|
||||
#: contrib/admin/templates/admin_doc/model_detail.html:3
|
||||
#: contrib/admin/templates/admin_doc/model_index.html:5
|
||||
#: contrib/admin/templates/admin_doc/template_detail.html:4
|
||||
#: contrib/admin/templates/admin_doc/template_filter_index.html:5
|
||||
#: contrib/admin/templates/admin_doc/template_tag_index.html:5
|
||||
#: contrib/admin/templates/admin_doc/view_detail.html:4
|
||||
#: contrib/admin/templates/admin_doc/view_index.html:5
|
||||
#: contrib/admin/templates/registration/password_change_done.html:3
|
||||
#: contrib/admin/templates/registration/password_change_form.html:3
|
||||
#:contrib/admin/templates/admin/base.html:25
|
||||
#:contrib/admin/templates/admin/change_form.html:10
|
||||
#:contrib/admin/templates/admin/change_list.html:5
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:3
|
||||
#:contrib/admin/templates/admin/object_history.html:3
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:9
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:15
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:46
|
||||
#:contrib/admin/templates/admin_doc/bookmarklets.html:4
|
||||
#:contrib/admin/templates/admin_doc/index.html:4
|
||||
#:contrib/admin/templates/admin_doc/missing_docutils.html:4
|
||||
#:contrib/admin/templates/admin_doc/model_detail.html:3
|
||||
#:contrib/admin/templates/admin_doc/model_index.html:5
|
||||
#:contrib/admin/templates/admin_doc/template_detail.html:4
|
||||
#:contrib/admin/templates/admin_doc/template_filter_index.html:5
|
||||
#:contrib/admin/templates/admin_doc/template_tag_index.html:5
|
||||
#:contrib/admin/templates/admin_doc/view_detail.html:4
|
||||
#:contrib/admin/templates/admin_doc/view_index.html:5
|
||||
#:contrib/admin/templates/registration/password_change_done.html:3
|
||||
#:contrib/admin/templates/registration/password_change_form.html:3
|
||||
msgid "Change password"
|
||||
msgstr "Passwort ändern"
|
||||
|
||||
#: contrib/admin/templates/admin/base.html:25
|
||||
#: contrib/admin/templates/admin/change_form.html:10
|
||||
#: contrib/admin/templates/admin/change_list.html:5
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:3
|
||||
#: contrib/admin/templates/admin/object_history.html:3
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:9
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:4
|
||||
#: contrib/admin/templates/admin_doc/index.html:4
|
||||
#: contrib/admin/templates/admin_doc/missing_docutils.html:4
|
||||
#: contrib/admin/templates/admin_doc/model_detail.html:3
|
||||
#: contrib/admin/templates/admin_doc/model_index.html:5
|
||||
#: contrib/admin/templates/admin_doc/template_detail.html:4
|
||||
#: contrib/admin/templates/admin_doc/template_filter_index.html:5
|
||||
#: contrib/admin/templates/admin_doc/template_tag_index.html:5
|
||||
#: contrib/admin/templates/admin_doc/view_detail.html:4
|
||||
#: contrib/admin/templates/admin_doc/view_index.html:5
|
||||
#: contrib/admin/templates/registration/password_change_done.html:3
|
||||
#: contrib/admin/templates/registration/password_change_form.html:3
|
||||
#: contrib/comments/templates/comments/form.html:6
|
||||
#:contrib/admin/templates/admin/base.html:25
|
||||
#:contrib/admin/templates/admin/change_form.html:10
|
||||
#:contrib/admin/templates/admin/change_list.html:5
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:3
|
||||
#:contrib/admin/templates/admin/object_history.html:3
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:9
|
||||
#:contrib/admin/templates/admin_doc/bookmarklets.html:4
|
||||
#:contrib/admin/templates/admin_doc/index.html:4
|
||||
#:contrib/admin/templates/admin_doc/missing_docutils.html:4
|
||||
#:contrib/admin/templates/admin_doc/model_detail.html:3
|
||||
#:contrib/admin/templates/admin_doc/model_index.html:5
|
||||
#:contrib/admin/templates/admin_doc/template_detail.html:4
|
||||
#:contrib/admin/templates/admin_doc/template_filter_index.html:5
|
||||
#:contrib/admin/templates/admin_doc/template_tag_index.html:5
|
||||
#:contrib/admin/templates/admin_doc/view_detail.html:4
|
||||
#:contrib/admin/templates/admin_doc/view_index.html:5
|
||||
#:contrib/admin/templates/registration/password_change_done.html:3
|
||||
#:contrib/admin/templates/registration/password_change_form.html:3
|
||||
#:contrib/comments/templates/comments/form.html:6
|
||||
msgid "Log out"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#: contrib/admin/templates/admin/base_site.html:4
|
||||
#:contrib/admin/templates/admin/base_site.html:4
|
||||
msgid "Django site admin"
|
||||
msgstr "Django-Systemverwaltung"
|
||||
|
||||
#: contrib/admin/templates/admin/base_site.html:7
|
||||
#:contrib/admin/templates/admin/base_site.html:7
|
||||
msgid "Django administration"
|
||||
msgstr "Django-Verwaltung"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:15
|
||||
#: contrib/admin/templates/admin/index.html:28
|
||||
#:contrib/admin/templates/admin/change_form.html:15
|
||||
#:contrib/admin/templates/admin/index.html:28
|
||||
msgid "Add"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:21
|
||||
#: contrib/admin/templates/admin/object_history.html:5
|
||||
#:contrib/admin/templates/admin/change_form.html:21
|
||||
#:contrib/admin/templates/admin/object_history.html:5
|
||||
msgid "History"
|
||||
msgstr "Geschichte"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:22
|
||||
#:contrib/admin/templates/admin/change_form.html:22
|
||||
msgid "View on site"
|
||||
msgstr "Im Web anzeigen"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:32
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:24
|
||||
#:contrib/admin/templates/admin/change_form.html:32
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:24
|
||||
msgid "Please correct the error below."
|
||||
msgid_plural "Please correct the errors below."
|
||||
msgstr[0] "Bitte den aufgeführten Fehler korrigieren."
|
||||
msgstr[1] "Bitte die aufgeführten Fehler korrigieren."
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:50
|
||||
#:contrib/admin/templates/admin/change_form.html:50
|
||||
msgid "Ordering"
|
||||
msgstr "Sortierung"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:53
|
||||
#:contrib/admin/templates/admin/change_form.html:53
|
||||
msgid "Order:"
|
||||
msgstr "Reihenfolge:"
|
||||
|
||||
#: contrib/admin/templates/admin/change_list.html:12
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/change_list.html:12
|
||||
#,python-format
|
||||
msgid "Add %(name)s"
|
||||
msgstr "%(name)s hinzufügen"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:9
|
||||
#: contrib/admin/templates/admin/submit_line.html:3
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:9
|
||||
#:contrib/admin/templates/admin/submit_line.html:3
|
||||
msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:14
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:14
|
||||
#,python-format
|
||||
msgid ""
|
||||
"Deleting the %(object_name)s '%(escaped_object)s' would result in deleting "
|
||||
"related objects, but your account doesn't have permission to delete the "
|
||||
"following types of objects:"
|
||||
msgstr ""
|
||||
"Die Löschung des %(object_name)s '%(escaped_object)s' hätte die Löschung von "
|
||||
msgstr "Die Löschung des %(object_name)s '%(escaped_object)s' hätte die Löschung von "
|
||||
"abhängigen Daten zur Folge, aber Sie haben nicht die nötigen Rechte um die "
|
||||
"folgenden abhängigen Daten zu löschen:"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:21
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:21
|
||||
#,python-format
|
||||
msgid ""
|
||||
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
|
||||
"All of the following related items will be deleted:"
|
||||
msgstr ""
|
||||
"Sind Sie sicher, dass Sie %(object_name)s \"%(escaped_object)s\" löschen "
|
||||
msgstr "Sind Sie sicher, dass Sie %(object_name)s \"%(escaped_object)s\" löschen "
|
||||
"wollen? Es werden zusätzlich die folgenden abhängigen Daten mit gelöscht:"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:26
|
||||
#:contrib/admin/templates/admin/delete_confirmation.html:26
|
||||
msgid "Yes, I'm sure"
|
||||
msgstr "Ja, ich bin sicher"
|
||||
|
||||
#: contrib/admin/templates/admin/filter.html:2
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/filter.html:2
|
||||
#,python-format
|
||||
msgid " By %(filter_title)s "
|
||||
msgstr " Nach %(filter_title)s "
|
||||
|
||||
#: contrib/admin/templates/admin/filters.html:4
|
||||
#:contrib/admin/templates/admin/filters.html:4
|
||||
msgid "Filter"
|
||||
msgstr "Filter"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:17
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/index.html:17
|
||||
#,python-format
|
||||
msgid "Models available in the %(name)s application."
|
||||
msgstr "Modelle, die in der Anwendung %(name)s vorhanden sind."
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:18
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/index.html:18
|
||||
#,python-format
|
||||
msgid "%(name)s"
|
||||
msgstr "%(name)s"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:34
|
||||
#:contrib/admin/templates/admin/index.html:34
|
||||
msgid "Change"
|
||||
msgstr "Ändern"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:44
|
||||
#:contrib/admin/templates/admin/index.html:44
|
||||
msgid "You don't have permission to edit anything."
|
||||
msgstr "Sie haben keine Berechtigung irgendwas zu ändern."
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:52
|
||||
#:contrib/admin/templates/admin/index.html:52
|
||||
msgid "Recent Actions"
|
||||
msgstr "Kürzliche Aktionen"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:53
|
||||
#:contrib/admin/templates/admin/index.html:53
|
||||
msgid "My Actions"
|
||||
msgstr "Meine Aktionen"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:57
|
||||
#:contrib/admin/templates/admin/index.html:57
|
||||
msgid "None available"
|
||||
msgstr "Keine vorhanden"
|
||||
|
||||
#: contrib/admin/templates/admin/invalid_setup.html:8
|
||||
#:contrib/admin/templates/admin/invalid_setup.html:8
|
||||
msgid ""
|
||||
"Something's wrong with your database installation. Make sure the appropriate "
|
||||
"database tables have been created, and make sure the database is readable by "
|
||||
"the appropriate user."
|
||||
msgstr ""
|
||||
"Etwas stimmt nicht mit der Datenbankkonfiguration. Bitte sicherstellen, dass "
|
||||
"die richtigen Datenbanktabellen angelegt wurden und "
|
||||
"die Datenbank vom verwendeten Datenbankbenutzer auch lesbar ist."
|
||||
msgstr "Etwas stimmt nicht mit der Datenbankkonfiguration. Bitte sicherstellen, dass "
|
||||
"die richtigen Datenbanktabellen angelegt wurden und die Datenbank vom "
|
||||
"verwendeten Datenbankbenutzer auch lesbar ist."
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:17
|
||||
#: contrib/comments/templates/comments/form.html:6
|
||||
#: contrib/comments/templates/comments/form.html:8
|
||||
#:contrib/admin/templates/admin/login.html:17
|
||||
#:contrib/comments/templates/comments/form.html:6
|
||||
#:contrib/comments/templates/comments/form.html:8
|
||||
msgid "Username:"
|
||||
msgstr "Benutzername:"
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:20
|
||||
#: contrib/comments/templates/comments/form.html:8
|
||||
#:contrib/admin/templates/admin/login.html:20
|
||||
#:contrib/comments/templates/comments/form.html:8
|
||||
msgid "Password:"
|
||||
msgstr "Passwort:"
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:25
|
||||
#: contrib/admin/views/decorators.py:24
|
||||
#:contrib/admin/templates/admin/login.html:25
|
||||
#:contrib/admin/views/decorators.py:24
|
||||
msgid "Log in"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:18
|
||||
#:contrib/admin/templates/admin/object_history.html:18
|
||||
msgid "Date/time"
|
||||
msgstr "Datum/Zeit"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:19
|
||||
#:contrib/admin/templates/admin/object_history.html:19
|
||||
msgid "User"
|
||||
msgstr "Benutzer"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:20
|
||||
#:contrib/admin/templates/admin/object_history.html:20
|
||||
msgid "Action"
|
||||
msgstr "Aktion"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:26
|
||||
#:contrib/admin/templates/admin/object_history.html:26
|
||||
msgid "DATE_WITH_TIME_FULL"
|
||||
msgstr "j. N Y, H:i"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:36
|
||||
#:contrib/admin/templates/admin/object_history.html:36
|
||||
msgid ""
|
||||
"This object doesn't have a change history. It probably wasn't added via this "
|
||||
"admin site."
|
||||
msgstr ""
|
||||
"Dieses Objekt hat keine Änderungsgeschichte. Es wurde möglicherweise nicht "
|
||||
msgstr "Dieses Objekt hat keine Änderungsgeschichte. Es wurde möglicherweise nicht "
|
||||
"über diese Verwaltungsseiten angelegt."
|
||||
|
||||
#: contrib/admin/templates/admin/pagination.html:10
|
||||
#:contrib/admin/templates/admin/pagination.html:10
|
||||
msgid "Show all"
|
||||
msgstr "Zeige alle"
|
||||
|
||||
#: contrib/admin/templates/admin/search_form.html:8
|
||||
#:contrib/admin/templates/admin/search_form.html:8
|
||||
msgid "Go"
|
||||
msgstr "Los"
|
||||
|
||||
#: contrib/admin/templates/admin/search_form.html:10
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/search_form.html:10
|
||||
#,python-format
|
||||
msgid "1 result"
|
||||
msgid_plural "%(counter)s results"
|
||||
msgstr[0] "Ein Ergebnis"
|
||||
msgstr[1] "%(counter)s Ergebnisse"
|
||||
|
||||
#: contrib/admin/templates/admin/search_form.html:10
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/search_form.html:10
|
||||
#,python-format
|
||||
msgid "%(full_result_count)s total"
|
||||
msgstr "%(full_result_count)s gesamt"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:4
|
||||
#:contrib/admin/templates/admin/submit_line.html:4
|
||||
msgid "Save as new"
|
||||
msgstr "Als neu sichern"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:5
|
||||
#:contrib/admin/templates/admin/submit_line.html:5
|
||||
msgid "Save and add another"
|
||||
msgstr "Sichern und neu hinzufügen"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:6
|
||||
#:contrib/admin/templates/admin/submit_line.html:6
|
||||
msgid "Save and continue editing"
|
||||
msgstr "Sichern und weiter bearbeiten"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:7
|
||||
#:contrib/admin/templates/admin/submit_line.html:7
|
||||
msgid "Save"
|
||||
msgstr "Sichern"
|
||||
|
||||
#: contrib/admin/templates/admin/auth/user/add_form.html:6
|
||||
#:contrib/admin/templates/admin/auth/user/add_form.html:6
|
||||
msgid ""
|
||||
"First, enter a username and password. Then, you'll be able to edit more user "
|
||||
"options."
|
||||
msgstr ""
|
||||
"Zuerst einen Benutzer und ein Passwort eingeben. Danach können weitere "
|
||||
msgstr "Zuerst einen Benutzer und ein Passwort eingeben. Danach können weitere "
|
||||
"Optionen für den Benutzer geändert werden."
|
||||
|
||||
#: contrib/admin/templates/admin/auth/user/add_form.html:12
|
||||
#:contrib/admin/templates/admin/auth/user/add_form.html:12
|
||||
msgid "Username"
|
||||
msgstr "Benutzername"
|
||||
|
||||
#: contrib/admin/templates/admin/auth/user/add_form.html:18
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:34
|
||||
#:contrib/admin/templates/admin/auth/user/add_form.html:18
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:34
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: contrib/admin/templates/admin/auth/user/add_form.html:23
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:39
|
||||
#:contrib/admin/templates/admin/auth/user/add_form.html:23
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:39
|
||||
msgid "Password (again)"
|
||||
msgstr "Passwort (wiederholen)"
|
||||
|
||||
#: contrib/admin/templates/admin/auth/user/add_form.html:24
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:40
|
||||
#:contrib/admin/templates/admin/auth/user/add_form.html:24
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:40
|
||||
msgid "Enter the same password as above, for verification."
|
||||
msgstr "Bitte das gleiche Passwort zur Überprüfung nochmal eingeben."
|
||||
|
||||
#: contrib/admin/templates/admin/auth/user/change_password.html:28
|
||||
#, python-format
|
||||
#:contrib/admin/templates/admin/auth/user/change_password.html:28
|
||||
#,python-format
|
||||
msgid "Enter a new password for the user <strong>%(username)s</strong>."
|
||||
msgstr ""
|
||||
"Bitte geben Sie ein neues Passwort für den Benutzer <strong>%(username)s</"
|
||||
msgstr "Bitte geben Sie ein neues Passwort für den Benutzer <strong>%(username)s</"
|
||||
"strong> ein."
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
|
||||
#:contrib/admin/templates/admin_doc/bookmarklets.html:3
|
||||
msgid "Bookmarklets"
|
||||
msgstr "Bookmarklets"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:5
|
||||
#:contrib/admin/templates/admin_doc/bookmarklets.html:5
|
||||
msgid "Documentation bookmarklets"
|
||||
msgstr "Dokumentations-Bookmarklets"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:9
|
||||
#:contrib/admin/templates/admin_doc/bookmarklets.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
"<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n"
|
||||
@ -612,9 +611,9 @@ msgid ""
|
||||
"bookmarklets require you to be viewing the site from a computer designated\n"
|
||||
"as \"internal\" (talk to your system administrator if you aren't sure if\n"
|
||||
"your computer is \"internal\").</p>\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p class=\"help\">Um Bookmarklets zu installieren, müssen diese Links in die\n"
|
||||
msgstr "\n"
|
||||
"<p class=\"help\">Um Bookmarklets zu installieren, müssen diese Links in "
|
||||
"die\n"
|
||||
"Browser-Werkzeugleiste gezogen werden, oder mittels rechter Maustaste in "
|
||||
"die\n"
|
||||
"Bookmarks gespeichert werden. Danach können die Bookmarklets von jeder "
|
||||
@ -830,7 +829,7 @@ msgid ""
|
||||
"Please enter a correct username and password. Note that both fields are case-"
|
||||
"sensitive."
|
||||
msgstr ""
|
||||
"Bitte einen Benutzernamen und ein Passwort eingeben. Beide Felder "
|
||||
"Bitte einen gültigen Benutzernamen und ein Passwort eingeben. Beide Felder "
|
||||
"berücksichtigen die Groß-/Kleinschreibung."
|
||||
|
||||
#: contrib/admin/views/decorators.py:62
|
||||
|
Binary file not shown.
@ -11,21 +11,21 @@ msgstr ""
|
||||
"PO-Revision-Date: 2005-12-04 13:21+0100\n"
|
||||
"Last-Translator: Dirk Eschler <dirk.eschler@gmx.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=iso-8859-1\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "Verfügbare %s"
|
||||
msgstr "Verfügbare %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr "Alles auswählen"
|
||||
msgstr "Alles auswählen"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr "Hinzufügen"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
@ -34,15 +34,15 @@ msgstr "Entfernen"
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "Ausgewählte %s"
|
||||
msgstr "Ausgewählte %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr "Gewünschte Auswahl treffen und "
|
||||
msgstr "Gewünschte Auswahl treffen und "
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr "Alles abwählen"
|
||||
msgstr "Alles abwählen"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:26
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
@ -50,7 +50,7 @@ msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr ""
|
||||
"Januar Februar März April Mai Juni Juli August September Oktober November "
|
||||
"Januar Februar März April Mai Juni Juli August September Oktober November "
|
||||
"Dezember"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,26 +1,41 @@
|
||||
# Spanish translation for the django-admin JS files.
|
||||
# Copyright (C)
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Jorge Gajon <gajon@gajon.org>, 2005.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django JavaScript 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: 2005-12-06 21:32+0100\n"
|
||||
"POT-Creation-Date: 2007-07-14 13:47-0500\n"
|
||||
"PO-Revision-Date: 2007-07-14 13:41-0500\n"
|
||||
"Last-Translator: Jorge Gajon <gajon@gajon.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\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 ""
|
||||
"Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre "
|
||||
"Noviembre Diciembre"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "D L M M J V S"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "%s Disponibles"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
#, fuzzy
|
||||
msgid "Choose all"
|
||||
msgstr "Selecciona todos"
|
||||
|
||||
@ -45,66 +60,58 @@ msgstr "Haz tus elecciones y da click en "
|
||||
msgid "Clear all"
|
||||
msgstr "Elimina todos"
|
||||
|
||||
#: 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 ""
|
||||
"Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre "
|
||||
"Noviembre Diciembre"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "D L M M J V S"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Now"
|
||||
msgstr "Ahora"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr "Reloj"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr "Elige una hora"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr "Medianoche"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr "6 a.m."
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "Mediodía"
|
||||
msgstr "Mediodía"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||
msgid "Today"
|
||||
msgstr "Hoy"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr "Calendario"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr "Ayer"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "Mañana"
|
||||
msgstr "Mañana"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr "Mostrar"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr "Esconder"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,17 +1,17 @@
|
||||
# Argentinean spanish translation for the django-admin JS files, based on
|
||||
# Spanish translation work by Jorge Gajon.
|
||||
# This file is distributed under the same license as the Django package.
|
||||
# Copyright (C) Ramiro Morales <rm0@gmx.net>, 2006,2007.
|
||||
# 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 JavaScript 1.0\n"
|
||||
"Project-Id-Version: Django Javascript 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-02-25 17:48-0300\n"
|
||||
"PO-Revision-Date: 2007-02-25 17:55-0300\n"
|
||||
"POT-Creation-Date: 2007-07-14 13:45-0300\n"
|
||||
"PO-Revision-Date: 2007-07-14 14:36-0300\n"
|
||||
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
|
||||
"Language-Team: Django-I18N <django-i18n@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
@ -55,7 +55,7 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado"
|
||||
msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
@ -93,7 +93,7 @@ msgstr "6 a.m."
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "Mediodía"
|
||||
msgstr "Mediodía"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
@ -115,4 +115,4 @@ msgstr "Ayer"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "Mañana"
|
||||
msgstr "Mañana"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
# French translation for js.
|
||||
# Copyright (C) 2005 Mikaël Barbero
|
||||
# Copyright (C) 2005 Mikaël Barbero
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Mikaël Barbero <mikael.barbero nospam at nospam free.fr>, 2005.
|
||||
# Mikaël Barbero <mikael.barbero nospam at nospam free.fr>, 2005.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
@ -9,10 +9,10 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-24 16:39+0100\n"
|
||||
"PO-Revision-Date: 2005-12-24 16:39+0100\n"
|
||||
"Last-Translator: Mikaël Barbero <mikael.barbero nospam at nospam free.fr>\n"
|
||||
"Last-Translator: Mikaël Barbero <mikael.barbero nospam at nospam free.fr>\n"
|
||||
"Language-Team: French <fr@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
@ -21,8 +21,8 @@ msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr ""
|
||||
"Janvier Février Mars Avril Mai Juin Juillet Août Septembre Octobre Novembre "
|
||||
"Décembre"
|
||||
"Janvier Février Mars Avril Mai Juin Juillet Août Septembre Octobre Novembre "
|
||||
"Décembre"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
@ -35,7 +35,7 @@ msgstr "Dimanche Lundi Mardi Mercredi Jeudi Vendredi Samedi"
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "Disponible %s"
|
||||
msgstr "%s disponible(s)"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
@ -52,11 +52,11 @@ msgstr "Enlever"
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "Choisi %s"
|
||||
msgstr "%s choisi(es)"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr "Sélectionnez un ou plusieurs choix et cliquez "
|
||||
msgstr "Sélectionnez un ou plusieurs choix et cliquez "
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
|
BIN
django/conf/locale/hr/LC_MESSAGES/django.mo
Normal file
BIN
django/conf/locale/hr/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
3282
django/conf/locale/hr/LC_MESSAGES/django.po
Normal file
3282
django/conf/locale/hr/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/hr/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/hr/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
118
django/conf/locale/hr/LC_MESSAGES/djangojs.po
Normal file
118
django/conf/locale/hr/LC_MESSAGES/djangojs.po
Normal file
@ -0,0 +1,118 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-08-13 11:13+1000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@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/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/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr ""
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr ""
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
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.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -38,7 +38,7 @@ msgstr "Domenica Lunedì Martedì Mercoledì Giovedì Venerdì Sabato"
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "Disponibile %s"
|
||||
msgstr "%s disponibili"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
@ -55,11 +55,11 @@ msgstr "Rimuovi"
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "Scelto %s"
|
||||
msgstr "%s scelti"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr "Seleziona le tue scelte e clicca "
|
||||
msgstr "Fai le tue scelte e clicca "
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
|
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.
@ -5,8 +5,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: DJANGO-JS\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: 2007-03-31 21:29+0100\n"
|
||||
"POT-Creation-Date: 2007-07-02 13:55+0200\n"
|
||||
"PO-Revision-Date: 2007-07-02 13:56+0100\n"
|
||||
"Last-Translator: Gasper Koren <skrat@owca.info>\n"
|
||||
"Language-Team: SLOVENIAN <lugos-slo@lugos.si>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -15,6 +15,19 @@ msgstr ""
|
||||
"X-Poedit-Language: Slovenian\n"
|
||||
"X-Poedit-Country: SLOVENIA\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 "Januar Februar Marec April Maj Junij Julij Avgust September Oktober November December"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "N P T S Č P S"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Nedelja Ponedeljek Torek Sreda Četrtek Petek Sobota"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
@ -45,63 +58,59 @@ msgstr "Izberite in kliknite"
|
||||
msgid "Clear all"
|
||||
msgstr "Izbriši vse"
|
||||
|
||||
#: 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 "Januar Februar Marec April Maj Junij Julij Avgust September Oktober November December"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Nedelja Ponedeljek Torek Sreda Četrtek Petek Sobota"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "N P T S Č P S"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Now"
|
||||
msgstr "Sedaj"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr "URA"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr "Izberite čas"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr "Polnoč"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr "Ob 6h"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "Opoldne"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
msgid "Cancel"
|
||||
msgstr "Prekliči"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||
msgid "Today"
|
||||
msgstr "Danes"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr "Koledar"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr "Včeraj"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "Jutri"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr "Prikaži"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr "Skrij"
|
||||
|
||||
|
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
@ -17,15 +17,14 @@ DATABASE_HOST = '' # Set to empty string for localhost. Not used wit
|
||||
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
|
||||
# although not all variations may be possible on all operating systems.
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be avilable on all operating systems.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
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://blogs.law.harvard.edu/tech/stories/storyReader$15
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
SITE_ID = 1
|
||||
|
@ -7,6 +7,8 @@ certain test -- e.g. being a DateField or ForeignKey.
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
from django.utils.encoding import smart_unicode, iri_to_uri
|
||||
from django.utils.translation import ugettext as _
|
||||
import datetime
|
||||
|
||||
class FilterSpec(object):
|
||||
@ -37,12 +39,12 @@ class FilterSpec(object):
|
||||
def output(self, cl):
|
||||
t = []
|
||||
if self.has_output():
|
||||
t.append(_('<h3>By %s:</h3>\n<ul>\n') % self.title())
|
||||
t.append(_(u'<h3>By %s:</h3>\n<ul>\n') % self.title())
|
||||
|
||||
for choice in self.choices(cl):
|
||||
t.append('<li%s><a href="%s">%s</a></li>\n' % \
|
||||
t.append(u'<li%s><a href="%s">%s</a></li>\n' % \
|
||||
((choice['selected'] and ' class="selected"' or ''),
|
||||
choice['query_string'] ,
|
||||
iri_to_uri(choice['query_string']),
|
||||
choice['display']))
|
||||
t.append('</ul>\n\n')
|
||||
return "".join(t)
|
||||
@ -70,7 +72,7 @@ class RelatedFilterSpec(FilterSpec):
|
||||
'display': _('All')}
|
||||
for val in self.lookup_choices:
|
||||
pk_val = getattr(val, self.field.rel.to._meta.pk.attname)
|
||||
yield {'selected': self.lookup_val == str(pk_val),
|
||||
yield {'selected': self.lookup_val == smart_unicode(pk_val),
|
||||
'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}),
|
||||
'display': val}
|
||||
|
||||
@ -87,7 +89,7 @@ class ChoicesFilterSpec(FilterSpec):
|
||||
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
|
||||
'display': _('All')}
|
||||
for k, v in self.field.choices:
|
||||
yield {'selected': str(k) == self.lookup_val,
|
||||
yield {'selected': smart_unicode(k) == self.lookup_val,
|
||||
'query_string': cl.get_query_string({self.lookup_kwarg: k}),
|
||||
'display': v}
|
||||
|
||||
@ -168,7 +170,7 @@ class AllValuesFilterSpec(FilterSpec):
|
||||
'query_string': cl.get_query_string({}, [self.field.name]),
|
||||
'display': _('All')}
|
||||
for val in self.lookup_choices:
|
||||
val = str(val[self.field.name])
|
||||
val = smart_unicode(val[self.field.name])
|
||||
yield {'selected': self.lookup_val == val,
|
||||
'query_string': cl.get_query_string({self.field.name: val}),
|
||||
'display': val}
|
||||
|
@ -31,10 +31,11 @@ function showAddAnotherPopup(triggeringLink) {
|
||||
var name = triggeringLink.id.replace(/^add_/, '');
|
||||
name = name.replace(/\./g, '___');
|
||||
href = triggeringLink.href
|
||||
if (href.indexOf('?') == -1)
|
||||
href += '?_popup=1';
|
||||
else
|
||||
href += '&_popup=1';
|
||||
if (href.indexOf('?') == -1) {
|
||||
href += '?_popup=1';
|
||||
} else {
|
||||
href += '&_popup=1';
|
||||
}
|
||||
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
|
||||
win.focus();
|
||||
return false;
|
||||
|
@ -1,15 +1,121 @@
|
||||
var LATIN_MAP = {
|
||||
'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
|
||||
'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
|
||||
'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
|
||||
'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
|
||||
'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä':
|
||||
'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
|
||||
'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'o', 'ñ': 'n', 'ò': 'o', 'ó':
|
||||
'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u',
|
||||
'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
|
||||
}
|
||||
var LATIN_SYMBOLS_MAP = {
|
||||
'©':'(c)'
|
||||
}
|
||||
var GREEK_MAP = {
|
||||
'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8',
|
||||
'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p',
|
||||
'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w',
|
||||
'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s',
|
||||
'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i',
|
||||
'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8',
|
||||
'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P',
|
||||
'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W',
|
||||
'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I',
|
||||
'Ϋ':'Y'
|
||||
}
|
||||
var TURKISH_MAP = {
|
||||
'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U',
|
||||
'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G'
|
||||
}
|
||||
var RUSSIAN_MAP = {
|
||||
'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh',
|
||||
'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o',
|
||||
'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c',
|
||||
'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu',
|
||||
'я':'ya',
|
||||
'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh',
|
||||
'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O',
|
||||
'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C',
|
||||
'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
|
||||
'Я':'Ya'
|
||||
}
|
||||
var CZECH_MAP = {
|
||||
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
|
||||
'ž':'z'
|
||||
}
|
||||
|
||||
var ALL_DOWNCODE_MAPS=new Array()
|
||||
ALL_DOWNCODE_MAPS[0]=LATIN_MAP
|
||||
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
|
||||
|
||||
var Downcoder = new Object();
|
||||
Downcoder.Initialize = function()
|
||||
{
|
||||
if (Downcoder.map) // already made
|
||||
return ;
|
||||
Downcoder.map ={}
|
||||
Downcoder.chars = '' ;
|
||||
for(var i in ALL_DOWNCODE_MAPS)
|
||||
{
|
||||
var lookup = ALL_DOWNCODE_MAPS[i]
|
||||
for (var c in lookup)
|
||||
{
|
||||
Downcoder.map[c] = lookup[c] ;
|
||||
Downcoder.chars += c ;
|
||||
}
|
||||
}
|
||||
Downcoder.regex = new RegExp('[' + Downcoder.chars + ']|[^' + Downcoder.chars + ']+','g') ;
|
||||
}
|
||||
|
||||
downcode= function( slug )
|
||||
{
|
||||
Downcoder.Initialize() ;
|
||||
var downcoded =""
|
||||
var pieces = slug.match(Downcoder.regex);
|
||||
if(pieces)
|
||||
{
|
||||
for (var i = 0 ; i < pieces.length ; i++)
|
||||
{
|
||||
if (pieces[i].length == 1)
|
||||
{
|
||||
var mapped = Downcoder.map[pieces[i]] ;
|
||||
if (mapped != null)
|
||||
{
|
||||
downcoded+=mapped;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
downcoded+=pieces[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
downcoded = slug;
|
||||
}
|
||||
return downcoded;
|
||||
}
|
||||
|
||||
|
||||
function URLify(s, num_chars) {
|
||||
// changes, e.g., "Petty theft" to "petty_theft"
|
||||
// remove all these words from the string before urlifying
|
||||
s = downcode(s);
|
||||
removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from",
|
||||
"is", "in", "into", "like", "of", "off", "on", "onto", "per",
|
||||
"since", "than", "the", "this", "that", "to", "up", "via",
|
||||
"with"];
|
||||
r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
|
||||
s = s.replace(r, '');
|
||||
// if downcode doesn't hit, the char will be stripped here
|
||||
s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
|
||||
s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
|
||||
s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
|
||||
s = s.toLowerCase(); // convert to lowercase
|
||||
return s.substring(0, num_chars);// trim to first num_chars chars
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
from django.db import models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import smart_unicode
|
||||
|
||||
ADDITION = 1
|
||||
CHANGE = 2
|
||||
@ -9,7 +10,7 @@ DELETION = 3
|
||||
|
||||
class LogEntryManager(models.Manager):
|
||||
def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''):
|
||||
e = self.model(None, None, user_id, content_type_id, str(object_id), object_repr[:200], action_flag, change_message)
|
||||
e = self.model(None, None, user_id, content_type_id, smart_unicode(object_id), object_repr[:200], action_flag, change_message)
|
||||
e.save()
|
||||
|
||||
class LogEntry(models.Model):
|
||||
@ -17,7 +18,7 @@ class LogEntry(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
content_type = models.ForeignKey(ContentType, blank=True, null=True)
|
||||
object_id = models.TextField(_('object id'), blank=True, null=True)
|
||||
object_repr = models.CharField(_('object repr'), maxlength=200)
|
||||
object_repr = models.CharField(_('object repr'), max_length=200)
|
||||
action_flag = models.PositiveSmallIntegerField(_('action flag'))
|
||||
change_message = models.TextField(_('change message'), blank=True)
|
||||
objects = LogEntryManager()
|
||||
@ -28,7 +29,7 @@ class LogEntry(models.Model):
|
||||
ordering = ('-action_time',)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.action_time)
|
||||
return smart_unicode(self.action_time)
|
||||
|
||||
def is_addition(self):
|
||||
return self.action_flag == ADDITION
|
||||
@ -48,4 +49,4 @@ class LogEntry(models.Model):
|
||||
Returns the admin URL to edit the object represented by this log entry.
|
||||
This is relative to the Django admin index page.
|
||||
"""
|
||||
return "%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, self.object_id)
|
||||
return u"%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, self.object_id)
|
||||
|
@ -6,7 +6,7 @@
|
||||
{% endblock %}
|
||||
{% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %}
|
||||
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
|
||||
{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
||||
{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
||||
{% block breadcrumbs %}{% if not is_popup %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="../../../../">{% trans "Home" %}</a> ›
|
||||
|
@ -3,6 +3,6 @@
|
||||
<ul>
|
||||
{% for choice in choices %}
|
||||
<li{% if choice.selected %} class="selected"{% endif %}>
|
||||
<a href="{{ choice.query_string }}">{{ choice.display|escape }}</a></li>
|
||||
<a href="{{ choice.query_string|iriencode }}">{{ choice.display|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
@ -58,7 +58,7 @@
|
||||
{% else %}
|
||||
<ul class="actionlist">
|
||||
{% for entry in admin_log %}
|
||||
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr|escape }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{{ entry.content_type.name|capfirst|escape }}</span></li>
|
||||
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr|escape }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{% filter capfirst|escape %}{% trans entry.content_type.name %}{% endfilter %}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
@ -6,7 +6,8 @@ from django.db import models
|
||||
from django.utils import dateformat
|
||||
from django.utils.html import escape
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import get_date_formats, get_partial_date_formats
|
||||
from django.utils.translation import get_date_formats, get_partial_date_formats, ugettext as _
|
||||
from django.utils.encoding import smart_unicode, smart_str, force_unicode
|
||||
from django.template import Library
|
||||
import datetime
|
||||
|
||||
@ -16,11 +17,11 @@ DOT = '.'
|
||||
|
||||
def paginator_number(cl,i):
|
||||
if i == DOT:
|
||||
return '... '
|
||||
return u'... '
|
||||
elif i == cl.page_num:
|
||||
return '<span class="this-page">%d</span> ' % (i+1)
|
||||
return u'<span class="this-page">%d</span> ' % (i+1)
|
||||
else:
|
||||
return '<a href="%s"%s>%d</a> ' % (cl.get_query_string({PAGE_VAR: i}), (i == cl.paginator.pages-1 and ' class="end"' or ''), i+1)
|
||||
return u'<a href="%s"%s>%d</a> ' % (cl.get_query_string({PAGE_VAR: i}), (i == cl.paginator.pages-1 and ' class="end"' or ''), i+1)
|
||||
paginator_number = register.simple_tag(paginator_number)
|
||||
|
||||
def pagination(cl):
|
||||
@ -75,10 +76,12 @@ def result_headers(cl):
|
||||
admin_order_field = None
|
||||
except models.FieldDoesNotExist:
|
||||
# For non-field list_display values, check for the function
|
||||
# attribute "short_description". If that doesn't exist, fall
|
||||
# back to the method name. And __str__ is a special-case.
|
||||
if field_name == '__str__':
|
||||
header = lookup_opts.verbose_name
|
||||
# attribute "short_description". If that doesn't exist, fall back
|
||||
# to the method name. And __str__ and __unicode__ are special-cases.
|
||||
if field_name == '__unicode__':
|
||||
header = force_unicode(lookup_opts.verbose_name)
|
||||
elif field_name == '__str__':
|
||||
header = smart_str(lookup_opts.verbose_name)
|
||||
else:
|
||||
attr = getattr(cl.model, field_name) # Let AttributeErrors propagate.
|
||||
try:
|
||||
@ -114,7 +117,7 @@ def result_headers(cl):
|
||||
|
||||
def _boolean_icon(field_val):
|
||||
BOOLEAN_MAPPING = {True: 'yes', False: 'no', None: 'unknown'}
|
||||
return '<img src="%simg/admin/icon-%s.gif" alt="%s" />' % (settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val)
|
||||
return u'<img src="%simg/admin/icon-%s.gif" alt="%s" />' % (settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val)
|
||||
|
||||
def items_for_result(cl, result):
|
||||
first = True
|
||||
@ -136,7 +139,7 @@ def items_for_result(cl, result):
|
||||
allow_tags = True
|
||||
result_repr = _boolean_icon(attr)
|
||||
else:
|
||||
result_repr = str(attr)
|
||||
result_repr = smart_unicode(attr)
|
||||
except (AttributeError, ObjectDoesNotExist):
|
||||
result_repr = EMPTY_CHANGELIST_VALUE
|
||||
else:
|
||||
@ -179,19 +182,21 @@ def items_for_result(cl, result):
|
||||
elif f.choices:
|
||||
result_repr = dict(f.choices).get(field_val, EMPTY_CHANGELIST_VALUE)
|
||||
else:
|
||||
result_repr = escape(str(field_val))
|
||||
if result_repr == '':
|
||||
result_repr = escape(field_val)
|
||||
if force_unicode(result_repr) == '':
|
||||
result_repr = ' '
|
||||
# If list_display_links not defined, add the link tag to the first field
|
||||
if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links:
|
||||
table_tag = {True:'th', False:'td'}[first]
|
||||
first = False
|
||||
url = cl.url_for_result(result)
|
||||
result_id = str(getattr(result, pk)) # str() is needed in case of 23L (long ints)
|
||||
yield ('<%s%s><a href="%s"%s>%s</a></%s>' % \
|
||||
(table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %r); return false;"' % result_id or ''), result_repr, table_tag))
|
||||
# Convert the pk to something that can be used in Javascript.
|
||||
# Problem cases are long ints (23L) and non-ASCII strings.
|
||||
result_id = repr(force_unicode(getattr(result, pk)))[1:]
|
||||
yield (u'<%s%s><a href="%s"%s>%s</a></%s>' % \
|
||||
(table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), result_repr, table_tag))
|
||||
else:
|
||||
yield ('<td%s>%s</td>' % (row_class, result_repr))
|
||||
yield (u'<td%s>%s</td>' % (row_class, result_repr))
|
||||
|
||||
def results(cl):
|
||||
for res in cl.result_list:
|
||||
|
@ -2,6 +2,7 @@ from django import template
|
||||
from django.contrib.admin.views.main import AdminBoundField
|
||||
from django.template import loader
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.db import models
|
||||
from django.db.models.fields import Field
|
||||
from django.db.models.related import BoundRelatedObject
|
||||
@ -14,7 +15,7 @@ word_re = re.compile('[A-Z][a-z]+')
|
||||
absolute_url_re = re.compile(r'^(?:http(?:s)?:/)?/', re.IGNORECASE)
|
||||
|
||||
def class_name_to_underscored(name):
|
||||
return '_'.join([s.lower() for s in word_re.findall(name)[:-1]])
|
||||
return u'_'.join([s.lower() for s in word_re.findall(name)[:-1]])
|
||||
|
||||
def include_admin_script(script_path):
|
||||
"""
|
||||
@ -31,7 +32,7 @@ def include_admin_script(script_path):
|
||||
"""
|
||||
if not absolute_url_re.match(script_path):
|
||||
script_path = '%s%s' % (settings.ADMIN_MEDIA_PREFIX, script_path)
|
||||
return '<script type="text/javascript" src="%s"></script>' % script_path
|
||||
return u'<script type="text/javascript" src="%s"></script>' % script_path
|
||||
include_admin_script = register.simple_tag(include_admin_script)
|
||||
|
||||
def submit_row(context):
|
||||
@ -61,9 +62,9 @@ def field_label(bound_field):
|
||||
if not bound_field.first:
|
||||
class_names.append('inline')
|
||||
colon = ":"
|
||||
class_str = class_names and ' class="%s"' % ' '.join(class_names) or ''
|
||||
return '<label for="%s"%s>%s%s</label> ' % (bound_field.element_id, class_str, \
|
||||
capfirst(bound_field.field.verbose_name), colon)
|
||||
class_str = class_names and u' class="%s"' % u' '.join(class_names) or u''
|
||||
return u'<label for="%s"%s>%s%s</label> ' % (bound_field.element_id, class_str, \
|
||||
force_unicode(capfirst(bound_field.field.verbose_name)), colon)
|
||||
field_label = register.simple_tag(field_label)
|
||||
|
||||
class FieldWidgetNode(template.Node):
|
||||
@ -77,7 +78,7 @@ class FieldWidgetNode(template.Node):
|
||||
if klass not in cls.nodelists:
|
||||
try:
|
||||
field_class_name = klass.__name__
|
||||
template_name = "widget/%s.html" % class_name_to_underscored(field_class_name)
|
||||
template_name = u"widget/%s.html" % class_name_to_underscored(field_class_name)
|
||||
nodelist = loader.get_template(template_name).nodelist
|
||||
except template.TemplateDoesNotExist:
|
||||
super_klass = bool(klass.__bases__) and klass.__bases__[0] or None
|
||||
@ -175,30 +176,30 @@ class EditInlineNode(template.Node):
|
||||
return output
|
||||
|
||||
def output_all(form_fields):
|
||||
return ''.join([str(f) for f in form_fields])
|
||||
return u''.join([force_unicode(f) for f in form_fields])
|
||||
output_all = register.simple_tag(output_all)
|
||||
|
||||
def auto_populated_field_script(auto_pop_fields, change = False):
|
||||
t = []
|
||||
for field in auto_pop_fields:
|
||||
if change:
|
||||
t.append('document.getElementById("id_%s")._changed = true;' % field.name)
|
||||
t.append(u'document.getElementById("id_%s")._changed = true;' % field.name)
|
||||
else:
|
||||
t.append('document.getElementById("id_%s").onchange = function() { this._changed = true; };' % field.name)
|
||||
t.append(u'document.getElementById("id_%s").onchange = function() { this._changed = true; };' % field.name)
|
||||
|
||||
add_values = ' + " " + '.join(['document.getElementById("id_%s").value' % g for g in field.prepopulate_from])
|
||||
add_values = u' + " " + '.join([u'document.getElementById("id_%s").value' % g for g in field.prepopulate_from])
|
||||
for f in field.prepopulate_from:
|
||||
t.append('document.getElementById("id_%s").onkeyup = function() {' \
|
||||
t.append(u'document.getElementById("id_%s").onkeyup = function() {' \
|
||||
' var e = document.getElementById("id_%s");' \
|
||||
' if(!e._changed) { e.value = URLify(%s, %s);} }; ' % (
|
||||
f, field.name, add_values, field.maxlength))
|
||||
return ''.join(t)
|
||||
f, field.name, add_values, field.max_length))
|
||||
return u''.join(t)
|
||||
auto_populated_field_script = register.simple_tag(auto_populated_field_script)
|
||||
|
||||
def filter_interface_script_maybe(bound_field):
|
||||
f = bound_field.field
|
||||
if f.rel and isinstance(f.rel, models.ManyToManyRel) and f.rel.filter_interface:
|
||||
return '<script type="text/javascript">addEvent(window, "load", function(e) {' \
|
||||
return u'<script type="text/javascript">addEvent(window, "load", function(e) {' \
|
||||
' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % (
|
||||
f.name, f.verbose_name.replace('"', '\\"'), f.rel.filter_interface-1, settings.ADMIN_MEDIA_PREFIX)
|
||||
else:
|
||||
|
@ -1,5 +1,6 @@
|
||||
from django import template
|
||||
from django.db.models import get_models
|
||||
from django.utils.encoding import force_unicode
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@ -36,8 +37,8 @@ class AdminApplistNode(template.Node):
|
||||
# If so, add the module to the model_list.
|
||||
if True in perms.values():
|
||||
model_list.append({
|
||||
'name': capfirst(m._meta.verbose_name_plural),
|
||||
'admin_url': '%s/%s/' % (app_label, m.__name__.lower()),
|
||||
'name': force_unicode(capfirst(m._meta.verbose_name_plural)),
|
||||
'admin_url': u'%s/%s/' % (force_unicode(app_label), m.__name__.lower()),
|
||||
'perms': perms,
|
||||
})
|
||||
|
||||
|
@ -6,6 +6,7 @@ from django import oldforms, template
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
def user_add_stage(request):
|
||||
if not request.user.has_perm('auth.change_user'):
|
||||
|
@ -3,11 +3,11 @@ from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.shortcuts import render_to_response
|
||||
from django.utils.translation import gettext_lazy
|
||||
from django.utils.translation import ugettext_lazy, ugettext as _
|
||||
import base64, datetime, md5
|
||||
import cPickle as pickle
|
||||
|
||||
ERROR_MESSAGE = gettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
|
||||
ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
|
||||
LOGIN_FORM_KEY = 'this_is_the_login_form'
|
||||
|
||||
def _display_login_form(request, error_message=''):
|
||||
|
@ -9,6 +9,7 @@ from django.http import Http404, get_host
|
||||
from django.core import urlresolvers
|
||||
from django.contrib.admin import utils
|
||||
from django.contrib.sites.models import Site
|
||||
from django.utils.translation import ugettext as _
|
||||
import inspect, os, re
|
||||
|
||||
# Exclude methods starting with these strings from documentation
|
||||
@ -290,7 +291,7 @@ def get_return_data_type(func_name):
|
||||
DATA_TYPE_MAPPING = {
|
||||
'AutoField' : _('Integer'),
|
||||
'BooleanField' : _('Boolean (Either True or False)'),
|
||||
'CharField' : _('String (up to %(maxlength)s)'),
|
||||
'CharField' : _('String (up to %(max_length)s)'),
|
||||
'CommaSeparatedIntegerField': _('Comma-separated integers'),
|
||||
'DateField' : _('Date (without time)'),
|
||||
'DateTimeField' : _('Date (with time)'),
|
||||
@ -309,7 +310,7 @@ DATA_TYPE_MAPPING = {
|
||||
'PhoneNumberField' : _('Phone number'),
|
||||
'PositiveIntegerField' : _('Integer'),
|
||||
'PositiveSmallIntegerField' : _('Integer'),
|
||||
'SlugField' : _('String (up to %(maxlength)s)'),
|
||||
'SlugField' : _('String (up to %(max_length)s)'),
|
||||
'SmallIntegerField' : _('Integer'),
|
||||
'TextField' : _('Text'),
|
||||
'TimeField' : _('Time'),
|
||||
|
@ -12,6 +12,8 @@ from django.db.models.query import handle_legacy_orderlist, QuerySet
|
||||
from django.http import Http404, HttpResponse, HttpResponseRedirect
|
||||
from django.utils.html import escape
|
||||
from django.utils.text import capfirst, get_text_list
|
||||
from django.utils.encoding import force_unicode, smart_str
|
||||
from django.utils.translation import ugettext as _
|
||||
import operator
|
||||
|
||||
try:
|
||||
@ -130,11 +132,11 @@ class AdminBoundField(object):
|
||||
if max([bool(f.errors()) for f in self.form_fields]):
|
||||
classes.append('error')
|
||||
if classes:
|
||||
self.cell_class_attribute = ' class="%s" ' % ' '.join(classes)
|
||||
self.cell_class_attribute = u' class="%s" ' % ' '.join(classes)
|
||||
self._repr_filled = False
|
||||
|
||||
if field.rel:
|
||||
self.related_url = '../../../%s/%s/' % (field.rel.to._meta.app_label, field.rel.to._meta.object_name.lower())
|
||||
self.related_url = u'../../../%s/%s/' % (field.rel.to._meta.app_label, field.rel.to._meta.object_name.lower())
|
||||
|
||||
def original_value(self):
|
||||
if self.original:
|
||||
@ -145,9 +147,9 @@ class AdminBoundField(object):
|
||||
return self._display
|
||||
except AttributeError:
|
||||
if isinstance(self.field.rel, models.ManyToOneRel):
|
||||
self._display = getattr(self.original, self.field.name)
|
||||
self._display = force_unicode(getattr(self.original, self.field.name), strings_only=True)
|
||||
elif isinstance(self.field.rel, models.ManyToManyRel):
|
||||
self._display = ", ".join([str(obj) for obj in getattr(self.original, self.field.name).all()])
|
||||
self._display = u", ".join([force_unicode(obj) for obj in getattr(self.original, self.field.name).all()])
|
||||
return self._display
|
||||
|
||||
def __repr__(self):
|
||||
@ -258,8 +260,8 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
|
||||
if not errors:
|
||||
new_object = manipulator.save(new_data)
|
||||
pk_value = new_object._get_pk_val()
|
||||
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), ADDITION)
|
||||
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
|
||||
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, force_unicode(new_object), ADDITION)
|
||||
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)}
|
||||
# Here, we distinguish between different save types by checking for
|
||||
# the presence of keys in request.POST.
|
||||
if "_continue" in request.POST:
|
||||
@ -271,9 +273,9 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
|
||||
if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable.
|
||||
pk_value = '"%s"' % pk_value.replace('"', '\\"')
|
||||
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
|
||||
(pk_value, str(new_object).replace('"', '\\"')))
|
||||
(pk_value, force_unicode(new_object).replace('"', '\\"')))
|
||||
elif "_addanother" in request.POST:
|
||||
request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
|
||||
request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
||||
return HttpResponseRedirect(request.path)
|
||||
else:
|
||||
request.user.message_set.create(message=msg)
|
||||
@ -291,7 +293,7 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
|
||||
form = oldforms.FormWrapper(manipulator, new_data, errors)
|
||||
|
||||
c = template.RequestContext(request, {
|
||||
'title': _('Add %s') % opts.verbose_name,
|
||||
'title': _('Add %s') % force_unicode(opts.verbose_name),
|
||||
'form': form,
|
||||
'is_popup': '_popup' in request.REQUEST,
|
||||
'show_delete': show_delete,
|
||||
@ -345,9 +347,9 @@ def change_stage(request, app_label, model_name, object_id):
|
||||
change_message = ' '.join(change_message)
|
||||
if not change_message:
|
||||
change_message = _('No fields changed.')
|
||||
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), CHANGE, change_message)
|
||||
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, force_unicode(new_object), CHANGE, change_message)
|
||||
|
||||
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
|
||||
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)}
|
||||
if "_continue" in request.POST:
|
||||
request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
|
||||
if '_popup' in request.REQUEST:
|
||||
@ -355,10 +357,10 @@ def change_stage(request, app_label, model_name, object_id):
|
||||
else:
|
||||
return HttpResponseRedirect(request.path)
|
||||
elif "_saveasnew" in request.POST:
|
||||
request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
|
||||
request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)})
|
||||
return HttpResponseRedirect("../%s/" % pk_value)
|
||||
elif "_addanother" in request.POST:
|
||||
request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
|
||||
request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
||||
return HttpResponseRedirect("../add/")
|
||||
else:
|
||||
request.user.message_set.create(message=msg)
|
||||
@ -393,7 +395,7 @@ def change_stage(request, app_label, model_name, object_id):
|
||||
form.order_objects.extend(orig_list)
|
||||
|
||||
c = template.RequestContext(request, {
|
||||
'title': _('Change %s') % opts.verbose_name,
|
||||
'title': _('Change %s') % force_unicode(opts.verbose_name),
|
||||
'form': form,
|
||||
'object_id': object_id,
|
||||
'original': manipulator.original_object,
|
||||
@ -434,11 +436,11 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
|
||||
if related.field.rel.edit_inline or not related.opts.admin:
|
||||
# Don't display link to edit, because it either has no
|
||||
# admin or is edited inline.
|
||||
nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), sub_obj), []])
|
||||
nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
|
||||
else:
|
||||
# Display a link to the admin page.
|
||||
nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
|
||||
(capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(),
|
||||
nh(deleted_objects, current_depth, [u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
|
||||
(force_unicode(capfirst(related.opts.verbose_name)), related.opts.app_label, related.opts.object_name.lower(),
|
||||
sub_obj._get_pk_val(), sub_obj), []])
|
||||
_get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)
|
||||
else:
|
||||
@ -448,11 +450,11 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
|
||||
if related.field.rel.edit_inline or not related.opts.admin:
|
||||
# Don't display link to edit, because it either has no
|
||||
# admin or is edited inline.
|
||||
nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), escape(str(sub_obj))), []])
|
||||
nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), escape(sub_obj)), []])
|
||||
else:
|
||||
# Display a link to the admin page.
|
||||
nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
|
||||
(capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(str(sub_obj))), []])
|
||||
nh(deleted_objects, current_depth, [u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
|
||||
(force_unicode(capfirst(related.opts.verbose_name)), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(sub_obj)), []])
|
||||
_get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)
|
||||
# If there were related objects, and the user doesn't have
|
||||
# permission to delete them, add the missing perm to perms_needed.
|
||||
@ -479,17 +481,17 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
|
||||
# Don't display link to edit, because it either has no
|
||||
# admin or is edited inline.
|
||||
nh(deleted_objects, current_depth, [_('One or more %(fieldname)s in %(name)s: %(obj)s') % \
|
||||
{'fieldname': related.field.verbose_name, 'name': related.opts.verbose_name, 'obj': escape(str(sub_obj))}, []])
|
||||
{'fieldname': force_unicode(related.field.verbose_name), 'name': force_unicode(related.opts.verbose_name), 'obj': escape(sub_obj)}, []])
|
||||
else:
|
||||
# Display a link to the admin page.
|
||||
nh(deleted_objects, current_depth, [
|
||||
(_('One or more %(fieldname)s in %(name)s:') % {'fieldname': related.field.verbose_name, 'name':related.opts.verbose_name}) + \
|
||||
(' <a href="../../../../%s/%s/%s/">%s</a>' % \
|
||||
(related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(str(sub_obj)))), []])
|
||||
(_('One or more %(fieldname)s in %(name)s:') % {'fieldname': force_unicode(related.field.verbose_name), 'name': force_unicode(related.opts.verbose_name)}) + \
|
||||
(u' <a href="../../../../%s/%s/%s/">%s</a>' % \
|
||||
(related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(sub_obj))), []])
|
||||
# If there were related objects, and the user doesn't have
|
||||
# permission to change them, add the missing perm to perms_needed.
|
||||
if related.opts.admin and has_related_objs:
|
||||
p = '%s.%s' % (related.opts.app_label, related.opts.get_change_permission())
|
||||
p = u'%s.%s' % (related.opts.app_label, related.opts.get_change_permission())
|
||||
if not user.has_perm(p):
|
||||
perms_needed.add(related.opts.verbose_name)
|
||||
|
||||
@ -505,21 +507,21 @@ def delete_stage(request, app_label, model_name, object_id):
|
||||
|
||||
# Populate deleted_objects, a data structure of all related objects that
|
||||
# will also be deleted.
|
||||
deleted_objects = ['%s: <a href="../../%s/">%s</a>' % (capfirst(opts.verbose_name), object_id, escape(str(obj))), []]
|
||||
deleted_objects = [u'%s: <a href="../../%s/">%s</a>' % (force_unicode(capfirst(opts.verbose_name)), force_unicode(object_id), escape(obj)), []]
|
||||
perms_needed = set()
|
||||
_get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1)
|
||||
|
||||
if request.POST: # The user has already confirmed the deletion.
|
||||
if perms_needed:
|
||||
raise PermissionDenied
|
||||
obj_display = str(obj)
|
||||
obj_display = force_unicode(obj)
|
||||
obj.delete()
|
||||
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, object_id, obj_display, DELETION)
|
||||
request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': opts.verbose_name, 'obj': obj_display})
|
||||
request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': obj_display})
|
||||
return HttpResponseRedirect("../../")
|
||||
extra_context = {
|
||||
"title": _("Are you sure?"),
|
||||
"object_name": opts.verbose_name,
|
||||
"object_name": force_unicode(opts.verbose_name),
|
||||
"object": obj,
|
||||
"deleted_objects": deleted_objects,
|
||||
"perms_lacking": perms_needed,
|
||||
@ -542,7 +544,7 @@ def history(request, app_label, model_name, object_id):
|
||||
extra_context = {
|
||||
'title': _('Change history: %s') % obj,
|
||||
'action_list': action_list,
|
||||
'module_name': capfirst(model._meta.verbose_name_plural),
|
||||
'module_name': force_unicode(capfirst(model._meta.verbose_name_plural)),
|
||||
'object': obj,
|
||||
}
|
||||
return render_to_response(["admin/%s/%s/object_history.html" % (app_label, model._meta.object_name.lower()),
|
||||
@ -574,7 +576,7 @@ class ChangeList(object):
|
||||
self.query = request.GET.get(SEARCH_VAR, '')
|
||||
self.query_set = self.get_query_set()
|
||||
self.get_results(request)
|
||||
self.title = (self.is_popup and _('Select %s') % self.opts.verbose_name or _('Select %s to change') % self.opts.verbose_name)
|
||||
self.title = (self.is_popup and _('Select %s') % force_unicode(self.opts.verbose_name) or _('Select %s to change') % force_unicode(self.opts.verbose_name))
|
||||
self.filter_specs, self.has_filters = self.get_filters(request)
|
||||
self.pk_attname = self.lookup_opts.pk.attname
|
||||
|
||||
@ -602,7 +604,7 @@ class ChangeList(object):
|
||||
del p[k]
|
||||
elif v is not None:
|
||||
p[k] = v
|
||||
return '?' + '&'.join(['%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20')
|
||||
return '?' + '&'.join([u'%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20')
|
||||
|
||||
def get_results(self, request):
|
||||
paginator = ObjectPaginator(self.query_set, self.lookup_opts.admin.list_per_page)
|
||||
@ -671,7 +673,7 @@ class ChangeList(object):
|
||||
try:
|
||||
attr = getattr(lookup_opts.admin.manager.model, field_name)
|
||||
order_field = attr.admin_order_field
|
||||
except IndexError:
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
if not isinstance(f.rel, models.ManyToOneRel) or not f.null:
|
||||
@ -688,6 +690,12 @@ class ChangeList(object):
|
||||
for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR):
|
||||
if i in lookup_params:
|
||||
del lookup_params[i]
|
||||
for key, value in lookup_params.items():
|
||||
if not isinstance(key, str):
|
||||
# 'key' will be used as a keyword argument later, so Python
|
||||
# requires it to be a string.
|
||||
del lookup_params[key]
|
||||
lookup_params[smart_str(key)] = value
|
||||
|
||||
# Apply lookup parameters from the query string.
|
||||
qs = qs.filter(**lookup_params)
|
||||
|
@ -12,6 +12,8 @@ def load_backend(path):
|
||||
mod = __import__(module, {}, {}, [attr])
|
||||
except ImportError, e:
|
||||
raise ImproperlyConfigured, 'Error importing authentication backend %s: "%s"' % (module, e)
|
||||
except ValueError, e:
|
||||
raise ImproperlyConfigured, 'Error importing authentication backends. Is AUTHENTICATION_BACKENDS a correctly defined list or tuple?'
|
||||
try:
|
||||
cls = getattr(mod, attr)
|
||||
except AttributeError:
|
||||
|
@ -4,16 +4,16 @@ from django.contrib.sites.models import Site
|
||||
from django.template import Context, loader
|
||||
from django.core import validators
|
||||
from django import oldforms
|
||||
from django.utils.translation import gettext as _
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
class UserCreationForm(oldforms.Manipulator):
|
||||
"A form that creates a user, with no privileges, from the given username and password."
|
||||
def __init__(self):
|
||||
self.fields = (
|
||||
oldforms.TextField(field_name='username', length=30, maxlength=30, is_required=True,
|
||||
oldforms.TextField(field_name='username', length=30, max_length=30, is_required=True,
|
||||
validator_list=[validators.isAlphaNumeric, self.isValidUsername]),
|
||||
oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
|
||||
oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
|
||||
oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True),
|
||||
oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True,
|
||||
validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
|
||||
)
|
||||
|
||||
@ -42,9 +42,9 @@ class AuthenticationForm(oldforms.Manipulator):
|
||||
"""
|
||||
self.request = request
|
||||
self.fields = [
|
||||
oldforms.TextField(field_name="username", length=15, maxlength=30, is_required=True,
|
||||
oldforms.TextField(field_name="username", length=15, max_length=30, is_required=True,
|
||||
validator_list=[self.isValidUser, self.hasCookiesEnabled]),
|
||||
oldforms.PasswordField(field_name="password", length=15, maxlength=30, is_required=True),
|
||||
oldforms.PasswordField(field_name="password", length=15, max_length=30, is_required=True),
|
||||
]
|
||||
self.user_cache = None
|
||||
|
||||
@ -111,11 +111,11 @@ class PasswordChangeForm(oldforms.Manipulator):
|
||||
def __init__(self, user):
|
||||
self.user = user
|
||||
self.fields = (
|
||||
oldforms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True,
|
||||
oldforms.PasswordField(field_name="old_password", length=30, max_length=30, is_required=True,
|
||||
validator_list=[self.isValidOldPassword]),
|
||||
oldforms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True,
|
||||
oldforms.PasswordField(field_name="new_password1", length=30, max_length=30, is_required=True,
|
||||
validator_list=[validators.AlwaysMatchesOtherField('new_password2', _("The two 'new password' fields didn't match."))]),
|
||||
oldforms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True),
|
||||
oldforms.PasswordField(field_name="new_password2", length=30, max_length=30, is_required=True),
|
||||
)
|
||||
|
||||
def isValidOldPassword(self, new_data, all_data):
|
||||
@ -133,8 +133,8 @@ class AdminPasswordChangeForm(oldforms.Manipulator):
|
||||
def __init__(self, user):
|
||||
self.user = user
|
||||
self.fields = (
|
||||
oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
|
||||
oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
|
||||
oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True),
|
||||
oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True,
|
||||
validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
|
||||
)
|
||||
|
||||
|
@ -7,13 +7,13 @@ from django.db.models import get_models, signals
|
||||
from django.contrib.auth import models as auth_app
|
||||
|
||||
def _get_permission_codename(action, opts):
|
||||
return '%s_%s' % (action, opts.object_name.lower())
|
||||
return u'%s_%s' % (action, opts.object_name.lower())
|
||||
|
||||
def _get_all_permissions(opts):
|
||||
"Returns (codename, name) for all permissions in the given opts."
|
||||
perms = []
|
||||
for action in ('add', 'change', 'delete'):
|
||||
perms.append((_get_permission_codename(action, opts), 'Can %s %s' % (action, opts.verbose_name)))
|
||||
perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
|
||||
return perms + list(opts.permissions)
|
||||
|
||||
def create_permissions(app, created_models, verbosity):
|
||||
|
@ -1,9 +1,13 @@
|
||||
from django.core import validators
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import backend, connection, models
|
||||
from django.db import connection, models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.encoding import smart_str
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import datetime
|
||||
import urllib
|
||||
|
||||
UNUSABLE_PASSWORD = '!' # This will never be a valid hash
|
||||
|
||||
try:
|
||||
set
|
||||
@ -18,16 +22,16 @@ def check_password(raw_password, enc_password):
|
||||
algo, salt, hsh = enc_password.split('$')
|
||||
if algo == 'md5':
|
||||
import md5
|
||||
return hsh == md5.new(salt+raw_password).hexdigest()
|
||||
return hsh == md5.new(smart_str(salt + raw_password)).hexdigest()
|
||||
elif algo == 'sha1':
|
||||
import sha
|
||||
return hsh == sha.new(salt+raw_password).hexdigest()
|
||||
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(raw_password, salt)
|
||||
return hsh == crypt.crypt(smart_str(raw_password), smart_str(salt))
|
||||
raise ValueError, "Got unknown password algorithm type in password."
|
||||
|
||||
class SiteProfileNotAvailable(Exception):
|
||||
@ -46,9 +50,9 @@ class Permission(models.Model):
|
||||
|
||||
Three basic permissions -- add, change and delete -- are automatically created for each Django model.
|
||||
"""
|
||||
name = models.CharField(_('name'), maxlength=50)
|
||||
name = models.CharField(_('name'), max_length=50)
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
codename = models.CharField(_('codename'), maxlength=100)
|
||||
codename = models.CharField(_('codename'), max_length=100)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('permission')
|
||||
@ -56,8 +60,8 @@ class Permission(models.Model):
|
||||
unique_together = (('content_type', 'codename'),)
|
||||
ordering = ('content_type', 'codename')
|
||||
|
||||
def __str__(self):
|
||||
return "%s | %s | %s" % (self.content_type.app_label, self.content_type, self.name)
|
||||
def __unicode__(self):
|
||||
return u"%s | %s | %s" % (self.content_type.app_label, self.content_type, self.name)
|
||||
|
||||
class Group(models.Model):
|
||||
"""Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
|
||||
@ -66,7 +70,7 @@ class Group(models.Model):
|
||||
|
||||
Beyond permissions, groups are a convenient way to categorize users to apply some label, or extended functionality, to them. For example, you could create a group 'Special users', and you could write code that would do special things to those users -- such as giving them access to a members-only portion of your site, or sending them members-only e-mail messages.
|
||||
"""
|
||||
name = models.CharField(_('name'), maxlength=80, unique=True)
|
||||
name = models.CharField(_('name'), max_length=80, unique=True)
|
||||
permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL)
|
||||
|
||||
class Meta:
|
||||
@ -77,15 +81,18 @@ class Group(models.Model):
|
||||
class Admin:
|
||||
search_fields = ('name',)
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class UserManager(models.Manager):
|
||||
def create_user(self, username, email, password):
|
||||
def create_user(self, username, email, password=None):
|
||||
"Creates and saves a User with the given username, e-mail and password."
|
||||
now = datetime.datetime.now()
|
||||
user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now)
|
||||
user.set_password(password)
|
||||
if password:
|
||||
user.set_password(password)
|
||||
else:
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
return user
|
||||
|
||||
@ -101,11 +108,11 @@ class User(models.Model):
|
||||
|
||||
Username and password are required. Other fields are optional.
|
||||
"""
|
||||
username = models.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric], help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
|
||||
first_name = models.CharField(_('first name'), maxlength=30, blank=True)
|
||||
last_name = models.CharField(_('last name'), maxlength=30, blank=True)
|
||||
username = models.CharField(_('username'), max_length=30, unique=True, validator_list=[validators.isAlphaNumeric], help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
|
||||
first_name = models.CharField(_('first name'), max_length=30, blank=True)
|
||||
last_name = models.CharField(_('last name'), max_length=30, blank=True)
|
||||
email = models.EmailField(_('e-mail address'), blank=True)
|
||||
password = models.CharField(_('password'), maxlength=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
|
||||
password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
|
||||
is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site."))
|
||||
is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts."))
|
||||
is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))
|
||||
@ -133,11 +140,11 @@ class User(models.Model):
|
||||
list_filter = ('is_staff', 'is_superuser')
|
||||
search_fields = ('username', 'first_name', 'last_name', 'email')
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.username
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "/users/%s/" % self.username
|
||||
return "/users/%s/" % urllib.quote(smart_str(self.username))
|
||||
|
||||
def is_anonymous(self):
|
||||
"Always returns False. This is a way of comparing User objects to anonymous users."
|
||||
@ -150,14 +157,14 @@ class User(models.Model):
|
||||
|
||||
def get_full_name(self):
|
||||
"Returns the first_name plus the last_name, with a space in between."
|
||||
full_name = '%s %s' % (self.first_name, self.last_name)
|
||||
full_name = u'%s %s' % (self.first_name, self.last_name)
|
||||
return full_name.strip()
|
||||
|
||||
def set_password(self, raw_password):
|
||||
import sha, random
|
||||
algo = 'sha1'
|
||||
salt = sha.new(str(random.random())).hexdigest()[:5]
|
||||
hsh = sha.new(salt+raw_password).hexdigest()
|
||||
hsh = sha.new(salt + smart_str(raw_password)).hexdigest()
|
||||
self.password = '%s$%s$%s' % (algo, salt, hsh)
|
||||
|
||||
def check_password(self, raw_password):
|
||||
@ -169,7 +176,7 @@ class User(models.Model):
|
||||
# algorithm or salt.
|
||||
if '$' not in self.password:
|
||||
import md5
|
||||
is_correct = (self.password == md5.new(raw_password).hexdigest())
|
||||
is_correct = (self.password == md5.new(smart_str(raw_password)).hexdigest())
|
||||
if is_correct:
|
||||
# Convert the password to the new, more secure format.
|
||||
self.set_password(raw_password)
|
||||
@ -177,6 +184,13 @@ class User(models.Model):
|
||||
return is_correct
|
||||
return check_password(raw_password, self.password)
|
||||
|
||||
def set_unusable_password(self):
|
||||
# Sets a value that will never be a valid hash
|
||||
self.password = UNUSABLE_PASSWORD
|
||||
|
||||
def has_usable_password(self):
|
||||
return self.password != UNUSABLE_PASSWORD
|
||||
|
||||
def get_group_permissions(self):
|
||||
"Returns a list of permission strings that this user has through his/her groups."
|
||||
if not hasattr(self, '_group_perm_cache'):
|
||||
@ -189,6 +203,7 @@ class User(models.Model):
|
||||
# AND gp."group_id" = ug."group_id"
|
||||
# AND ct."id" = p."content_type_id"
|
||||
# AND ug."user_id" = %s, [self.id])
|
||||
qn = connection.ops.quote_name
|
||||
sql = """
|
||||
SELECT ct.%s, p.%s
|
||||
FROM %s p, %s gp, %s ug, %s ct
|
||||
@ -196,20 +211,20 @@ class User(models.Model):
|
||||
AND gp.%s = ug.%s
|
||||
AND ct.%s = p.%s
|
||||
AND ug.%s = %%s""" % (
|
||||
backend.quote_name('app_label'), backend.quote_name('codename'),
|
||||
backend.quote_name('auth_permission'), backend.quote_name('auth_group_permissions'),
|
||||
backend.quote_name('auth_user_groups'), backend.quote_name('django_content_type'),
|
||||
backend.quote_name('id'), backend.quote_name('permission_id'),
|
||||
backend.quote_name('group_id'), backend.quote_name('group_id'),
|
||||
backend.quote_name('id'), backend.quote_name('content_type_id'),
|
||||
backend.quote_name('user_id'),)
|
||||
qn('app_label'), qn('codename'),
|
||||
qn('auth_permission'), qn('auth_group_permissions'),
|
||||
qn('auth_user_groups'), qn('django_content_type'),
|
||||
qn('id'), qn('permission_id'),
|
||||
qn('group_id'), qn('group_id'),
|
||||
qn('id'), qn('content_type_id'),
|
||||
qn('user_id'),)
|
||||
cursor.execute(sql, [self.id])
|
||||
self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
|
||||
return self._group_perm_cache
|
||||
|
||||
def get_all_permissions(self):
|
||||
if not hasattr(self, '_perm_cache'):
|
||||
self._perm_cache = set(["%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()])
|
||||
self._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()])
|
||||
self._perm_cache.update(self.get_group_permissions())
|
||||
return self._perm_cache
|
||||
|
||||
@ -266,12 +281,13 @@ class User(models.Model):
|
||||
return self._profile_cache
|
||||
|
||||
class Message(models.Model):
|
||||
"""The message system is a lightweight way to queue messages for given users. A message is associated with a User instance (so it is only applicable for registered users). There's no concept of expiration or timestamps. Messages are created by the Django admin after successful actions. For example, "The poll Foo was created successfully." is a message.
|
||||
"""
|
||||
The message system is a lightweight way to queue messages for given users. A message is associated with a User instance (so it is only applicable for registered users). There's no concept of expiration or timestamps. Messages are created by the Django admin after successful actions. For example, "The poll Foo was created successfully." is a message.
|
||||
"""
|
||||
user = models.ForeignKey(User)
|
||||
message = models.TextField(_('message'))
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.message
|
||||
|
||||
class AnonymousUser(object):
|
||||
@ -281,8 +297,11 @@ class AnonymousUser(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __unicode__(self):
|
||||
return 'AnonymousUser'
|
||||
|
||||
def __str__(self):
|
||||
return _('AnonymousUser')
|
||||
return unicode(self).encode('utf-8')
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__)
|
||||
|
19
django/contrib/auth/tests.py
Normal file
19
django/contrib/auth/tests.py
Normal file
@ -0,0 +1,19 @@
|
||||
"""
|
||||
>>> from models import User
|
||||
>>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw')
|
||||
>>> u.has_usable_password()
|
||||
True
|
||||
>>> u.check_password('bad')
|
||||
False
|
||||
>>> u.check_password('testpw')
|
||||
True
|
||||
>>> u.set_unusable_password()
|
||||
>>> u.save()
|
||||
>>> u.check_password('testpw')
|
||||
False
|
||||
>>> u.has_usable_password()
|
||||
False
|
||||
>>> u2 = User.objects.create_user('testuser2', 'test2@example.com')
|
||||
>>> u2.has_usable_password()
|
||||
False
|
||||
"""
|
@ -3,10 +3,11 @@ from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm
|
||||
from django import oldforms
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.contrib.sites.models import Site
|
||||
from django.contrib.sites.models import Site, RequestSite
|
||||
from django.http import HttpResponseRedirect
|
||||
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'):
|
||||
"Displays the login form and handles the login action."
|
||||
@ -26,10 +27,16 @@ def login(request, template_name='registration/login.html'):
|
||||
else:
|
||||
errors = {}
|
||||
request.session.set_test_cookie()
|
||||
|
||||
if Site._meta.installed:
|
||||
current_site = Site.objects.get_current()
|
||||
else:
|
||||
current_site = RequestSite(request)
|
||||
|
||||
return render_to_response(template_name, {
|
||||
'form': oldforms.FormWrapper(manipulator, request.POST, errors),
|
||||
REDIRECT_FIELD_NAME: redirect_to,
|
||||
'site_name': Site.objects.get_current().name,
|
||||
'site_name': current_site.name,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def logout(request, next_page=None, template_name='registration/logged_out.html'):
|
||||
|
@ -11,7 +11,7 @@ class LatestFreeCommentsFeed(Feed):
|
||||
def title(self):
|
||||
if not hasattr(self, '_site'):
|
||||
self._site = Site.objects.get_current()
|
||||
return "%s comments" % self._site.name
|
||||
return u"%s comments" % self._site.name
|
||||
|
||||
def link(self):
|
||||
if not hasattr(self, '_site'):
|
||||
@ -21,7 +21,7 @@ class LatestFreeCommentsFeed(Feed):
|
||||
def description(self):
|
||||
if not hasattr(self, '_site'):
|
||||
self._site = Site.objects.get_current()
|
||||
return "Latest comments on %s" % self._site.name
|
||||
return u"Latest comments on %s" % self._site.name
|
||||
|
||||
def get_query_set(self):
|
||||
return self.comments_class.objects.filter(site__pk=settings.SITE_ID, is_public=True)
|
||||
|
@ -2,7 +2,7 @@ from django.db import models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.sites.models import Site
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
import datetime
|
||||
|
||||
@ -65,8 +65,8 @@ class Comment(models.Model):
|
||||
user = models.ForeignKey(User, raw_id_admin=True)
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
object_id = models.IntegerField(_('object ID'))
|
||||
headline = models.CharField(_('headline'), maxlength=255, blank=True)
|
||||
comment = models.TextField(_('comment'), maxlength=3000)
|
||||
headline = models.CharField(_('headline'), max_length=255, blank=True)
|
||||
comment = models.TextField(_('comment'), max_length=3000)
|
||||
rating1 = models.PositiveSmallIntegerField(_('rating #1'), blank=True, null=True)
|
||||
rating2 = models.PositiveSmallIntegerField(_('rating #2'), blank=True, null=True)
|
||||
rating3 = models.PositiveSmallIntegerField(_('rating #3'), blank=True, null=True)
|
||||
@ -106,7 +106,10 @@ class Comment(models.Model):
|
||||
return "%s: %s..." % (self.user.username, self.comment[:100])
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.get_content_object().get_absolute_url() + "#c" + str(self.id)
|
||||
try:
|
||||
return self.get_content_object().get_absolute_url() + "#c" + str(self.id)
|
||||
except AttributeError:
|
||||
return ""
|
||||
|
||||
def get_crossdomain_url(self):
|
||||
return "/r/%d/%d/" % (self.content_type_id, self.object_id)
|
||||
@ -164,8 +167,8 @@ class FreeComment(models.Model):
|
||||
# A FreeComment is a comment by a non-registered user.
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
object_id = models.IntegerField(_('object ID'))
|
||||
comment = models.TextField(_('comment'), maxlength=3000)
|
||||
person_name = models.CharField(_("person's name"), maxlength=50)
|
||||
comment = models.TextField(_('comment'), max_length=3000)
|
||||
person_name = models.CharField(_("person's name"), max_length=50)
|
||||
submit_date = models.DateTimeField(_('date/time submitted'), auto_now_add=True)
|
||||
is_public = models.BooleanField(_('is public'))
|
||||
ip_address = models.IPAddressField(_('ip address'))
|
||||
@ -191,7 +194,10 @@ class FreeComment(models.Model):
|
||||
return "%s: %s..." % (self.person_name, self.comment[:100])
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.get_content_object().get_absolute_url() + "#c" + str(self.id)
|
||||
try:
|
||||
return self.get_content_object().get_absolute_url() + "#c" + str(self.id)
|
||||
except AttributeError:
|
||||
return ""
|
||||
|
||||
def get_content_object(self):
|
||||
"""
|
||||
|
@ -5,6 +5,7 @@ from django import template
|
||||
from django.template import loader
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.encoding import smart_str
|
||||
import re
|
||||
|
||||
register = template.Library()
|
||||
@ -111,9 +112,9 @@ class CommentListNode(template.Node):
|
||||
'site__id__exact': settings.SITE_ID,
|
||||
}
|
||||
kwargs.update(self.extra_kwargs)
|
||||
if not self.free and settings.COMMENTS_BANNED_USERS_GROUP:
|
||||
kwargs['select'] = {'is_hidden': 'user_id IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)' % settings.COMMENTS_BANNED_USERS_GROUP}
|
||||
comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related()
|
||||
if not self.free and settings.COMMENTS_BANNED_USERS_GROUP:
|
||||
comment_list = comment_list.extra(select={'is_hidden': 'user_id IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)' % settings.COMMENTS_BANNED_USERS_GROUP})
|
||||
|
||||
if not self.free:
|
||||
if 'user' in context and context['user'].is_authenticated():
|
||||
@ -174,6 +175,7 @@ class DoCommentForm:
|
||||
if tokens[4] != 'with':
|
||||
raise template.TemplateSyntaxError, "Fourth argument in %r tag must be 'with'" % tokens[0]
|
||||
for option, args in zip(tokens[5::2], tokens[6::2]):
|
||||
option = smart_str(option)
|
||||
if option in ('photos_optional', 'photos_required') and not self.free:
|
||||
# VALIDATION ##############################################
|
||||
option_list = args.split(',')
|
||||
|
@ -11,7 +11,8 @@ from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.text import normalize_newlines
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ngettext
|
||||
from django.utils.translation import ungettext, ugettext as _
|
||||
from django.utils.encoding import smart_unicode
|
||||
import base64, datetime
|
||||
|
||||
COMMENTS_PER_PAGE = 20
|
||||
@ -28,7 +29,7 @@ class PublicCommentManipulator(AuthenticationForm):
|
||||
else:
|
||||
return []
|
||||
self.fields.extend([
|
||||
oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
|
||||
oldforms.LargeTextField(field_name="comment", max_length=3000, is_required=True,
|
||||
validator_list=[self.hasNoProfanities]),
|
||||
oldforms.RadioSelectField(field_name="rating1", choices=choices,
|
||||
is_required=ratings_required and num_rating_choices > 0,
|
||||
@ -108,11 +109,11 @@ class PublicCommentManipulator(AuthenticationForm):
|
||||
# If the commentor has posted fewer than COMMENTS_FIRST_FEW comments,
|
||||
# send the comment to the managers.
|
||||
if self.user_cache.comment_set.count() <= settings.COMMENTS_FIRST_FEW:
|
||||
message = ngettext('This comment was posted by a user who has posted fewer than %(count)s comment:\n\n%(text)s',
|
||||
message = ungettext('This comment was posted by a user who has posted fewer than %(count)s comment:\n\n%(text)s',
|
||||
'This comment was posted by a user who has posted fewer than %(count)s comments:\n\n%(text)s', settings.COMMENTS_FIRST_FEW) % \
|
||||
{'count': settings.COMMENTS_FIRST_FEW, 'text': c.get_as_text()}
|
||||
mail_managers("Comment posted by rookie user", message)
|
||||
if settings.COMMENTS_SKETCHY_USERS_GROUP and settings.COMMENTS_SKETCHY_USERS_GROUP in [g.id for g in self.user_cache.get_group_list()]:
|
||||
if settings.COMMENTS_SKETCHY_USERS_GROUP and settings.COMMENTS_SKETCHY_USERS_GROUP in [g.id for g in self.user_cache.groups.all()]:
|
||||
message = _('This comment was posted by a sketchy user:\n\n%(text)s') % {'text': c.get_as_text()}
|
||||
mail_managers("Comment posted by sketchy user (%s)" % self.user_cache.username, c.get_as_text())
|
||||
return c
|
||||
@ -121,9 +122,9 @@ class PublicFreeCommentManipulator(oldforms.Manipulator):
|
||||
"Manipulator that handles public free (unregistered) comments"
|
||||
def __init__(self):
|
||||
self.fields = (
|
||||
oldforms.TextField(field_name="person_name", maxlength=50, is_required=True,
|
||||
oldforms.TextField(field_name="person_name", max_length=50, is_required=True,
|
||||
validator_list=[self.hasNoProfanities]),
|
||||
oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
|
||||
oldforms.LargeTextField(field_name="comment", max_length=3000, is_required=True,
|
||||
validator_list=[self.hasNoProfanities]),
|
||||
)
|
||||
|
||||
@ -248,7 +249,7 @@ def post_comment(request):
|
||||
# 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.
|
||||
if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
|
||||
mail_admins("Banned IP attempted to post comment", str(request.POST) + "\n\n" + str(request.META))
|
||||
mail_admins("Banned IP attempted to post comment", smart_unicode(request.POST) + "\n\n" + str(request.META))
|
||||
else:
|
||||
manipulator.do_html2python(new_data)
|
||||
comment = manipulator.save(new_data)
|
||||
@ -312,7 +313,7 @@ def post_free_comment(request):
|
||||
# serve up the "Thanks for posting" page as if the comment WAS posted.
|
||||
if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
|
||||
from django.core.mail import mail_admins
|
||||
mail_admins("Practical joker", str(request.POST) + "\n\n" + str(request.META))
|
||||
mail_admins("Practical joker", smart_unicode(request.POST) + "\n\n" + str(request.META))
|
||||
else:
|
||||
manipulator.do_html2python(new_data)
|
||||
comment = manipulator.save(new_data)
|
||||
|
@ -2,6 +2,7 @@ from django.http import Http404
|
||||
from django.shortcuts import render_to_response
|
||||
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):
|
||||
"""
|
||||
|
@ -4,7 +4,7 @@ Classes allowing "generic" relations through ContentType and object-id fields.
|
||||
|
||||
from django import oldforms
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db import backend
|
||||
from django.db import connection
|
||||
from django.db.models import signals
|
||||
from django.db.models.fields.related import RelatedField, Field, ManyToManyRel
|
||||
from django.db.models.loading import get_model
|
||||
@ -49,7 +49,7 @@ class GenericForeignKey(object):
|
||||
|
||||
def __get__(self, instance, instance_type=None):
|
||||
if instance is None:
|
||||
raise AttributeError, "%s must be accessed via instance" % self.name
|
||||
raise AttributeError, u"%s must be accessed via instance" % self.name
|
||||
|
||||
try:
|
||||
return getattr(instance, self.cache_attr)
|
||||
@ -66,7 +66,7 @@ class GenericForeignKey(object):
|
||||
|
||||
def __set__(self, instance, value):
|
||||
if instance is None:
|
||||
raise AttributeError, "%s must be accessed via instance" % self.related.opts.object_name
|
||||
raise AttributeError, u"%s must be accessed via instance" % self.related.opts.object_name
|
||||
|
||||
ct = None
|
||||
fk = None
|
||||
@ -163,13 +163,15 @@ class ReverseGenericRelatedObjectsDescriptor(object):
|
||||
superclass = rel_model._default_manager.__class__
|
||||
RelatedManager = create_generic_related_manager(superclass)
|
||||
|
||||
qn = connection.ops.quote_name
|
||||
|
||||
manager = RelatedManager(
|
||||
model = rel_model,
|
||||
instance = instance,
|
||||
symmetrical = (self.field.rel.symmetrical and instance.__class__ == rel_model),
|
||||
join_table = backend.quote_name(self.field.m2m_db_table()),
|
||||
source_col_name = backend.quote_name(self.field.m2m_column_name()),
|
||||
target_col_name = backend.quote_name(self.field.m2m_reverse_name()),
|
||||
join_table = qn(self.field.m2m_db_table()),
|
||||
source_col_name = qn(self.field.m2m_column_name()),
|
||||
target_col_name = qn(self.field.m2m_reverse_name()),
|
||||
content_type = ContentType.objects.get_for_model(self.field.model),
|
||||
content_type_field_name = self.field.content_type_field_name,
|
||||
object_id_field_name = self.field.object_id_field_name
|
||||
|
@ -4,6 +4,7 @@ Creates content types for all installed models.
|
||||
|
||||
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
|
||||
@ -17,7 +18,7 @@ def create_contenttypes(app, created_models, verbosity=2):
|
||||
ContentType.objects.get(app_label=opts.app_label,
|
||||
model=opts.object_name.lower())
|
||||
except ContentType.DoesNotExist:
|
||||
ct = ContentType(name=str(opts.verbose_name),
|
||||
ct = ContentType(name=smart_unicode(opts.verbose_name_raw),
|
||||
app_label=opts.app_label, model=opts.object_name.lower())
|
||||
ct.save()
|
||||
if verbosity >= 2:
|
||||
|
@ -1,5 +1,6 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import smart_unicode
|
||||
|
||||
CONTENT_TYPE_CACHE = {}
|
||||
class ContentTypeManager(models.Manager):
|
||||
@ -13,10 +14,10 @@ class ContentTypeManager(models.Manager):
|
||||
try:
|
||||
ct = CONTENT_TYPE_CACHE[key]
|
||||
except KeyError:
|
||||
# The str() is needed around opts.verbose_name because it's a
|
||||
# django.utils.functional.__proxy__ object.
|
||||
# The smart_unicode() is needed around opts.verbose_name_raw because it might
|
||||
# be a django.utils.functional.__proxy__ object.
|
||||
ct, created = self.model._default_manager.get_or_create(app_label=key[0],
|
||||
model=key[1], defaults={'name': str(opts.verbose_name)})
|
||||
model=key[1], defaults={'name': smart_unicode(opts.verbose_name_raw)})
|
||||
CONTENT_TYPE_CACHE[key] = ct
|
||||
return ct
|
||||
|
||||
@ -31,9 +32,9 @@ class ContentTypeManager(models.Manager):
|
||||
CONTENT_TYPE_CACHE = {}
|
||||
|
||||
class ContentType(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
app_label = models.CharField(maxlength=100)
|
||||
model = models.CharField(_('python model class name'), maxlength=100)
|
||||
name = models.CharField(max_length=100)
|
||||
app_label = models.CharField(max_length=100)
|
||||
model = models.CharField(_('python model class name'), max_length=100)
|
||||
objects = ContentTypeManager()
|
||||
class Meta:
|
||||
verbose_name = _('content type')
|
||||
@ -42,7 +43,7 @@ class ContentType(models.Model):
|
||||
ordering = ('name',)
|
||||
unique_together = (('app_label', 'model'),)
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def model_class(self):
|
||||
|
@ -7,6 +7,8 @@ from django.db import models
|
||||
from django.utils import dateformat
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import get_date_formats
|
||||
from django.utils.encoding import smart_unicode, smart_str, iri_to_uri
|
||||
from django.db.models.query import QuerySet
|
||||
|
||||
EMPTY_VALUE = '(None)'
|
||||
|
||||
@ -19,7 +21,7 @@ class EasyModel(object):
|
||||
self.verbose_name_plural = model._meta.verbose_name_plural
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyModel for %s>' % self.model._meta.object_name
|
||||
return '<EasyModel for %s>' % smart_str(self.model._meta.object_name)
|
||||
|
||||
def model_databrowse(self):
|
||||
"Returns the ModelDatabrowse class for this model."
|
||||
@ -29,8 +31,12 @@ class EasyModel(object):
|
||||
return '%s%s/%s/' % (self.site.root_url, self.model._meta.app_label, self.model._meta.module_name)
|
||||
|
||||
def objects(self, **kwargs):
|
||||
for obj in self.model._default_manager.filter(**kwargs):
|
||||
yield EasyInstance(self, obj)
|
||||
return self.get_query_set().filter(**kwargs)
|
||||
|
||||
def get_query_set(self):
|
||||
easy_qs = self.model._default_manager.get_query_set()._clone(klass=EasyQuerySet)
|
||||
easy_qs._easymodel = self
|
||||
return easy_qs
|
||||
|
||||
def object_by_pk(self, pk):
|
||||
return EasyInstance(self, self.model._default_manager.get(pk=pk))
|
||||
@ -54,7 +60,7 @@ class EasyField(object):
|
||||
self.model, self.field = easy_model, field
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
|
||||
return smart_str(u'<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
|
||||
|
||||
def choices(self):
|
||||
for value, label in self.field.choices:
|
||||
@ -72,29 +78,32 @@ class EasyChoice(object):
|
||||
self.value, self.label = value, label
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
|
||||
return smart_str(u'<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
|
||||
|
||||
def url(self):
|
||||
return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, self.value)
|
||||
return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value))
|
||||
|
||||
class EasyInstance(object):
|
||||
def __init__(self, easy_model, instance):
|
||||
self.model, self.instance = easy_model, instance
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val())
|
||||
return smart_str(u'<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val()))
|
||||
|
||||
def __unicode__(self):
|
||||
val = smart_unicode(self.instance)
|
||||
if len(val) > 30:
|
||||
return val[:30] + u'...'
|
||||
return val
|
||||
|
||||
def __str__(self):
|
||||
val = str(self.instance)
|
||||
if len(val) > 30:
|
||||
return val[:30] + '...'
|
||||
return val
|
||||
return self.__unicode__().encode('utf-8')
|
||||
|
||||
def pk(self):
|
||||
return self.instance._get_pk_val()
|
||||
|
||||
def url(self):
|
||||
return '%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.pk())
|
||||
return '%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, iri_to_uri(self.pk()))
|
||||
|
||||
def fields(self):
|
||||
"""
|
||||
@ -126,7 +135,7 @@ class EasyInstanceField(object):
|
||||
self.raw_value = getattr(instance.instance, field.name)
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
|
||||
return smart_str(u'<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
|
||||
|
||||
def values(self):
|
||||
"""
|
||||
@ -175,18 +184,32 @@ class EasyInstanceField(object):
|
||||
if self.field.rel.to in self.model.model_list:
|
||||
lst = []
|
||||
for value in self.values():
|
||||
url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, value._get_pk_val())
|
||||
lst.append((str(value), url))
|
||||
url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val()))
|
||||
lst.append((smart_unicode(value), url))
|
||||
else:
|
||||
lst = [(value, None) for value in self.values()]
|
||||
elif self.field.choices:
|
||||
lst = []
|
||||
for value in self.values():
|
||||
url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, self.raw_value)
|
||||
url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value))
|
||||
lst.append((value, url))
|
||||
elif isinstance(self.field, models.URLField):
|
||||
val = self.values()[0]
|
||||
lst = [(val, val)]
|
||||
lst = [(val, iri_to_uri(val))]
|
||||
else:
|
||||
lst = [(self.values()[0], None)]
|
||||
return lst
|
||||
|
||||
class EasyQuerySet(QuerySet):
|
||||
"""
|
||||
When creating (or cloning to) an `EasyQuerySet`, make sure to set the
|
||||
`_easymodel` variable to the related `EasyModel`.
|
||||
"""
|
||||
def iterator(self, *args, **kwargs):
|
||||
for obj in super(EasyQuerySet, self).iterator(*args, **kwargs):
|
||||
yield EasyInstance(self._easymodel, obj)
|
||||
|
||||
def _clone(self, *args, **kwargs):
|
||||
c = super(EasyQuerySet, self)._clone(*args, **kwargs)
|
||||
c._easymodel = self._easymodel
|
||||
return c
|
||||
|
@ -6,6 +6,7 @@ from django.shortcuts import render_to_response
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import get_date_formats
|
||||
from django.views.generic import date_based
|
||||
from django.utils.encoding import force_unicode
|
||||
import datetime
|
||||
import time
|
||||
|
||||
@ -27,13 +28,13 @@ class CalendarPlugin(DatabrowsePlugin):
|
||||
def model_index_html(self, request, model, site):
|
||||
fields = self.field_dict(model)
|
||||
if not fields:
|
||||
return ''
|
||||
return '<p class="filter"><strong>View calendar by:</strong> %s</p>' % \
|
||||
', '.join(['<a href="calendars/%s/">%s</a>' % (f.name, capfirst(f.verbose_name)) for f in fields.values()])
|
||||
return u''
|
||||
return u'<p class="filter"><strong>View calendar by:</strong> %s</p>' % \
|
||||
u', '.join(['<a href="calendars/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()])
|
||||
|
||||
def urls(self, plugin_name, easy_instance_field):
|
||||
if isinstance(easy_instance_field.field, models.DateField):
|
||||
return ['%s%s/%s/%s/%s/%s/' % (easy_instance_field.model.url(),
|
||||
return [u'%s%s/%s/%s/%s/%s/' % (easy_instance_field.model.url(),
|
||||
plugin_name, easy_instance_field.field.name,
|
||||
easy_instance_field.raw_value.year,
|
||||
easy_instance_field.raw_value.strftime('%b').lower(),
|
||||
@ -63,22 +64,22 @@ class CalendarPlugin(DatabrowsePlugin):
|
||||
|
||||
def calendar_view(self, request, field, year=None, month=None, day=None):
|
||||
easy_model = EasyModel(self.site, self.model)
|
||||
queryset = easy_model.get_query_set()
|
||||
extra_context = {'root_url': self.site.root_url, 'model': easy_model, 'field': field}
|
||||
if day is not None:
|
||||
# TODO: The objects in this template should be EasyInstances
|
||||
return date_based.archive_day(request, year, month, day, self.model.objects.all(), field.name,
|
||||
return date_based.archive_day(request, year, month, day, queryset, field.name,
|
||||
template_name='databrowse/calendar_day.html', allow_empty=False, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
elif month is not None:
|
||||
return date_based.archive_month(request, year, month, self.model.objects.all(), field.name,
|
||||
return date_based.archive_month(request, year, month, queryset, field.name,
|
||||
template_name='databrowse/calendar_month.html', allow_empty=False, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
elif year is not None:
|
||||
return date_based.archive_year(request, year, self.model.objects.all(), field.name,
|
||||
return date_based.archive_year(request, year, queryset, field.name,
|
||||
template_name='databrowse/calendar_year.html', allow_empty=False, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
else:
|
||||
return date_based.archive_index(request, self.model.objects.all(), field.name,
|
||||
return date_based.archive_index(request, queryset, field.name,
|
||||
template_name='databrowse/calendar_main.html', allow_empty=True, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
assert False, ('%s, %s, %s, %s' % (field, year, month, day))
|
||||
|
@ -4,9 +4,11 @@ from django.contrib.databrowse.datastructures import EasyModel
|
||||
from django.contrib.databrowse.sites import DatabrowsePlugin
|
||||
from django.shortcuts import render_to_response
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.encoding import smart_str, force_unicode
|
||||
from django.views.generic import date_based
|
||||
import datetime
|
||||
import time
|
||||
import urllib
|
||||
|
||||
class FieldChoicePlugin(DatabrowsePlugin):
|
||||
def __init__(self, field_filter=None):
|
||||
@ -29,15 +31,16 @@ class FieldChoicePlugin(DatabrowsePlugin):
|
||||
def model_index_html(self, request, model, site):
|
||||
fields = self.field_dict(model)
|
||||
if not fields:
|
||||
return ''
|
||||
return '<p class="filter"><strong>View by:</strong> %s</p>' % \
|
||||
', '.join(['<a href="fields/%s/">%s</a>' % (f.name, capfirst(f.verbose_name)) for f in fields.values()])
|
||||
return u''
|
||||
return u'<p class="filter"><strong>View by:</strong> %s</p>' % \
|
||||
u', '.join(['<a href="fields/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()])
|
||||
|
||||
def urls(self, plugin_name, easy_instance_field):
|
||||
if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values():
|
||||
return ['%s%s/%s/%s/' % (easy_instance_field.model.url(),
|
||||
field_value = smart_str(easy_instance_field.raw_value)
|
||||
return [u'%s%s/%s/%s/' % (easy_instance_field.model.url(),
|
||||
plugin_name, easy_instance_field.field.name,
|
||||
easy_instance_field.raw_value)]
|
||||
urllib.quote(field_value, safe=''))]
|
||||
|
||||
def model_view(self, request, model_databrowse, url):
|
||||
self.model, self.site = model_databrowse.model, model_databrowse.site
|
||||
|
@ -60,7 +60,7 @@ class ModelDatabrowse(object):
|
||||
|
||||
def main_view(self, request):
|
||||
easy_model = EasyModel(self.site, self.model)
|
||||
html_snippets = '\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()])
|
||||
html_snippets = u'\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()])
|
||||
return render_to_response('databrowse/model_detail.html', {
|
||||
'model': easy_model,
|
||||
'root_url': self.site.root_url,
|
||||
|
@ -2,6 +2,7 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
{% block style %}
|
||||
<style type="text/css">
|
||||
* { margin:0; padding:0; }
|
||||
body { background:#eee; color:#333; font:76%/1.6 "Lucida Grande","Bitstream Vera Sans",Verdana,sans-serif; }
|
||||
@ -48,9 +49,11 @@ p { margin:0.5em 0 1em 0; }
|
||||
/* CONTENT */
|
||||
#content { background:#fff; border-bottom:1px solid #ddd; padding:0 20px; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block extrahead %}{% endblock %}
|
||||
</head>
|
||||
<body id="{% block bodyid %}page{% endblock %}">
|
||||
<div id="header"><a href="{{ root_url }}">Databrowse</a></div>
|
||||
<div id="header"><a href="{{ root_url }}">{% block databrowse_title %}Databrowse{% endblock %}</a></div>
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
@ -0,0 +1 @@
|
||||
{% extends "databrowse/base.html" %}
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} {{ day|date:"F j, Y" }}{% endblock %}
|
||||
|
||||
@ -6,11 +6,11 @@
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../../../../">Calendars</a> / <a href="../../../">By {{ field.verbose_name }}</a> / <a href="../../">{{ day.year }}</a> / <a href="../">{{ day|date:"F" }}</a> / {{ day.day }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} on {{ day|date:"F j, Y" }}</h1>
|
||||
<h1>{{ object_list.count }} {% if object_list.count|pluralize %}{{ model.verbose_name_plural|escape }}{% else %}{{ model.verbose_name|escape }}{% endif %} with {{ field.verbose_name }} on {{ day|date:"F j, Y" }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}Calendars{% endblock %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ field.verbose_name|capfirst }} calendar{% endblock %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} in {{ month|date:"F Y" }}{% endblock %}
|
||||
|
||||
@ -6,11 +6,11 @@
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../../../">Calendars</a> / <a href="../../">By {{ field.verbose_name }}</a> / <a href="../">{{ month.year }}</a> / {{ month|date:"F" }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} in {{ month|date:"F Y" }}</h1>
|
||||
<h1>{{ object_list.count }} {% if object_list.count|pluralize %}{{ model.verbose_name_plural|escape }}{% else %}{{ model.verbose_name|escape }}{% endif %} with {{ field.verbose_name }} on {{ day|date:"F Y" }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} in {{ year }}{% endblock %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} by {{ field.field.verbose_name }}: {{ value|escape }}{% endblock %}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} by {{ field.field.verbose_name }}{% endblock %}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for choice in field.choices %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label }}</a></li>
|
||||
<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst|escape }} with {{ field.field.verbose_name|escape }} {{ value|escape }}{% endblock %}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../../">Fields</a> / <a href="../">By {{ field.field.verbose_name|escape }}</a> / {{ value|escape }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst|escape }} with {{ field.field.verbose_name|escape }} {{ value|escape }}</h1>
|
||||
<h1>{{ object_list.count }} {% if object_list.count|pluralize %}{{ model.verbose_name_plural|escape }}{% else %}{{ model.verbose_name|escape }}{% endif %} with {{ field.field.verbose_name|escape }} {{ value|escape }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}Browsable fields in {{ model.verbose_name_plural|escape }}{% endblock %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst|escape }} by {{ field.field.verbose_name|escape }}{% endblock %}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object }}/">{{ object|escape }}</a></li>
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}Databrowse{% endblock %}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
|
||||
<p>
|
||||
{% for object in model.sample_objects %}
|
||||
<a href="{{ object.url }}">{{ object }}</a>,
|
||||
<a href="{{ object.url }}">{{ object|escape }}</a>,
|
||||
{% endfor %}
|
||||
<a class="more" href="{{ model.url }}">More →</a>
|
||||
</p>
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }}{% endblock %}
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / {{ model.verbose_name_plural|capfirst }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }}</h1>
|
||||
<h1>{{ model.objects.count }} {% if model.objects.count|pluralize %}{{ model.verbose_name_plural }}{% else %}{{ model.verbose_name }}{% endif %}</h1>
|
||||
|
||||
{{ plugin_html }}
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in model.objects %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
{% extends "databrowse/base_site.html" %}
|
||||
|
||||
{% block title %}{{ object.model.verbose_name|capfirst }}: {{ object }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ object.model.url }}">{{ object.model.verbose_name_plural|capfirst }}</a> / {{ object }}</div>
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ object.model.url }}">{{ object.model.verbose_name_plural|capfirst }}</a> / {{ object|escape }}</div>
|
||||
|
||||
<h1>{{ object.model.verbose_name|capfirst }}: {{ object }}</h1>
|
||||
<h1>{{ object.model.verbose_name|capfirst }}: {{ object|escape }}</h1>
|
||||
|
||||
<table class="objectinfo">
|
||||
{% for field in object.fields %}
|
||||
@ -14,8 +14,8 @@
|
||||
<th>{{ field.field.verbose_name|capfirst }}</th>
|
||||
<td>
|
||||
{% if field.urls %}
|
||||
{% for urlvalue in field.urls %}
|
||||
{% if urlvalue.1 %}<a href="{{ urlvalue.1 }}">{% endif %}{{ urlvalue.0 }}{% if urlvalue.1 %}</a>{% endif %}{% if not forloop.last %}, {% endif %}
|
||||
{% for value, url in field.urls %}
|
||||
{% if url %}<a href="{{ url }}">{% endif %}{{ value|escape }}{% if url %}</a>{% endif %}{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% else %}None{% endif %}
|
||||
</td>
|
||||
@ -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 }}</a></li>
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
|
@ -1,15 +1,15 @@
|
||||
from django.core import validators
|
||||
from django.db import models
|
||||
from django.contrib.sites.models import Site
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
class FlatPage(models.Model):
|
||||
url = models.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL], db_index=True,
|
||||
url = models.CharField(_('URL'), max_length=100, validator_list=[validators.isAlphaNumericURL], db_index=True,
|
||||
help_text=_("Example: '/about/contact/'. Make sure to have leading and trailing slashes."))
|
||||
title = models.CharField(_('title'), maxlength=200)
|
||||
title = models.CharField(_('title'), max_length=200)
|
||||
content = models.TextField(_('content'))
|
||||
enable_comments = models.BooleanField(_('enable comments'))
|
||||
template_name = models.CharField(_('template name'), maxlength=70, blank=True,
|
||||
template_name = models.CharField(_('template name'), max_length=70, blank=True,
|
||||
help_text=_("Example: 'flatpages/contact_page.html'. If this isn't provided, the system will use 'flatpages/default.html'."))
|
||||
registration_required = models.BooleanField(_('registration required'), help_text=_("If this is checked, only logged-in users will be able to view the page."))
|
||||
sites = models.ManyToManyField(Site)
|
||||
@ -26,8 +26,8 @@ class FlatPage(models.Model):
|
||||
list_filter = ('sites',)
|
||||
search_fields = ('url', 'title')
|
||||
|
||||
def __str__(self):
|
||||
return "%s -- %s" % (self.url, self.title)
|
||||
def __unicode__(self):
|
||||
return u"%s -- %s" % (self.url, self.title)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.url
|
||||
|
@ -12,9 +12,10 @@
|
||||
additional spatial databases.
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.db import backend
|
||||
from django.db import connection
|
||||
from django.db.models.query import LOOKUP_SEPARATOR, field_choices, find_field, FieldFound, QUERY_TERMS, get_where_clause
|
||||
from django.utils.datastructures import SortedDict
|
||||
qn = connection.ops.quote_name
|
||||
|
||||
if settings.DATABASE_ENGINE == 'postgresql_psycopg2':
|
||||
# PostGIS is the spatial database, getting the rquired modules, renaming as necessary.
|
||||
@ -89,7 +90,6 @@ def parse_lookup(kwarg_items, opts):
|
||||
return joins, where, params
|
||||
|
||||
def lookup_inner(path, lookup_type, value, opts, table, column):
|
||||
qn = backend.quote_name
|
||||
joins, where, params = SortedDict(), [], []
|
||||
current_opts = opts
|
||||
current_table = table
|
||||
@ -216,6 +216,7 @@ def lookup_inner(path, lookup_type, value, opts, table, column):
|
||||
else:
|
||||
# No elements left in path. Current element is the element on which
|
||||
# the search is being performed.
|
||||
db_type = None
|
||||
|
||||
if join_required:
|
||||
# Last query term is a RelatedObject
|
||||
@ -282,7 +283,7 @@ def lookup_inner(path, lookup_type, value, opts, table, column):
|
||||
where.append(gwc)
|
||||
params.extend(geo_params)
|
||||
else:
|
||||
where.append(get_where_clause(lookup_type, current_table + '.', column, value))
|
||||
where.append(get_where_clause(lookup_type, current_table + '.', column, value, db_type))
|
||||
params.extend(field.get_db_prep_lookup(lookup_type, value))
|
||||
|
||||
return joins, where, params
|
||||
|
@ -1,6 +1,6 @@
|
||||
from django.conf import settings
|
||||
from django.core.management import syncdb
|
||||
from django.db import connection, backend
|
||||
from django.core.management import call_command
|
||||
from django.db import connection
|
||||
from django.test.utils import _set_autocommit, TEST_DATABASE_PREFIX
|
||||
from commands import getstatusoutput
|
||||
import os, re, sys
|
||||
@ -23,13 +23,12 @@ def create_lang(db_name, verbosity=1):
|
||||
if status != 0:
|
||||
raise Exception, "Error executing 'plpgsql' command: %s\n" % output
|
||||
|
||||
|
||||
def _create_with_cursor(db_name, verbosity=1, autoclobber=False):
|
||||
"Creates database with psycopg2 cursor."
|
||||
|
||||
# Constructing the necessary SQL to create the database (the DATABASE_USER
|
||||
# must possess the privileges to create a database)
|
||||
create_sql = 'CREATE DATABASE %s OWNER %s' % (backend.quote_name(db_name),
|
||||
create_sql = 'CREATE DATABASE %s OWNER %s' % (connection.ops.quote_name(db_name),
|
||||
settings.DATABASE_USER)
|
||||
cursor = connection.cursor()
|
||||
_set_autocommit(connection)
|
||||
@ -113,7 +112,7 @@ def create_spatial_db(test=False, verbosity=1, autoclobber=False, interactive=Fa
|
||||
settings.DATABASE_NAME = db_name
|
||||
|
||||
# Syncing the database
|
||||
syncdb(verbosity, interactive=interactive)
|
||||
call_command('syncdb', verbosity=verbosity, interactive=interactive)
|
||||
|
||||
# Get a cursor (even though we don't need one yet). This has
|
||||
# the side effect of initializing the test database.
|
||||
@ -123,7 +122,7 @@ def drop_db(db_name=False, test=False):
|
||||
"Using the cursor, drops the given database. All exceptions will be propagated up."
|
||||
if not db_name: db_name = get_spatial_db(test=test)
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("DROP DATABASE %s" % backend.quote_name(db_name))
|
||||
cursor.execute("DROP DATABASE %s" % connection.ops.quote_name(db_name))
|
||||
|
||||
def get_cmd_options(db_name):
|
||||
"Obtains the command-line PostgreSQL connection options for shell commands."
|
||||
|
@ -2,9 +2,10 @@
|
||||
This module contains the spatial lookup types, and the get_geo_where_clause()
|
||||
routine for PostGIS.
|
||||
"""
|
||||
from django.db import backend
|
||||
from django.db import connection
|
||||
from django.contrib.gis.db.backend.postgis.management import postgis_version_tuple
|
||||
from types import StringType, UnicodeType
|
||||
quote_name = connection.ops.quote_name
|
||||
|
||||
# Getting the PostGIS version information
|
||||
POSTGIS_VERSION, MAJOR_VERSION, MINOR_VERSION1, MINOR_VERSION2 = postgis_version_tuple()
|
||||
@ -120,8 +121,8 @@ def get_geom_func(lookup_type):
|
||||
def get_geo_where_clause(lookup_type, table_prefix, field_name, value):
|
||||
"Returns the SQL WHERE clause for use in PostGIS SQL construction."
|
||||
if table_prefix.endswith('.'):
|
||||
table_prefix = backend.quote_name(table_prefix[:-1])+'.'
|
||||
field_name = backend.quote_name(field_name)
|
||||
table_prefix = quote_name(table_prefix[:-1])+'.'
|
||||
field_name = quote_name(field_name)
|
||||
|
||||
# See if a PostGIS operator matches the lookup type first
|
||||
try:
|
||||
|
@ -46,6 +46,11 @@ class GeometryField(GeoBackendField):
|
||||
def get_internal_type(self):
|
||||
return "NoField"
|
||||
|
||||
def db_type(self):
|
||||
# Geometry columns are added by stored procedures, and thus should
|
||||
# be None.
|
||||
return None
|
||||
|
||||
def get_manipulator_field_objs(self):
|
||||
"Using the WKTField (defined above) to be our manipulator."
|
||||
return [WKTField]
|
||||
|
@ -1,6 +1,6 @@
|
||||
import operator
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import backend
|
||||
from django.db import connection
|
||||
from django.db.models.query import Q, QuerySet, handle_legacy_orderlist, quote_only_if_word
|
||||
from django.db.models.fields import FieldDoesNotExist
|
||||
from django.utils.datastructures import SortedDict
|
||||
@ -17,6 +17,8 @@ class GeoQ(Q):
|
||||
class GeoQuerySet(QuerySet):
|
||||
"Geographical-enabled QuerySet object."
|
||||
|
||||
quote_name = connection.ops.quote_name
|
||||
|
||||
#### Overloaded QuerySet Routines ####
|
||||
def __init__(self, model=None):
|
||||
super(GeoQuerySet, self).__init__(model=model)
|
||||
@ -79,10 +81,10 @@ class GeoQuerySet(QuerySet):
|
||||
|
||||
# Add any additional SELECTs.
|
||||
if self._select:
|
||||
select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()])
|
||||
select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), self.quote_name(s[0])) for s in self._select.items()])
|
||||
|
||||
# Start composing the body of the SQL statement.
|
||||
sql = [" FROM", backend.quote_name(opts.db_table)]
|
||||
sql = [" FROM", self.quote_name(opts.db_table)]
|
||||
|
||||
# Compose the join dictionary into SQL describing the joins.
|
||||
if joins:
|
||||
@ -115,15 +117,15 @@ class GeoQuerySet(QuerySet):
|
||||
order = "ASC"
|
||||
if "." in col_name:
|
||||
table_prefix, col_name = col_name.split('.', 1)
|
||||
table_prefix = backend.quote_name(table_prefix) + '.'
|
||||
table_prefix = self.quote_name(table_prefix) + '.'
|
||||
else:
|
||||
# Use the database table as a column prefix if it wasn't given,
|
||||
# and if the requested column isn't a custom SELECT.
|
||||
if "." not in col_name and col_name not in (self._select or ()):
|
||||
table_prefix = backend.quote_name(opts.db_table) + '.'
|
||||
table_prefix = self.quote_name(opts.db_table) + '.'
|
||||
else:
|
||||
table_prefix = ''
|
||||
order_by.append('%s%s %s' % (table_prefix, backend.quote_name(orderfield2column(col_name, opts)), order))
|
||||
order_by.append('%s%s %s' % (table_prefix, self.quote_name(orderfield2column(col_name, opts)), order))
|
||||
if order_by:
|
||||
sql.append("ORDER BY " + ", ".join(order_by))
|
||||
|
||||
@ -142,8 +144,8 @@ class GeoQuerySet(QuerySet):
|
||||
|
||||
#### Methods specific to the GeoQuerySet ####
|
||||
def _field_column(self, field):
|
||||
return "%s.%s" % (backend.quote_name(self.model._meta.db_table),
|
||||
backend.quote_name(field.column))
|
||||
return "%s.%s" % (self.quote_name(self.model._meta.db_table),
|
||||
self.quote_name(field.column))
|
||||
|
||||
def kml(self, field_name, precision=8):
|
||||
"""Returns KML representation of the given field name in a `kml`
|
||||
@ -174,7 +176,7 @@ class GeoQuerySet(QuerySet):
|
||||
# override the geometry column returned from the database.
|
||||
self._custom_select[field.column] = \
|
||||
'(ST_Transform(%s, %s)) AS %s' % (self._field_column(field), srid,
|
||||
backend.quote_name(field.column))
|
||||
self.quote_name(field.column))
|
||||
return self._clone()
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Getting what we need from ctypes
|
||||
import re
|
||||
from types import StringType, TupleType
|
||||
from types import StringType, UnicodeType, TupleType
|
||||
from ctypes import \
|
||||
c_char_p, c_int, c_double, c_void_p, POINTER, \
|
||||
byref, string_at, create_string_buffer
|
||||
@ -84,6 +84,9 @@ class SpatialReference(object):
|
||||
# Creating an initial empty string buffer.
|
||||
buf = c_char_p('')
|
||||
|
||||
if isinstance(input, UnicodeType):
|
||||
input = input.encode('ascii')
|
||||
|
||||
if isinstance(input, StringType):
|
||||
# Is this an EPSG well known name?
|
||||
m = self._epsg_regex.match(input)
|
||||
@ -113,7 +116,7 @@ class SpatialReference(object):
|
||||
|
||||
# If the pointer is NULL, throw an exception.
|
||||
if not srs:
|
||||
raise SRSException, 'Could not create spatial reference from WKT!'
|
||||
raise SRSException, 'Could not create spatial reference from WKT! (%s)' % input
|
||||
else:
|
||||
self._srs = srs
|
||||
|
||||
@ -304,6 +307,7 @@ class SpatialReference(object):
|
||||
check_err(lgdal.OSRExportToProj4(self._srs, byref(w)))
|
||||
return string_at(w)
|
||||
|
||||
@property
|
||||
def proj4(self):
|
||||
"Alias for proj()."
|
||||
return self.proj
|
||||
|
@ -42,7 +42,7 @@ class SpatialRefSys(models.Model):
|
||||
auth_name = models.CharField(maxlength=256)
|
||||
auth_srid = models.IntegerField()
|
||||
srtext = models.CharField(maxlength=2048)
|
||||
proj4 = models.CharField(maxlength=2048, db_column='proj4text')
|
||||
proj4text = models.CharField(maxlength=2048)
|
||||
|
||||
class Meta:
|
||||
db_table = 'spatial_ref_sys'
|
||||
@ -55,17 +55,17 @@ class SpatialRefSys(models.Model):
|
||||
try:
|
||||
self._srs = SpatialReference(self.srtext, 'wkt')
|
||||
return
|
||||
except:
|
||||
except Exception, msg:
|
||||
pass
|
||||
|
||||
# Trying the proj4 text next
|
||||
try:
|
||||
self._srs = SpatialReference(self.proj4, 'proj4')
|
||||
self._srs = SpatialReference(self.proj4text, 'proj4')
|
||||
return
|
||||
except:
|
||||
except Exception, msg:
|
||||
pass
|
||||
|
||||
raise Exception, 'Could not get a OSR Spatial Reference.'
|
||||
raise Exception, 'Could not get a OSR Spatial Reference: %s' % msg
|
||||
else:
|
||||
raise Exception, 'GDAL is not installed!'
|
||||
|
||||
|
@ -25,7 +25,7 @@ def run(verbosity=1):
|
||||
"Runs the tests that do not require geographic (GEOS, GDAL, etc.) models."
|
||||
TextTestRunner(verbosity=verbosity).run(suite())
|
||||
|
||||
def run_tests(module_list, verbosity=1):
|
||||
def run_tests(module_list, verbosity=1, interactive=True):
|
||||
"""Run the tests that require creation of a spatial database. Does not
|
||||
yet work on Windows platforms.
|
||||
|
||||
|
@ -29,11 +29,11 @@ class SpatialRefSysTest(unittest.TestCase):
|
||||
"Testing retrieval of SpatialRefSys model objects."
|
||||
for sd in test_srs:
|
||||
srs = SpatialRefSys.objects.get(srid=sd['srid'])
|
||||
self.assertEqual(srs.srid, sd['srid'])
|
||||
self.assertEqual(srs.auth_name, sd['auth_name'])
|
||||
self.assertEqual(srs.auth_srid, sd['auth_srid'])
|
||||
self.assertEqual(srs.srtext, sd['srtext'])
|
||||
self.assertEqual(srs.proj4, sd['proj4'])
|
||||
self.assertEqual(sd['srid'], srs.srid)
|
||||
self.assertEqual(sd['auth_name'], srs.auth_name)
|
||||
self.assertEqual(sd['auth_srid'], srs.auth_srid)
|
||||
self.assertEqual(sd['srtext'], srs.srtext)
|
||||
self.assertEqual(sd['proj4'], srs.proj4text)
|
||||
|
||||
def test02_osr(self):
|
||||
"Testing getting OSR objects from SpatialRefSys model objects."
|
||||
@ -46,11 +46,12 @@ class SpatialRefSysTest(unittest.TestCase):
|
||||
|
||||
# Testing the SpatialReference object directly.
|
||||
srs = sr.srs
|
||||
self.assertEqual(sd['proj4'], srs.proj)
|
||||
self.assertEqual(sd['proj4'], srs.proj4)
|
||||
self.assertEqual(sd['srtext'], srs.wkt)
|
||||
|
||||
def test03_ellipsoid(self):
|
||||
"Testing the ellipsoid property."
|
||||
return
|
||||
for sd in test_srs:
|
||||
# Getting the ellipsoid and precision parameters.
|
||||
ellps1 = sd['ellipsoid']
|
||||
|
@ -1,6 +1,9 @@
|
||||
from django.utils.translation import ngettext
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ungettext, ugettext as _
|
||||
from django.utils.encoding import force_unicode
|
||||
from django import template
|
||||
from django.template import defaultfilters
|
||||
from django.conf import settings
|
||||
from datetime import date, timedelta
|
||||
import re
|
||||
|
||||
register = template.Library()
|
||||
@ -16,8 +19,8 @@ def ordinal(value):
|
||||
return value
|
||||
t = (_('th'), _('st'), _('nd'), _('rd'), _('th'), _('th'), _('th'), _('th'), _('th'), _('th'))
|
||||
if value % 100 in (11, 12, 13): # special case
|
||||
return "%d%s" % (value, t[0])
|
||||
return '%d%s' % (value, t[value % 10])
|
||||
return u"%d%s" % (value, t[0])
|
||||
return u'%d%s' % (value, t[value % 10])
|
||||
register.filter(ordinal)
|
||||
|
||||
def intcomma(value):
|
||||
@ -25,8 +28,8 @@ def intcomma(value):
|
||||
Converts an integer to a string containing commas every three digits.
|
||||
For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
|
||||
"""
|
||||
orig = str(value)
|
||||
new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', str(value))
|
||||
orig = force_unicode(value)
|
||||
new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', orig)
|
||||
if orig == new:
|
||||
return new
|
||||
else:
|
||||
@ -44,13 +47,13 @@ def intword(value):
|
||||
return value
|
||||
if value < 1000000000:
|
||||
new_value = value / 1000000.0
|
||||
return ngettext('%(value).1f million', '%(value).1f million', new_value) % {'value': new_value}
|
||||
return ungettext('%(value).1f million', '%(value).1f million', new_value) % {'value': new_value}
|
||||
if value < 1000000000000:
|
||||
new_value = value / 1000000000.0
|
||||
return ngettext('%(value).1f billion', '%(value).1f billion', new_value) % {'value': new_value}
|
||||
return ungettext('%(value).1f billion', '%(value).1f billion', new_value) % {'value': new_value}
|
||||
if value < 1000000000000000:
|
||||
new_value = value / 1000000000000.0
|
||||
return ngettext('%(value).1f trillion', '%(value).1f trillion', new_value) % {'value': new_value}
|
||||
return ungettext('%(value).1f trillion', '%(value).1f trillion', new_value) % {'value': new_value}
|
||||
return value
|
||||
register.filter(intword)
|
||||
|
||||
@ -67,3 +70,27 @@ def apnumber(value):
|
||||
return value
|
||||
return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1]
|
||||
register.filter(apnumber)
|
||||
|
||||
def naturalday(value, arg=None):
|
||||
"""
|
||||
For date values that are tomorrow, today or yesterday compared to
|
||||
present day returns representing string. Otherwise, returns a string
|
||||
formatted according to settings.DATE_FORMAT.
|
||||
"""
|
||||
try:
|
||||
value = date(value.year, value.month, value.day)
|
||||
except AttributeError:
|
||||
# Passed value wasn't a date object
|
||||
return value
|
||||
except ValueError:
|
||||
# Date arguments out of range
|
||||
return value
|
||||
delta = value - date.today()
|
||||
if delta.days == 0:
|
||||
return _(u'today')
|
||||
elif delta.days == 1:
|
||||
return _(u'tomorrow')
|
||||
elif delta.days == -1:
|
||||
return _(u'yesterday')
|
||||
return defaultfilters.date(value, arg)
|
||||
register.filter(naturalday)
|
||||
|
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