mirror of
https://github.com/django/django.git
synced 2025-07-05 18:29:11 +00:00
gis: Merged revisions 4564-4668 via svnmerge from
http://code.djangoproject.com/svn/django/trunk git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@4669 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d60c443194
commit
5514d87319
6
AUTHORS
6
AUTHORS
@ -67,6 +67,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Ian Clelland <clelland@gmail.com>
|
||||
crankycoder@gmail.com
|
||||
Matt Croydon <http://www.postneo.com/>
|
||||
Jure Cuhalev <gandalf@owca.info>
|
||||
dackze+django@gmail.com
|
||||
Dirk Datzert <dummy@habmalnefrage.de>
|
||||
Jonathan Daugherty (cygnus) <http://www.cprogrammer.org/>
|
||||
@ -80,6 +81,8 @@ answer newbie questions, and generally made Django that much better:
|
||||
Andy Dustman <farcepest@gmail.com>
|
||||
Clint Ecker
|
||||
Enrico <rico.bl@gmail.com>
|
||||
Ludvig Ericson <ludvig.ericson@gmail.com>
|
||||
Dirk Eschler <dirk.eschler@gmx.net>
|
||||
Marc Fargas <telenieko@telenieko.com>
|
||||
favo@exoweb.net
|
||||
Eric Floehr <eric@intellovations.com>
|
||||
@ -115,6 +118,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
konrad@gwu.edu
|
||||
lakin.wecker@gmail.com
|
||||
Stuart Langridge <http://www.kryogenix.org/>
|
||||
Nicola Larosa <nico@teknico.net>
|
||||
Eugene Lazutkin <http://lazutkin.com/blog/>
|
||||
Jeong-Min Lee <falsetru@gmail.com>
|
||||
Christopher Lenz <http://www.cmlenz.net/>
|
||||
@ -132,6 +136,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Jason McBrayer <http://www.carcosa.net/jason/>
|
||||
mccutchen@gmail.com
|
||||
michael.mcewan@gmail.com
|
||||
mikko@sorl.net
|
||||
mitakummaa@gmail.com
|
||||
mmarshall
|
||||
Eric Moritz <http://eric.themoritzfamily.com/>
|
||||
@ -146,6 +151,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
pgross@thoughtworks.com
|
||||
phaedo <http://phaedo.cx/>
|
||||
phil@produxion.net
|
||||
phil.h.smith@gmail.com
|
||||
Gustavo Picon
|
||||
Luke Plant <http://lukeplant.me.uk/>
|
||||
plisk
|
||||
|
@ -55,6 +55,7 @@ LANGUAGES = (
|
||||
('is', gettext_noop('Icelandic')),
|
||||
('it', gettext_noop('Italian')),
|
||||
('ja', gettext_noop('Japanese')),
|
||||
('kn', gettext_noop('Kannada')),
|
||||
('lv', gettext_noop('Latvian')),
|
||||
('mk', gettext_noop('Macedonian')),
|
||||
('nl', gettext_noop('Dutch')),
|
||||
@ -98,7 +99,7 @@ SERVER_EMAIL = 'root@localhost'
|
||||
SEND_BROKEN_LINK_EMAILS = False
|
||||
|
||||
# Database connection info.
|
||||
DATABASE_ENGINE = '' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
|
||||
DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
|
||||
DATABASE_NAME = '' # Or path to database file if using sqlite3.
|
||||
DATABASE_USER = '' # Not used with sqlite3.
|
||||
DATABASE_PASSWORD = '' # Not used with sqlite3.
|
||||
@ -318,3 +319,10 @@ TEST_RUNNER = 'django.test.simple.run_tests'
|
||||
# The name of the database to use for testing purposes.
|
||||
# If None, a name of 'test_' + DATABASE_NAME will be assumed
|
||||
TEST_DATABASE_NAME = None
|
||||
|
||||
############
|
||||
# FIXTURES #
|
||||
############
|
||||
|
||||
# The list of directories to search for fixtures
|
||||
FIXTURE_DIRS = ()
|
||||
|
Binary file not shown.
@ -8,7 +8,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-02-05 02:56+0100\n"
|
||||
"PO-Revision-Date: 2007-02-05 03:19+0100\n"
|
||||
"Last-Translator: Benjamin Schulz <beschulz@gmail.com>\n"
|
||||
"Last-Translator: Dirk Eschler <dirk.eschler@gmx.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
@ -17,6 +17,7 @@ msgstr ""
|
||||
"X-Poedit-Country: GERMANY\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: .\conf\global_settings.py:39
|
||||
msgid "Arabic"
|
||||
@ -206,11 +207,11 @@ msgstr "Unbekannt"
|
||||
|
||||
#: .\contrib\admin\models.py:16
|
||||
msgid "action time"
|
||||
msgstr "Zeit der Aktion"
|
||||
msgstr "Zeitpunkt der Aktion"
|
||||
|
||||
#: .\contrib\admin\models.py:19
|
||||
msgid "object id"
|
||||
msgstr "Objekt ID"
|
||||
msgstr "Objekt-ID"
|
||||
|
||||
#: .\contrib\admin\models.py:20
|
||||
msgid "object repr"
|
||||
@ -239,7 +240,7 @@ msgstr "Seite nicht gefunden"
|
||||
|
||||
#: .\contrib\admin\templates\admin\404.html.py:10
|
||||
msgid "We're sorry, but the requested page could not be found."
|
||||
msgstr "Es tut uns leid, aber die angeforderte Seite kann nicht gefunden werden."
|
||||
msgstr "Es tut uns leid, aber die angeforderte Seite konnte nicht gefunden werden."
|
||||
|
||||
#: .\contrib\admin\templates\admin\500.html.py:4
|
||||
#: .\contrib\admin\templates\admin\base.html.py:30
|
||||
@ -272,7 +273,7 @@ msgstr "Serverfehler <em>(500)</em>"
|
||||
|
||||
#: .\contrib\admin\templates\admin\500.html.py: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 "Es hat einen Fehler gegeben. Dieser Fehler wurde an die Serververwalter per eMail weitergegeben und sollte bald behoben sein. Vielen Dank für Ihr Verständnis."
|
||||
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.py:25
|
||||
msgid "Welcome,"
|
||||
@ -346,7 +347,7 @@ msgstr "Django Verwaltung"
|
||||
#: .\contrib\admin\templates\admin\change_form.html.py:15
|
||||
#: .\contrib\admin\templates\admin\index.html.py:28
|
||||
msgid "Add"
|
||||
msgstr "Zufügen"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: .\contrib\admin\templates\admin\change_form.html.py:21
|
||||
#: .\contrib\admin\templates\admin\object_history.html.py:5
|
||||
@ -361,8 +362,8 @@ msgstr "Im Web Anzeigen"
|
||||
#: .\contrib\admin\templates\admin\auth\user\change_password.html.py:24
|
||||
msgid "Please correct the error below."
|
||||
msgid_plural "Please correct the errors below."
|
||||
msgstr[0] "Bitte den Fehler korrigieren."
|
||||
msgstr[1] "Bitte die Fehler korrigieren."
|
||||
msgstr[0] "Bitte den aufgeführten Fehler korrigieren."
|
||||
msgstr[1] "Bitte die aufgeführten Fehler korrigieren."
|
||||
|
||||
#: .\contrib\admin\templates\admin\change_form.html.py:50
|
||||
msgid "Ordering"
|
||||
@ -375,7 +376,7 @@ msgstr "Reihenfolge:"
|
||||
#: .\contrib\admin\templates\admin\change_list.html.py:12
|
||||
#, python-format
|
||||
msgid "Add %(name)s"
|
||||
msgstr "%(name)s zufügen"
|
||||
msgstr "%(name)s hinzufügen"
|
||||
|
||||
#: .\contrib\admin\templates\admin\delete_confirmation.html.py:9
|
||||
#: .\contrib\admin\templates\admin\submit_line.html.py:3
|
||||
@ -437,7 +438,7 @@ msgstr "Keine vorhanden"
|
||||
|
||||
#: .\contrib\admin\templates\admin\invalid_setup.html.py: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 "Irgendetwas ist falsch mit der Datenbankkonfiguration. Bitte sicherstellen, das die richtigen Datenbanktabellen angelegt wurden und bitte sicherstellen, das die Datenbank vom verwendeten Datenbankbenutzer auch lesbar ist."
|
||||
msgstr "Etwas stimmt nicht mit der Datenbankkonfiguration. Bitte sicherstellen, das die richtigen Datenbanktabellen angelegt wurden und bitte sicherstellen, das die Datenbank vom verwendeten Datenbankbenutzer auch lesbar ist."
|
||||
|
||||
#: .\contrib\admin\templates\admin\login.html.py:17
|
||||
#: .\contrib\comments\templates\comments\form.html.py:6
|
||||
@ -487,8 +488,8 @@ msgstr "Los"
|
||||
#, python-format
|
||||
msgid "1 result"
|
||||
msgid_plural "%(counter)s results"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "Ein Ergebnis"
|
||||
msgstr[1] "%(counter)s Ergebnisse"
|
||||
|
||||
#: .\contrib\admin\templates\admin\search_form.html.py:10
|
||||
#, python-format
|
||||
@ -497,7 +498,7 @@ msgstr "%(full_result_count)s gesamt"
|
||||
|
||||
#: .\contrib\admin\templates\admin\submit_line.html.py:4
|
||||
msgid "Save as new"
|
||||
msgstr "Als Neu sichern"
|
||||
msgstr "Als neu sichern"
|
||||
|
||||
#: .\contrib\admin\templates\admin\submit_line.html.py:5
|
||||
msgid "Save and add another"
|
||||
@ -527,12 +528,12 @@ msgstr "Passwort"
|
||||
#: .\contrib\admin\templates\admin\auth\user\add_form.html.py:23
|
||||
#: .\contrib\admin\templates\admin\auth\user\change_password.html.py:39
|
||||
msgid "Password (again)"
|
||||
msgstr "Kennwort (wiederholen)"
|
||||
msgstr "Passwort (wiederholen)"
|
||||
|
||||
#: .\contrib\admin\templates\admin\auth\user\add_form.html.py:24
|
||||
#: .\contrib\admin\templates\admin\auth\user\change_password.html.py:40
|
||||
msgid "Enter the same password as above, for verification."
|
||||
msgstr "Bitte das gleiche Passwort zur Prüfung nochmal eingeben."
|
||||
msgstr "Bitte das gleiche Passwort zur Überprüfung nochmal eingeben."
|
||||
|
||||
#: .\contrib\admin\templates\admin\auth\user\change_password.html.py:28
|
||||
#, python-format
|
||||
@ -559,7 +560,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p class=\"help\">Um Bookmarklets zu installieren müssen diese Links in die\n"
|
||||
"Browser-Werkzeugleiste gehzogen werden, oder mittels rechter Maustaste in die\n"
|
||||
"Browser-Werkzeugleiste gezogen werden, oder mittels rechter Maustaste in die\n"
|
||||
"Bookmarks gespeichert werden. Danach können die Bookmarklets von jeder Seite\n"
|
||||
"aufgerufen werden. Einige Bookmarklets sind für den Zugriff von 'internen'\n"
|
||||
"Rechnern eingeschränkt. Falls nicht klar ist, ob ein Rechner als 'intern'\n"
|
||||
@ -575,7 +576,7 @@ msgstr "Springt von jeder Seite zu der Dokumentation für den View der diese Sei
|
||||
|
||||
#: .\contrib\admin\templates\admin_doc\bookmarklets.html.py:22
|
||||
msgid "Show object ID"
|
||||
msgstr "Objekt ID anzeigen"
|
||||
msgstr "Objekt-ID anzeigen"
|
||||
|
||||
#: .\contrib\admin\templates\admin_doc\bookmarklets.html.py:23
|
||||
msgid "Shows the content-type and unique ID for pages that represent a single object."
|
||||
@ -595,71 +596,71 @@ msgstr "Dieses Objekt in einem neuen Fenster ändern."
|
||||
|
||||
#: .\contrib\admin\templates\admin_doc\bookmarklets.html.py:29
|
||||
msgid "As above, but opens the admin page in a new window."
|
||||
msgstr "Wie zuvor, aber öffnent die Administrationsseite in einem neuen Fenster."
|
||||
msgstr "Wie zuvor, aber öffnet die Administrationsseite in einem neuen Fenster."
|
||||
|
||||
#: .\contrib\admin\templates\registration\logged_out.html.py:8
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
msgstr "Vielen Dank, daß Sie hier ein paar nette Minuten verbracht haben."
|
||||
msgstr "Vielen Dank, dass Sie hier ein paar nette Minuten verbracht haben."
|
||||
|
||||
#: .\contrib\admin\templates\registration\logged_out.html.py:10
|
||||
msgid "Log in again"
|
||||
msgstr "Erneut Anmelden"
|
||||
msgstr "Erneut anmelden"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_done.html.py:4
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:4
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:6
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:10
|
||||
msgid "Password change"
|
||||
msgstr "Kennwort ändern"
|
||||
msgstr "Passwort ändern"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_done.html.py:6
|
||||
#: .\contrib\admin\templates\registration\password_change_done.html.py:10
|
||||
msgid "Password change successful"
|
||||
msgstr "Kennwortänderung erfolgreich"
|
||||
msgstr "Passwort erfolgreich geändert"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_done.html.py:12
|
||||
msgid "Your password was changed."
|
||||
msgstr "Ihr Kennwort wurde geändert."
|
||||
msgstr "Ihr Passwort wurde geändert."
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:12
|
||||
msgid "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly."
|
||||
msgstr "Bitte geben Sie aus Sicherheitsgründen erst Ihr altes Kennwort und darunter dann zweimal (um sicherzustellen, dass Sie es korrekt eingegeben haben) das neue Kennwort ein."
|
||||
msgstr "Bitte geben Sie aus Sicherheitsgründen erst Ihr altes Passwort und darunter dann zweimal (um sicherzustellen, dass Sie es korrekt eingegeben haben) das neue Kennwort ein."
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:17
|
||||
msgid "Old password:"
|
||||
msgstr "altes Kennwort:"
|
||||
msgstr "Altes Passwort:"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:19
|
||||
msgid "New password:"
|
||||
msgstr "neues Kennwort:"
|
||||
msgstr "Neues Passwort:"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:21
|
||||
msgid "Confirm password:"
|
||||
msgstr "Kennwortwiederholung:"
|
||||
msgstr "Passwort wiederholen:"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_change_form.html.py:23
|
||||
msgid "Change my password"
|
||||
msgstr "Mein Kennwort ändern"
|
||||
msgstr "Mein Passwort ändern"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_done.html.py:4
|
||||
#: .\contrib\admin\templates\registration\password_reset_form.html.py:4
|
||||
#: .\contrib\admin\templates\registration\password_reset_form.html.py:6
|
||||
#: .\contrib\admin\templates\registration\password_reset_form.html.py:10
|
||||
msgid "Password reset"
|
||||
msgstr "Kennwort zurücksetzen"
|
||||
msgstr "Passwort zurücksetzen"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_done.html.py:6
|
||||
#: .\contrib\admin\templates\registration\password_reset_done.html.py:10
|
||||
msgid "Password reset successful"
|
||||
msgstr "Erfolgreich Kennwort zurückgesetzt"
|
||||
msgstr "Passwort wurde erfolgreich zurückgesetzt"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_done.html.py:12
|
||||
msgid "We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly."
|
||||
msgstr "Wir haben Ihnen ein neues Kennwort per eMail zugeschickt an die Adresse, die Sie uns gegeben haben. Es sollte in Kürze ankommen."
|
||||
msgstr "Wir haben ein neues Passwort an die von Ihnen angegebene E-Mail-Adresse geschickt. Sie sollten es in Kürze erhalten."
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_email.html.py:2
|
||||
msgid "You're receiving this e-mail because you requested a password reset"
|
||||
msgstr "Sie erhalten diese Mail, weil Sie ein neues Kennwort"
|
||||
msgstr "Sie erhalten diese E-Mail, weil Sie ein neues Passwort"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_email.html.py:3
|
||||
#, python-format
|
||||
@ -669,11 +670,11 @@ msgstr "für Ihren Benutzer bei %(site_name)s angefordert haben."
|
||||
#: .\contrib\admin\templates\registration\password_reset_email.html.py:5
|
||||
#, python-format
|
||||
msgid "Your new password is: %(new_password)s"
|
||||
msgstr "Ihr neues Kennwort ist: %(new_password)s"
|
||||
msgstr "Ihr neues Passwort lautet: %(new_password)s"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_email.html.py:7
|
||||
msgid "Feel free to change this password by going to this page:"
|
||||
msgstr "Sie können das Kennwort auf folgender Seite ändern:"
|
||||
msgstr "Sie können das Passwort auf folgender Seite ändern:"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_email.html.py:11
|
||||
msgid "Your username, in case you've forgotten:"
|
||||
@ -690,7 +691,7 @@ msgstr "Das Team von %(site_name)s"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_form.html.py:12
|
||||
msgid "Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you."
|
||||
msgstr "Passwort vergessen? Einfach die E-Mail-Adresse eingeben und wir setzen das Passwort auf ein neues und senden das per E-Mail zu."
|
||||
msgstr "Passwort vergessen? Einfach die E-Mail-Adresse eingeben und wir setzen das Passwort zurück und lassen es Ihnen per E-Mail zukommen."
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_form.html.py:16
|
||||
msgid "E-mail address:"
|
||||
@ -698,7 +699,7 @@ msgstr "E-Mail-Adresse:"
|
||||
|
||||
#: .\contrib\admin\templates\registration\password_reset_form.html.py:16
|
||||
msgid "Reset my password"
|
||||
msgstr "Mein Kennwort zurücksetzen"
|
||||
msgstr "Mein Passwort zurücksetzen"
|
||||
|
||||
#: .\contrib\admin\templates\widget\date_time.html.py:3
|
||||
msgid "Date:"
|
||||
@ -730,30 +731,29 @@ msgstr "%(name)s \"%(obj)s\" wurde erfolgreich hinzugefügt."
|
||||
#: .\contrib\admin\views\main.py:261
|
||||
#: .\contrib\admin\views\main.py:347
|
||||
msgid "You may edit it again below."
|
||||
msgstr "Das Element kann jetzt weiter geändert werden."
|
||||
msgstr "Das Element kann jetzt weiter bearbeitet werden."
|
||||
|
||||
#: .\contrib\admin\views\auth.py:30
|
||||
msgid "Add user"
|
||||
msgstr "Benutzer zufügen"
|
||||
msgstr "Benutzer hinzufügen"
|
||||
|
||||
#: .\contrib\admin\views\auth.py:57
|
||||
#, fuzzy
|
||||
msgid "Password changed successfully."
|
||||
msgstr "Kennwortänderung erfolgreich"
|
||||
msgstr "Passwort erfolgreich geändert."
|
||||
|
||||
#: .\contrib\admin\views\auth.py:64
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Change password: %s"
|
||||
msgstr "Passwort ändern"
|
||||
msgstr "Passwort ändern: %s"
|
||||
|
||||
#: .\contrib\admin\views\decorators.py:10
|
||||
#: .\contrib\auth\forms.py:59
|
||||
msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
|
||||
msgstr "Bitte einen Benutzernamen und ein Kennwort eingeben. Beide Felder berücksichtigen die Groß-/Kleinschreibung."
|
||||
msgstr "Bitte einen Benutzernamen und ein Passwort eingeben. Beide Felder berücksichtigen die Groß-/Kleinschreibung."
|
||||
|
||||
#: .\contrib\admin\views\decorators.py:62
|
||||
msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
|
||||
msgstr "Bitte neu anmelden, da die Session ausgelaufen ist. Keine Angst: die Beiträge wurden gesichert."
|
||||
msgstr "Bitte neu anmelden, da die Session ausgelaufen ist. Keine Angst, die Beiträge wurden gesichert."
|
||||
|
||||
#: .\contrib\admin\views\decorators.py:69
|
||||
msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
|
||||
@ -761,12 +761,12 @@ msgstr "Es sieht danach aus, dass der Browser keine Cookies akzeptiert. Bitte im
|
||||
|
||||
#: .\contrib\admin\views\decorators.py:83
|
||||
msgid "Usernames cannot contain the '@' character."
|
||||
msgstr "Benutzernamen können das Zeichen '@' nicht enthalten."
|
||||
msgstr "Benutzernamen dürfen das Zeichen '@' nicht enthalten."
|
||||
|
||||
#: .\contrib\admin\views\decorators.py:85
|
||||
#, python-format
|
||||
msgid "Your e-mail address is not your username. Try '%s' instead."
|
||||
msgstr "Die eMail-Adresse ist nicht der Benutzername. Bitte '%s' stattdessen versuchen."
|
||||
msgstr "Die E-Mail-Adresse entspricht nicht Ihrem Benutzernamen. Bitte stattdessen '%s' versuchen."
|
||||
|
||||
#: .\contrib\admin\views\doc.py:46
|
||||
#: .\contrib\admin\views\doc.py:48
|
||||
@ -839,7 +839,7 @@ msgstr "Ganzzahl"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:292
|
||||
msgid "Boolean (Either True or False)"
|
||||
msgstr "Wahrheitswert (Wahr oder Falsch)"
|
||||
msgstr "Boolscher Wert (True oder False)"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:293
|
||||
#: .\contrib\admin\views\doc.py:311
|
||||
@ -849,19 +849,19 @@ msgstr "Zeichenkette (bis zu %(maxlength)s Zeichen)"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:294
|
||||
msgid "Comma-separated integers"
|
||||
msgstr "Kommaseparierte Liste von Zahlen"
|
||||
msgstr "Kommaseparierte Liste von Ganzzahlen"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:295
|
||||
msgid "Date (without time)"
|
||||
msgstr "Datum (ohne Zeit)"
|
||||
msgstr "Datum (ohne Uhrzeit)"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:296
|
||||
msgid "Date (with time)"
|
||||
msgstr "Datum (mit Zeit)"
|
||||
msgstr "Datum (mit Uhrzeit)"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:297
|
||||
msgid "E-mail address"
|
||||
msgstr "E-mail-Adresse"
|
||||
msgstr "E-Mail-Adresse"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:298
|
||||
#: .\contrib\admin\views\doc.py:299
|
||||
@ -880,11 +880,11 @@ msgstr "IP-Adresse"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:306
|
||||
msgid "Boolean (Either True, False or None)"
|
||||
msgstr "Wahrheitswert (Wahr, Falsch oder Nichts)"
|
||||
msgstr "Boolscher Wert (True, False oder None)"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:307
|
||||
msgid "Relation to parent model"
|
||||
msgstr "Beziehung zum Übermodell"
|
||||
msgstr "Beziehung zum Eltern-Modell"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:308
|
||||
msgid "Phone number"
|
||||
@ -901,15 +901,15 @@ msgstr "Zeit"
|
||||
#: .\contrib\admin\views\doc.py:315
|
||||
#: .\contrib\flatpages\models.py:7
|
||||
msgid "URL"
|
||||
msgstr "URL"
|
||||
msgstr "Adresse (URL)"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:316
|
||||
msgid "U.S. state (two uppercase letters)"
|
||||
msgstr "U.S. Bundesstaat (zwei Grossbuchstaben)"
|
||||
msgstr "U.S. Bundesstaat (zwei Großbuchstaben)"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:317
|
||||
msgid "XML text"
|
||||
msgstr "XML Text"
|
||||
msgstr "XML-Text"
|
||||
|
||||
#: .\contrib\admin\views\doc.py:343
|
||||
#, python-format
|
||||
@ -929,7 +929,7 @@ msgstr "Jetzt kann ein weiteres Element vom Typ %s angelegt werden."
|
||||
#: .\contrib\admin\views\main.py:289
|
||||
#, python-format
|
||||
msgid "Add %s"
|
||||
msgstr "%s zufügen"
|
||||
msgstr "%s hinzufügen"
|
||||
|
||||
#: .\contrib\admin\views\main.py:335
|
||||
#, python-format
|
||||
@ -965,7 +965,7 @@ msgstr "%(name)s \"%(obj)s\" wurde erfolgreich geändert."
|
||||
#: .\contrib\admin\views\main.py:353
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr "%(name)s \"%(obj)s\" wurde erfolgreich zugefügt. Das Element kann jetzt geändert werden."
|
||||
msgstr "%(name)s \"%(obj)s\" wurde erfolgreich hinzugefügt. Das Element kann jetzt geändert werden."
|
||||
|
||||
#: .\contrib\admin\views\main.py:391
|
||||
#, python-format
|
||||
@ -989,7 +989,7 @@ msgstr "%(name)s \"%(obj)s\" wurde erfolgreich gelöscht."
|
||||
|
||||
#: .\contrib\admin\views\main.py:514
|
||||
msgid "Are you sure?"
|
||||
msgstr "Sicher? Ganz sicher?"
|
||||
msgstr "Sind Sie ganz sicher?"
|
||||
|
||||
#: .\contrib\admin\views\main.py:536
|
||||
#, python-format
|
||||
@ -1013,7 +1013,7 @@ msgstr "Datenbankfehler"
|
||||
#: .\contrib\auth\forms.py:16
|
||||
#: .\contrib\auth\forms.py:137
|
||||
msgid "The two password fields didn't match."
|
||||
msgstr "Die zwei Passwörter sind nicht gleich."
|
||||
msgstr "Die beiden Passwörter sind nicht identisch."
|
||||
|
||||
#: .\contrib\auth\forms.py:24
|
||||
msgid "A user with that username already exists."
|
||||
@ -1021,7 +1021,7 @@ msgstr "Ein Benutzer mit diesem Namen existiert bereits."
|
||||
|
||||
#: .\contrib\auth\forms.py:52
|
||||
msgid "Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."
|
||||
msgstr "Der Webbrowser scheint keine Cookies aktiviert zu haben. Cookies sind für die Anmeldung zwingend notwendig."
|
||||
msgstr "Der Webbrowser scheint keine Cookies aktiviert zu haben. Cookies sind für die Anmeldung zwingend erforderlich."
|
||||
|
||||
#: .\contrib\auth\forms.py:61
|
||||
msgid "This account is inactive."
|
||||
@ -1029,11 +1029,11 @@ msgstr "Dieser Benutzer ist inaktiv."
|
||||
|
||||
#: .\contrib\auth\forms.py:84
|
||||
msgid "That e-mail address doesn't have an associated user account. Are you sure you've registered?"
|
||||
msgstr "Die Email-Adresse hat keinen Benutzer zugeordnet. Sicher, dass die Adresse hier angemeldet ist?"
|
||||
msgstr "Zu dieser E-Mail-Adresse existiert kein Benutzer. Sicher, dass Sie sich mit dieser Adresse angemeldet haben?"
|
||||
|
||||
#: .\contrib\auth\forms.py:116
|
||||
msgid "The two 'new password' fields didn't match."
|
||||
msgstr "Die zwei Passwörter sind nicht gleich."
|
||||
msgstr "Die beiden neuen Passwörter sind nicht identisch."
|
||||
|
||||
#: .\contrib\auth\forms.py:123
|
||||
msgid "Your old password was entered incorrectly. Please enter it again."
|
||||
@ -1084,15 +1084,15 @@ msgstr "Nachname"
|
||||
|
||||
#: .\contrib\auth\models.py:93
|
||||
msgid "e-mail address"
|
||||
msgstr "eMail-Adresse"
|
||||
msgstr "E-Mail-Adresse"
|
||||
|
||||
#: .\contrib\auth\models.py:94
|
||||
msgid "password"
|
||||
msgstr "Kennwort"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: .\contrib\auth\models.py:94
|
||||
msgid "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."
|
||||
msgstr "Benutzen Sie die Form '[algo]$[salt]$[hexdigest]' oder das <a href=\"password/\">Passwort ändern Formular</a>."
|
||||
msgstr "Die Form '[algo]$[salt]$[hexdigest]' verwenden, oder das <a href=\"password/\">Passwort ändern Formular</a> benutzen."
|
||||
|
||||
#: .\contrib\auth\models.py:95
|
||||
msgid "staff status"
|
||||
@ -1100,7 +1100,7 @@ msgstr "Administrator"
|
||||
|
||||
#: .\contrib\auth\models.py:95
|
||||
msgid "Designates whether the user can log into this admin site."
|
||||
msgstr "Gibt an, ob der Benutzer sich an der Administrationsseite anmelden kann."
|
||||
msgstr "Legt fest, ob sich der Benutzer an der Administrationsseite anmelden kann."
|
||||
|
||||
#: .\contrib\auth\models.py:96
|
||||
msgid "active"
|
||||
@ -1108,7 +1108,7 @@ msgstr "Aktiv"
|
||||
|
||||
#: .\contrib\auth\models.py:96
|
||||
msgid "Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts."
|
||||
msgstr "Gibt an, ob der Benutzer sich an der Administrationsseite anmelden kann. Anstelle Benutzer zu löschen, kann das hier auch einfach abgeschaltet werden."
|
||||
msgstr "Legt fest, ob sich der Benutzer an der Administrationsseite anmelden kann. Anstatt einen Benutzer zu löschen, kann er hier auch einfach deaktiviert werden."
|
||||
|
||||
#: .\contrib\auth\models.py:97
|
||||
msgid "superuser status"
|
||||
@ -1116,11 +1116,11 @@ msgstr "Hauptadmin."
|
||||
|
||||
#: .\contrib\auth\models.py:97
|
||||
msgid "Designates that this user has all permissions without explicitly assigning them."
|
||||
msgstr "Bestimmt, dass dieser Benutzer alle Berechtigungen hat, ohne diese einzeln zuweisen zu müssen."
|
||||
msgstr "Legt fest, dass der Benutzer alle Berechtigungen hat, ohne diese einzeln zuweisen zu müssen."
|
||||
|
||||
#: .\contrib\auth\models.py:98
|
||||
msgid "last login"
|
||||
msgstr "letzte Anmeldung"
|
||||
msgstr "Letzte Anmeldung"
|
||||
|
||||
#: .\contrib\auth\models.py:99
|
||||
msgid "date joined"
|
||||
@ -1169,7 +1169,7 @@ msgstr "Abgemeldet"
|
||||
#: .\contrib\comments\models.py:67
|
||||
#: .\contrib\comments\models.py:166
|
||||
msgid "object ID"
|
||||
msgstr "Objekt ID"
|
||||
msgstr "Objekt-ID"
|
||||
|
||||
#: .\contrib\comments\models.py:68
|
||||
msgid "headline"
|
||||
@ -1233,7 +1233,7 @@ msgstr "ist gelöscht"
|
||||
|
||||
#: .\contrib\comments\models.py:86
|
||||
msgid "Check this box if the comment is inappropriate. A \"This comment has been removed\" message will be displayed instead."
|
||||
msgstr "Hier einen Haken setzen, wenn der Kommentar unpassend ist. Es wird dann eine \"Dieser Kommentar wurde entfernt\" Meldung statt dessen angezeigt."
|
||||
msgstr "Hier einen Haken setzen, wenn der Kommentar unpassend ist. Stattdessen wird dann \"Dieser Kommentar wurde entfernt\" Meldung angezeigt."
|
||||
|
||||
#: .\contrib\comments\models.py:91
|
||||
msgid "comments"
|
||||
@ -1347,7 +1347,7 @@ msgstr "Vom Moderator %r gelöscht"
|
||||
|
||||
#: .\contrib\comments\templates\comments\form.html.py:8
|
||||
msgid "Forgotten your password?"
|
||||
msgstr "Kennwort vergessen?"
|
||||
msgstr "Passwort vergessen?"
|
||||
|
||||
#: .\contrib\comments\templates\comments\form.html.py:12
|
||||
msgid "Ratings"
|
||||
@ -1383,7 +1383,7 @@ msgstr "Ihr Name:"
|
||||
|
||||
#: .\contrib\comments\views\comments.py:27
|
||||
msgid "This rating is required because you've entered at least one other rating."
|
||||
msgstr "Die Abstimmung ist zwangsweise, weil Du an mindestens einer anderen Abstimmung teilnimmst."
|
||||
msgstr "Diese Abstimmung ist zwingend erforderlich, da Du an mindestens einer weiteren Abstimmung teilnimmst."
|
||||
|
||||
#: .\contrib\comments\views\comments.py:111
|
||||
#, python-format
|
||||
@ -1423,7 +1423,7 @@ msgstr "Nur POST ist erlaubt"
|
||||
#: .\contrib\comments\views\comments.py:192
|
||||
#: .\contrib\comments\views\comments.py:284
|
||||
msgid "One or more of the required fields wasn't submitted"
|
||||
msgstr "Eines oder mehrere der erforderlichen Felder fehlt"
|
||||
msgstr "Eines oder mehrere der erforderlichen Felder fehlen"
|
||||
|
||||
#: .\contrib\comments\views\comments.py:196
|
||||
#: .\contrib\comments\views\comments.py:286
|
||||
@ -1442,7 +1442,7 @@ msgstr "Das Kommentarformular wurde nicht mit 'preview' oder 'post' abgeschickt"
|
||||
|
||||
#: .\contrib\comments\views\karma.py:19
|
||||
msgid "Anonymous users cannot vote"
|
||||
msgstr "Anonyme Benutzer können nicht abstimmen"
|
||||
msgstr "Anonyme Benutzer dürfen nicht abstimmen"
|
||||
|
||||
#: .\contrib\comments\views\karma.py:23
|
||||
msgid "Invalid comment ID"
|
||||
@ -1450,7 +1450,7 @@ msgstr "Ungültige Kommentar-ID"
|
||||
|
||||
#: .\contrib\comments\views\karma.py:25
|
||||
msgid "No voting for yourself"
|
||||
msgstr "Keine Abstimmung bei Dir selber"
|
||||
msgstr "Keine Abstimmung für dich selbst"
|
||||
|
||||
#: .\contrib\contenttypes\models.py:26
|
||||
msgid "python model class name"
|
||||
@ -1494,7 +1494,7 @@ msgstr "Registrierung erforderlich"
|
||||
|
||||
#: .\contrib\flatpages\models.py:14
|
||||
msgid "If this is checked, only logged-in users will be able to view the page."
|
||||
msgstr "Wenn hier ein Haken ist, können nur angemeldete Benutzer diese Seite sehen."
|
||||
msgstr "Wenn hier ein Haken gesetzt ist, können nur angemeldete Benutzer diese Seite sehen."
|
||||
|
||||
#: .\contrib\flatpages\models.py:18
|
||||
msgid "flat page"
|
||||
@ -1590,7 +1590,7 @@ msgstr "Hier sind nur durch Komma getrennte Ziffern erlaubt."
|
||||
|
||||
#: .\core\validators.py:99
|
||||
msgid "Enter valid e-mail addresses separated by commas."
|
||||
msgstr "Bitte mit Komma getrennte, gültige eMail-Adressen eingeben."
|
||||
msgstr "Bitte mit Komma getrennte, gültige E-Mail-Adressen eingeben."
|
||||
|
||||
#: .\core\validators.py:103
|
||||
msgid "Please enter a valid IP address."
|
||||
@ -1643,17 +1643,17 @@ msgstr "Bitte eine gültige Datums- und Zeitangabe im Format JJJJ-MM-TT SS:MM ei
|
||||
#: .\core\validators.py:161
|
||||
#: .\newforms\fields.py:269
|
||||
msgid "Enter a valid e-mail address."
|
||||
msgstr "Bitte eine gültige eMail-Adresse eingeben"
|
||||
msgstr "Bitte eine gültige E-Mail-Adresse eingeben."
|
||||
|
||||
#: .\core\validators.py:173
|
||||
#: .\core\validators.py:442
|
||||
#: .\oldforms\__init__.py:667
|
||||
msgid "No file was submitted. Check the encoding type on the form."
|
||||
msgstr "Es wurde keine Datei geschickt. Eventuell ist das Formular-Encoding falsch."
|
||||
msgstr "Es wurde keine Datei übermittelt. Eventuell ist das Formular-Encoding falsch."
|
||||
|
||||
#: .\core\validators.py:177
|
||||
msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
|
||||
msgstr "Bitte ein Bild hochladen. Die Datei, die hochgeladen wurde, ist kein Bild oder ist defekt."
|
||||
msgstr "Bitte ein Bild hochladen. Die hochgeladene Datei ist kein Bild, oder ist defekt."
|
||||
|
||||
#: .\core\validators.py:184
|
||||
#, python-format
|
||||
@ -1663,16 +1663,16 @@ msgstr "Die URL %s zeigt nicht auf ein gültiges Bild."
|
||||
#: .\core\validators.py:188
|
||||
#, python-format
|
||||
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
|
||||
msgstr "Telefonnummern müssen im Format XXX-XXX-XXXX sein. \"%s\" ist ungültig."
|
||||
msgstr "Telefonnummern müssen das Format XXX-XXX-XXXX haben. \"%s\" ist ungültig."
|
||||
|
||||
#: .\core\validators.py:196
|
||||
#, python-format
|
||||
msgid "The URL %s does not point to a valid QuickTime video."
|
||||
msgstr "Die URL %s zeigt nicht auf ein gültiges QuickTime video."
|
||||
msgstr "Die URL %s zeigt nicht auf ein gültiges QuickTime-Video."
|
||||
|
||||
#: .\core\validators.py:200
|
||||
msgid "A valid URL is required."
|
||||
msgstr "Eine gültige URL ist hier verlangt."
|
||||
msgstr "Eine gültige URL wird hier verlangt."
|
||||
|
||||
#: .\core\validators.py:214
|
||||
#, python-format
|
||||
@ -1773,25 +1773,25 @@ msgstr[1] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffern eingeben."
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with a whole part of at most %s digit."
|
||||
msgid_plural "Please enter a valid decimal number with a whole part of at most %s digits."
|
||||
msgstr[0] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffer eingeben."
|
||||
msgstr[1] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffern eingeben."
|
||||
msgstr[0] "Bitte eine gültige Dezimalzahl mit einer Gesamtzahl von maximal %s Ziffer eingeben."
|
||||
msgstr[1] "Bitte eine gültige Dezimalzahl mit einer Gesamtzahl von maximal %s Ziffern eingeben."
|
||||
|
||||
#: .\core\validators.py:425
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s decimal place."
|
||||
msgid_plural "Please enter a valid decimal number with at most %s decimal places."
|
||||
msgstr[0] "Bitte eine gültige Dezimalzahl mit maximal %s Dezimalstelle eingeben."
|
||||
msgstr[0] "Bitte eine gültige Dezimalzahl mit maximal %s Dezimalstelle eingeben."
|
||||
msgstr[1] "Bitte eine gültige Dezimalzahl mit maximal %s Dezimalstellen eingeben."
|
||||
|
||||
#: .\core\validators.py:435
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at least %s bytes big."
|
||||
msgstr "Bitte sicherstellen, daß die hochgeladene Datei mindestens %s Bytes gross ist."
|
||||
msgstr "Bitte sicherstellen, dass die hochgeladene Datei mindestens %s Bytes groß ist."
|
||||
|
||||
#: .\core\validators.py:436
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at most %s bytes big."
|
||||
msgstr "Bitte sicherstellen, daß die hochgeladene Datei maximal %s Bytes gross ist."
|
||||
msgstr "Bitte sicherstellen, dass die hochgeladene Datei maximal %s Bytes groß ist."
|
||||
|
||||
#: .\core\validators.py:453
|
||||
msgid "The format for this field is wrong."
|
||||
@ -1857,7 +1857,7 @@ msgstr "Mehrere IDs können mit Komma getrennt werden."
|
||||
|
||||
#: .\db\models\fields\related.py:644
|
||||
msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr " Um mehr als eine Selektion zu treffen, \"Strg\", oder auf dem Mac \"Command\", beim Klicken gedrückt halten."
|
||||
msgstr "Um mehr als eine Selektion zu treffen, \"Strg\", oder auf dem Mac \"Command\", beim Klicken gedrückt halten."
|
||||
|
||||
#: .\db\models\fields\related.py:691
|
||||
#, python-format
|
||||
@ -1881,7 +1881,7 @@ msgstr "Ein '%(optname)s' mit diesem '%(fieldname)s' existiert bereits."
|
||||
#: .\newforms\fields.py:460
|
||||
#: .\oldforms\__init__.py:352
|
||||
msgid "This field is required."
|
||||
msgstr "Dieses Feld ist zwingend."
|
||||
msgstr "Dieses Feld ist zwingend erforderlich."
|
||||
|
||||
#: .\db\models\fields\__init__.py:360
|
||||
msgid "This value must be an integer."
|
||||
@ -1897,19 +1897,19 @@ msgstr "Dieses Feld darf nicht leer sein."
|
||||
|
||||
#: .\db\models\fields\__init__.py:619
|
||||
msgid "Enter a valid filename."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben."
|
||||
|
||||
#: .\newforms\fields.py:101
|
||||
#: .\newforms\fields.py:254
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Ensure this value has at most %d characters."
|
||||
msgstr "Bitte sicherstellen, dass der Text weniger als %s Zeichen hat."
|
||||
msgstr "Bitte sicherstellen, dass der Text maximal %d Zeichen hat."
|
||||
|
||||
#: .\newforms\fields.py:103
|
||||
#: .\newforms\fields.py:256
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Ensure this value has at least %d characters."
|
||||
msgstr "Bitte sicherstellen, dass der Text weniger als %s Zeichen hat."
|
||||
msgstr "Bitte sicherstellen, dass der Text wenigstens %d Zeichen hat."
|
||||
|
||||
#: .\newforms\fields.py:128
|
||||
#, python-format
|
||||
@ -1922,47 +1922,40 @@ msgid "Ensure this value is greater than or equal to %s."
|
||||
msgstr "Dieser Wert muss größer oder gleich %s sein."
|
||||
|
||||
#: .\newforms\fields.py:163
|
||||
#, fuzzy
|
||||
msgid "Enter a valid date."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
msgstr "Bitte ein gültiges Datum eingeben."
|
||||
|
||||
#: .\newforms\fields.py:190
|
||||
#, fuzzy
|
||||
msgid "Enter a valid time."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
msgstr "Bitte eine gültige Uhrzeit eingeben."
|
||||
|
||||
#: .\newforms\fields.py:226
|
||||
#, fuzzy
|
||||
msgid "Enter a valid date/time."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
msgstr "Bitte gültiges Datum und Uhrzeit eingeben."
|
||||
|
||||
#: .\newforms\fields.py:240
|
||||
#, fuzzy
|
||||
msgid "Enter a valid value."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
msgstr "Bitte einen gültigen Wert eingeben."
|
||||
|
||||
#: .\newforms\fields.py:287
|
||||
#: .\newforms\fields.py:309
|
||||
#, fuzzy
|
||||
msgid "Enter a valid URL."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
msgstr "Bitte eine gültige Adresse eingeben."
|
||||
|
||||
#: .\newforms\fields.py:311
|
||||
#, fuzzy
|
||||
msgid "This URL appears to be a broken link."
|
||||
msgstr "Die URL %s funktioniert nicht."
|
||||
msgstr "Diese Adresse scheint nicht gültig zu sein."
|
||||
|
||||
#: .\newforms\fields.py:359
|
||||
#: .\newforms\fields.py:386
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Select a valid choice. %s is not one of the available choices."
|
||||
msgstr "Bitte eine gültige Auswahl treffen; '%(data)s' ist nicht in %(choices)s."
|
||||
msgstr "Bitte eine gültige Auswahl treffen. %s ist keine gültige Auswahl."
|
||||
|
||||
#: .\newforms\fields.py:377
|
||||
#: .\newforms\fields.py:453
|
||||
#, fuzzy
|
||||
msgid "Enter a list of values."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
msgstr "Eine Liste mit Werten eingeben."
|
||||
|
||||
#: .\oldforms\__init__.py:387
|
||||
#, python-format
|
||||
@ -1988,7 +1981,7 @@ msgstr "Die ausgewählte Datei ist leer."
|
||||
|
||||
#: .\oldforms\__init__.py:725
|
||||
msgid "Enter a whole number between -32,768 and 32,767."
|
||||
msgstr "Bitte eine ganze Zahl zwischen -32.768 und 32.767 eingeben."
|
||||
msgstr "Bitte eine Ganzzahl zwischen -32.768 und 32.767 eingeben."
|
||||
|
||||
#: .\oldforms\__init__.py:735
|
||||
msgid "Enter a positive number."
|
||||
@ -2230,6 +2223,3 @@ msgstr "%(verbose_name)s wurde erfolgreich aktualisiert."
|
||||
msgid "The %(verbose_name)s was deleted."
|
||||
msgstr "%(verbose_name)s wurde gelöscht"
|
||||
|
||||
#~ msgid "Use '[algo]$[salt]$[hexdigest]'"
|
||||
#~ msgstr "Im Format '[algo]$[salt]$[hexdigest]'"
|
||||
|
||||
|
Binary file not shown.
@ -9,7 +9,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: 2005-12-04 13:21+0100\n"
|
||||
"Last-Translator: Georg Bauer <gb@bofh.ms>\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-Transfer-Encoding: 8bit\n"
|
||||
@ -21,11 +21,11 @@ msgstr "Verf
|
||||
|
||||
#: 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 "Zufügen"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
@ -42,7 +42,7 @@ msgstr "Gew
|
||||
|
||||
#: 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
|
||||
@ -89,7 +89,7 @@ msgstr "Mittag"
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
msgid "Cancel"
|
||||
msgstr "Abbruch"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
@ -116,3 +116,4 @@ msgstr "Anzeigen"
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr "Verbergen"
|
||||
|
||||
|
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.
@ -1,15 +1,14 @@
|
||||
# Argentinean spanish translation for the django-admin JS files, based on
|
||||
# Spanish translation work by Jorge Gajon.
|
||||
# Copyright (C)
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Ramiro Morales <rm0@gmx.net>, 2006.
|
||||
# This file is distributed under the same license as the Django package.
|
||||
# Copyright (C) Ramiro Morales <rm0@gmx.net>, 2006,2007.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django JavaScript 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-09-25 15:09-0300\n"
|
||||
"PO-Revision-Date: 2006-05-16 10:20-0300\n"
|
||||
"POT-Creation-Date: 2007-02-25 17:48-0300\n"
|
||||
"PO-Revision-Date: 2007-02-25 17:55-0300\n"
|
||||
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
|
Binary file not shown.
@ -93,7 +93,7 @@ msgstr "tšekki"
|
||||
|
||||
#: conf/global_settings.py:42
|
||||
msgid "Welsh"
|
||||
msgstr ""
|
||||
msgstr "wales"
|
||||
|
||||
#: conf/global_settings.py:43
|
||||
msgid "Danish"
|
||||
@ -169,15 +169,15 @@ msgstr "venäjä"
|
||||
|
||||
#: conf/global_settings.py:61
|
||||
msgid "Slovak"
|
||||
msgstr ""
|
||||
msgstr "slovakia"
|
||||
|
||||
#: conf/global_settings.py:62
|
||||
msgid "Slovenian"
|
||||
msgstr ""
|
||||
msgstr "slovenia"
|
||||
|
||||
#: conf/global_settings.py:63
|
||||
msgid "Serbian"
|
||||
msgstr ""
|
||||
msgstr "serbia"
|
||||
|
||||
#: conf/global_settings.py:64
|
||||
msgid "Swedish"
|
||||
@ -189,15 +189,15 @@ msgstr ""
|
||||
|
||||
#: conf/global_settings.py:66
|
||||
msgid "Ukrainian"
|
||||
msgstr ""
|
||||
msgstr "ukraina"
|
||||
|
||||
#: conf/global_settings.py:67
|
||||
msgid "Simplified Chinese"
|
||||
msgstr ""
|
||||
msgstr "kiina (yksinkertaistettu)"
|
||||
|
||||
#: conf/global_settings.py:68
|
||||
msgid "Traditional Chinese"
|
||||
msgstr ""
|
||||
msgstr "kiina (perinteinen)"
|
||||
|
||||
#: core/validators.py:63
|
||||
msgid "This value must contain only letters, numbers and underscores."
|
||||
@ -211,7 +211,7 @@ msgstr "Tässä voidaan käyttää vain kirjaimia (a-z), numeroita (0-9) sekä a
|
||||
|
||||
#: core/validators.py:75
|
||||
msgid "Uppercase letters are not allowed here."
|
||||
msgstr "Versaalit (ABC) eivät kelpaa tässä."
|
||||
msgstr "Isot kirjaimet (ABC) eivät kelpaa tässä."
|
||||
|
||||
#: core/validators.py:79
|
||||
msgid "Lowercase letters are not allowed here."
|
||||
@ -270,7 +270,7 @@ msgstr "Kuva ei kelpaa. Lähettämäsi tiedosto ei ole kuva, tai tiedosto on vio
|
||||
#: core/validators.py:162
|
||||
#, python-format
|
||||
msgid "The URL %s does not point to a valid image."
|
||||
msgstr "Osoittessa %s ei ole kelpaavaa kuvaa."
|
||||
msgstr "Osoittessa %s ei ole kuvaa tai se on vioittunut."
|
||||
|
||||
#: core/validators.py:166
|
||||
#, python-format
|
||||
@ -280,7 +280,7 @@ msgstr "Puhelinnumeron tulee olla muodossa XXX-XXX-XXXX. \"%s\" ei kelpaa."
|
||||
#: core/validators.py:174
|
||||
#, python-format
|
||||
msgid "The URL %s does not point to a valid QuickTime video."
|
||||
msgstr "Osoitteessa %s ei ole kelpaavaa QuickTime-videota."
|
||||
msgstr "Osoitteessa %s ei ole QuickTime-videota tai se on vioittunut."
|
||||
|
||||
#: core/validators.py:178
|
||||
msgid "A valid URL is required."
|
||||
@ -308,7 +308,7 @@ msgstr "URL-osoite %s ei kelpaa."
|
||||
#: core/validators.py:213 core/validators.py:215
|
||||
#, python-format
|
||||
msgid "The URL %s is a broken link."
|
||||
msgstr "Osoite %s on katkennut linkki."
|
||||
msgstr "Osoite %s on rikkoutunut tai väärä linkki."
|
||||
|
||||
#: core/validators.py:221
|
||||
msgid "Enter a valid U.S. state abbreviation."
|
||||
@ -324,7 +324,7 @@ msgstr[1] "Sanoja \"%s\" ei saa käyttää tässä."
|
||||
#: core/validators.py:243
|
||||
#, python-format
|
||||
msgid "This field must match the '%s' field."
|
||||
msgstr ""
|
||||
msgstr "Arvon täytyy olla sama kuin kentässä '%s'."
|
||||
|
||||
#: core/validators.py:262
|
||||
msgid "Please enter something for at least one field."
|
||||
@ -403,7 +403,7 @@ msgstr "Tämä arvo ei kelpaa."
|
||||
#: core/validators.py:441
|
||||
#, python-format
|
||||
msgid "Could not retrieve anything from %s."
|
||||
msgstr ""
|
||||
msgstr "Tietoja ei voida noutaa kohteesta: %s."
|
||||
|
||||
#: core/validators.py:444
|
||||
#, python-format
|
||||
@ -1676,7 +1676,13 @@ msgid_plural ""
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr[0] ""
|
||||
"Kommentin kirjoittanut käyttäjä on kirjoittanut vain yhden kommentin:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr[1] ""
|
||||
"Kommentin kirjoittanut käyttäjä on kirjoittanut alle %(count)s kommenttia:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
|
||||
# Mitä "sketchy user" tarkoittaa?
|
||||
#: contrib/comments/views/comments.py:116
|
||||
@ -1972,38 +1978,38 @@ msgstr "joulu"
|
||||
#: utils/timesince.py:12
|
||||
msgid "year"
|
||||
msgid_plural "years"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "vuosi"
|
||||
msgstr[1] "vuotta"
|
||||
|
||||
#: utils/timesince.py:13
|
||||
msgid "month"
|
||||
msgid_plural "months"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "kuukausi"
|
||||
msgstr[1] "kuukautta"
|
||||
|
||||
#: utils/timesince.py:14
|
||||
msgid "week"
|
||||
msgid_plural "weeks"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "viikko"
|
||||
msgstr[1] "viikkoa"
|
||||
|
||||
#: utils/timesince.py:15
|
||||
msgid "day"
|
||||
msgid_plural "days"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "päivä"
|
||||
msgstr[1] "päivää"
|
||||
|
||||
#: utils/timesince.py:16
|
||||
msgid "hour"
|
||||
msgid_plural "hours"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "tunti"
|
||||
msgstr[1] "tuntia"
|
||||
|
||||
#: utils/timesince.py:17
|
||||
msgid "minute"
|
||||
msgid_plural "minutes"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "minuutti"
|
||||
msgstr[1] "minuuttia"
|
||||
|
||||
#: utils/translation/trans_real.py:362
|
||||
msgid "DATE_FORMAT"
|
||||
@ -2019,10 +2025,9 @@ msgstr "G:i"
|
||||
|
||||
#: utils/translation/trans_real.py:380
|
||||
msgid "YEAR_MONTH_FORMAT"
|
||||
msgstr "N j, Y"
|
||||
msgstr "N Y"
|
||||
|
||||
#: utils/translation/trans_real.py:381
|
||||
#, fuzzy
|
||||
msgid "MONTH_DAY_FORMAT"
|
||||
msgstr "N j, Y"
|
||||
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,20 +1,39 @@
|
||||
# translation of djangojs.po to Italiano
|
||||
# Italian translation for the django-admin JS files
|
||||
# Copyright (C) 2006 the Lawrence Journal-World
|
||||
# This file is distributed under the same license as the Django package.
|
||||
# Carlo C8E Miron <carlo.miron AT gmail.com>, 2006.
|
||||
#
|
||||
# Carlo C8E Miron <carlo.miron AT gmail.com>, 2006.
|
||||
# Nicola 'tekNico' Larosa <nico@tekNico.net>, 2007.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django JavaScript 1.0\n"
|
||||
"Project-Id-Version: djangojs\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: 2005-12-04 21:47+0100\n"
|
||||
"Last-Translator: Carlo C8E Miron <carlo.miron AT gmail.com>\n"
|
||||
"Language-Team: Italian <Django-I18N@googlegroups.com>\n"
|
||||
"POT-Creation-Date: 2007-02-26 20:46+0100\n"
|
||||
"PO-Revision-Date: 2007-02-26 20:55+0100\n"
|
||||
"Last-Translator: Nicola Larosa <nico@tekNico.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: KBabel 1.11.2\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 ""
|
||||
"Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settembre Ottobre "
|
||||
"Novembre Dicembre"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "D L M M G V S"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Domenica Lunedì Martedì Mercoledì Giovedì Venerdì Sabato"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
@ -23,7 +42,7 @@ msgstr "Disponibile %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr "Seleziona tutto"
|
||||
msgstr "Scegli tutto"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
@ -36,7 +55,7 @@ msgstr "Rimuovi"
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "Selezionato %s"
|
||||
msgstr "Scelto %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
@ -46,66 +65,59 @@ msgstr "Seleziona le tue scelte e clicca "
|
||||
msgid "Clear all"
|
||||
msgstr "Cancella tutto"
|
||||
|
||||
#: 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 ""
|
||||
"Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settembre Ottobre "
|
||||
"Novembre Dicembre"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Domenica Lunedì Martedì Mercoledì Giovedì Venerdì Sabato"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "D L M M G 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 "Adesso"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr "Orologio"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr "Seleziona un orario"
|
||||
msgstr "Scegli un orario"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr "Mezzanotte"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr "6 del mattino"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "Mezzogiorno"
|
||||
|
||||
#: 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 "Annulla"
|
||||
|
||||
#: 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 "Oggi"
|
||||
|
||||
#: 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 "Ieri"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "Domani"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr "Mostra"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr "Nascondi"
|
||||
|
||||
|
BIN
django/conf/locale/kn/LC_MESSAGES/django.mo
Normal file
BIN
django/conf/locale/kn/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
2533
django/conf/locale/kn/LC_MESSAGES/django.po
Normal file
2533
django/conf/locale/kn/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/kn/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/kn/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
116
django/conf/locale/kn/LC_MESSAGES/djangojs.po
Normal file
116
django/conf/locale/kn/LC_MESSAGES/djangojs.po
Normal file
@ -0,0 +1,116 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django-kn 0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-09-25 15:43+0200\n"
|
||||
"PO-Revision-Date: 2007-01-08 20:22+0530\n"
|
||||
"Last-Translator: Kannada Localization Team <translation@sampada.info>\n"
|
||||
"Language-Team: Kannada <translation@sampada.info>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "ಲಭ್ಯ %s "
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr "ಎಲ್ಲವನ್ನೂ ಆಯ್ದುಕೊಳ್ಳಿ"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr "ಸೇರಿಸಿ"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr "ತೆಗೆದು ಹಾಕಿ"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "%s ಆಯ್ದುಕೊಳ್ಳಲಾಗಿದೆ"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr ""
|
||||
"ನಿಮ್ಮ ಆಯ್ಕೆ(ಗಳ)ನ್ನು ಆರಿಸಿ "
|
||||
"ಮತ್ತು ಕ್ಲಿಕ್ಕಿಸಿ"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr "ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:26
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr ""
|
||||
"ಜನವರಿ ಫೆಬ್ರುವರಿ ಮಾರ್ಚ್ "
|
||||
"ಎಪ್ರಿಲ್ ಮೇ ಜೂನ್ ಜುಲೈ ಆಗಸ್ಟ್ "
|
||||
"ಸೆಪ್ಟೆಂಬರ್ ನವೆಂಬರ್ ಡಿಸೆಂಬರ್"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
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:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
msgid "Now"
|
||||
msgstr "ಈಗ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
msgid "Clock"
|
||||
msgstr "ಗಡಿಯಾರ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
msgid "Choose a time"
|
||||
msgstr "ಸಮಯವೊಂದನ್ನು ಆರಿಸಿ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Midnight"
|
||||
msgstr "ಮಧ್ಯರಾತ್ರಿ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "6 a.m."
|
||||
msgstr "ಬೆಳಗಿನ ೬ ಗಂಟೆ "
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "Noon"
|
||||
msgstr "ಮಧ್ಯಾಹ್ನ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
msgid "Cancel"
|
||||
msgstr "ರದ್ದುಗೊಳಿಸಿ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
msgid "Today"
|
||||
msgstr "ಈ ದಿನ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||
msgid "Calendar"
|
||||
msgstr "ಪಂಚಾಂಗ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
msgid "Yesterday"
|
||||
msgstr "ನಿನ್ನೆ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "ನಾಳೆ"
|
Binary file not shown.
@ -1,18 +1,19 @@
|
||||
# translation of django.po to Macedonian
|
||||
# translation of mk_django.po to Macedonian
|
||||
#
|
||||
# Georgi Stanojevski <glisha@gmail.com>, 2006.
|
||||
# Georgi Stanojevski <glisha@gmail.com>, 2006, 2007.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: django\n"
|
||||
"Project-Id-Version: mk_django\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-02-15 10:53+1100\n"
|
||||
"PO-Revision-Date: 2006-12-04 15:58+0100\n"
|
||||
"PO-Revision-Date: 2007-02-24 13:53+0100\n"
|
||||
"Last-Translator: Georgi Stanojevski <glisha@gmail.com>\n"
|
||||
"Language-Team: Macedonian <ossm-members@hedona.on.net.mk>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;"
|
||||
|
||||
#: db/models/manipulators.py:305
|
||||
#, python-format
|
||||
@ -31,25 +32,18 @@ msgstr "Ве молам внесете правилно %s."
|
||||
|
||||
#: db/models/fields/related.py:642
|
||||
msgid "Separate multiple IDs with commas."
|
||||
msgstr "Одвој ги повеќето идентификациони броеви со запирки."
|
||||
msgstr "Одвојте ги идентификационите броеви со запирки."
|
||||
|
||||
#: db/models/fields/related.py:644
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
"Држете го „Control“ или „Command“ на Мекинтош за да изберете повеќе од едно."
|
||||
msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr "Држете го „Control“ или „Command“ на Мекинтош за да изберете повеќе од едно."
|
||||
|
||||
#: db/models/fields/related.py:691
|
||||
#, python-format
|
||||
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
|
||||
msgid_plural ""
|
||||
"Please enter valid %(self)s IDs. The values %(value)r are invalid."
|
||||
msgstr[0] ""
|
||||
"Ве молам внесете правилен %(self)s идентификацион број. Оваа вредност %"
|
||||
"(value)r е неправилна. "
|
||||
msgstr[1] ""
|
||||
"Ве молам внесете правилен %(self)s идентификацион број. Вредностите %(value)"
|
||||
"r се неправилни."
|
||||
msgid_plural "Please enter valid %(self)s IDs. The values %(value)r are invalid."
|
||||
msgstr[0] "Ве молам внесете правилен %(self)s идентификацион број. Оваа вредност %(value)r е неправилна."
|
||||
msgstr[1] "Ве молам внесете правилен %(self)s идентификацион број. Вредностите %(value)r се неправилни."
|
||||
|
||||
#: db/models/fields/__init__.py:42
|
||||
#, python-format
|
||||
@ -161,24 +155,23 @@ msgstr "Јапонски"
|
||||
|
||||
#: conf/global_settings.py:57
|
||||
msgid "Latvian"
|
||||
msgstr ""
|
||||
msgstr "Латвиски"
|
||||
|
||||
#: conf/global_settings.py:58
|
||||
msgid "Macedonian"
|
||||
msgstr ""
|
||||
msgstr "Македонски"
|
||||
|
||||
#: conf/global_settings.py:59
|
||||
msgid "Dutch"
|
||||
msgstr "Холандија"
|
||||
msgstr "Холандски"
|
||||
|
||||
#: conf/global_settings.py:60
|
||||
msgid "Norwegian"
|
||||
msgstr "Норвешки"
|
||||
|
||||
#: conf/global_settings.py:61
|
||||
#, fuzzy
|
||||
msgid "Polish"
|
||||
msgstr "Англиски"
|
||||
msgstr "Полски"
|
||||
|
||||
#: conf/global_settings.py:62
|
||||
msgid "Brazilian"
|
||||
@ -509,20 +502,17 @@ msgstr "сесии"
|
||||
|
||||
#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
|
||||
msgid "The two password fields didn't match."
|
||||
msgstr ""
|
||||
msgstr "Двете полиња со лозинките не се совпаѓаат."
|
||||
|
||||
#: contrib/auth/forms.py:25
|
||||
#, fuzzy
|
||||
msgid "A user with that username already exists."
|
||||
msgstr "%(optname)s со ова %(fieldname)s веќе постои."
|
||||
msgstr "Веќе постои корисник со тоа корисничко име."
|
||||
|
||||
#: contrib/auth/forms.py:53
|
||||
msgid ""
|
||||
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
|
||||
"required for logging in."
|
||||
msgstr ""
|
||||
"Не изгледа дека вашиот прелистувач има овозможено колачиња. Колачињата се "
|
||||
"потребни за да се најавите."
|
||||
msgstr "Не изгледа дека вашиот прелистувач има овозможено колачиња. Колачињата се потребни за да се најавите."
|
||||
|
||||
#: contrib/auth/forms.py:60 contrib/admin/views/decorators.py:10
|
||||
msgid ""
|
||||
@ -540,15 +530,15 @@ msgstr "Оваа сметка е неактивна."
|
||||
msgid ""
|
||||
"That e-mail address doesn't have an associated user account. Are you sure "
|
||||
"you've registered?"
|
||||
msgstr ""
|
||||
msgstr "Нема регистрирано корисник со оваа адреса за е-пошта. Сигурни ли сте дека сте регистрирани?"
|
||||
|
||||
#: contrib/auth/forms.py:117
|
||||
msgid "The two 'new password' fields didn't match."
|
||||
msgstr ""
|
||||
msgstr "Двете нови лозинки не се совпаѓаат."
|
||||
|
||||
#: contrib/auth/forms.py:124
|
||||
msgid "Your old password was entered incorrectly. Please enter it again."
|
||||
msgstr ""
|
||||
msgstr "Не ја внесовте точно вашата стара лозинка. Ве молам внесете ја повторно."
|
||||
|
||||
#: contrib/auth/views.py:39
|
||||
msgid "Logged out"
|
||||
@ -610,7 +600,7 @@ msgstr "лозинка"
|
||||
msgid ""
|
||||
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
|
||||
"password form</a>."
|
||||
msgstr ""
|
||||
msgstr "Користете '[algo]$[salt]$[hexdigest]' или користете ја <a href=\"password/\">формата за промена на лозинката</a>."
|
||||
|
||||
#: contrib/auth/models.py:95
|
||||
msgid "staff status"
|
||||
@ -618,8 +608,7 @@ msgstr "статус на администраторите"
|
||||
|
||||
#: contrib/auth/models.py:95
|
||||
msgid "Designates whether the user can log into this admin site."
|
||||
msgstr ""
|
||||
"Означува дали корисникот може да се логира во сајтот за администрација."
|
||||
msgstr "Означува дали корисникот може да се логира во сајтот за администрација."
|
||||
|
||||
#: contrib/auth/models.py:96
|
||||
msgid "active"
|
||||
@ -742,8 +731,7 @@ msgid "URL"
|
||||
msgstr "URL"
|
||||
|
||||
#: contrib/flatpages/models.py:8
|
||||
msgid ""
|
||||
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
|
||||
msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
|
||||
msgstr ""
|
||||
"На пр. „/za/kontakt/“. Осигурајте се да имате коса црта и на крајот и на "
|
||||
"почетокот."
|
||||
@ -1054,8 +1042,7 @@ msgid "No voting for yourself"
|
||||
msgstr "Нема гласање за самиот себе"
|
||||
|
||||
#: contrib/comments/views/comments.py:27
|
||||
msgid ""
|
||||
"This rating is required because you've entered at least one other rating."
|
||||
msgid "This rating is required because you've entered at least one other rating."
|
||||
msgstr ""
|
||||
"Ова гласање за популарност е потребно бидејќи внесовте најмалку уште едно "
|
||||
"друго."
|
||||
@ -1114,9 +1101,7 @@ msgstr "Некој ја променил формата за коментари
|
||||
msgid ""
|
||||
"The comment form had an invalid 'target' parameter -- the object ID was "
|
||||
"invalid"
|
||||
msgstr ""
|
||||
"Формата за коментар имаше неправилен „target“ параметар - идентификациониот "
|
||||
"број на објектот беше неправилен."
|
||||
msgstr "Формата за коментар имаше неправилен „target“ параметар - идентификациониот број на објектот беше неправилен"
|
||||
|
||||
#: contrib/comments/views/comments.py:257
|
||||
#: contrib/comments/views/comments.py:321
|
||||
@ -1316,8 +1301,7 @@ msgstr "Уреди го овој објект (во овој прозорец)"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:26
|
||||
msgid "Jumps to the admin page for pages that represent a single object."
|
||||
msgstr ""
|
||||
"Скокнува до админ страницата за страници кои претставуваат единечен објект."
|
||||
msgstr "Скокнува до админ страницата за страници кои претставуваат единечен објект."
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:28
|
||||
msgid "Edit this object (new window)"
|
||||
@ -1438,10 +1422,7 @@ 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 ""
|
||||
"Бришење на %(object_name)s '%(escaped_object)s' ќе резултира со бришење на "
|
||||
"поврзаните објекти, но со вашата сметка немате доволно привилегии да ги "
|
||||
"бришете следните типови на објекти."
|
||||
msgstr "Бришење на %(object_name)s '%(escaped_object)s' ќе резултира со бришење на поврзаните објекти, но со вашата сметка немате доволно привилегии да ги бришете следните типови на објекти:"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:21
|
||||
#, python-format
|
||||
@ -1575,7 +1556,7 @@ msgstr "Заради верификација внесете ја истата
|
||||
#: 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 ""
|
||||
msgstr "Внесете нова лозинка за корисникот <strong>%(username)s</strong>."
|
||||
|
||||
#: contrib/admin/templates/widget/file.html:2
|
||||
msgid "Currently:"
|
||||
@ -1595,8 +1576,7 @@ msgstr "Време:"
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:8
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
msgstr ""
|
||||
"Ви благодариме што денеска поминавте квалитетно време со интернет страницава."
|
||||
msgstr "Ви благодариме што денеска поминавте квалитетно време со интернет страницава."
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:10
|
||||
msgid "Log in again"
|
||||
@ -1604,8 +1584,7 @@ msgstr "Логирајте се повторно"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:2
|
||||
msgid "You're receiving this e-mail because you requested a password reset"
|
||||
msgstr ""
|
||||
"Ја добивата оваа порака бидејќи побаравте да се ресетира вашата лозинка"
|
||||
msgstr "Ја добивата оваа порака бидејќи побаравте да се ресетира вашата лозинка"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:3
|
||||
#, python-format
|
||||
@ -1619,8 +1598,7 @@ msgstr "Вашата нова лозинка е: %(new_password)s"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:7
|
||||
msgid "Feel free to change this password by going to this page:"
|
||||
msgstr ""
|
||||
"Чуствувајте се слободно да ја промените оваа лозинка преку оваа страница:"
|
||||
msgstr "Чуствувајте се слободно да ја промените оваа лозинка преку оваа страница:"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:11
|
||||
msgid "Your username, in case you've forgotten:"
|
||||
@ -1699,9 +1677,7 @@ msgstr "Вашата лозинка беше сменета."
|
||||
msgid ""
|
||||
"Forgotten your password? Enter your e-mail address below, and we'll reset "
|
||||
"your password and e-mail the new one to you."
|
||||
msgstr ""
|
||||
"Сте ја заборавиле вашата лозинка? Внесете ја вашата е-пошта подолу, ќе ја "
|
||||
"ресетираме вашата лозинка и новата ќе ви ја пратиме по е-пошта."
|
||||
msgstr "Сте ја заборавиле вашата лозинка? Внесете ја вашата е-пошта подолу, ќе ја ресетираме вашата лозинка и новата ќе ви ја пратиме по е-пошта."
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:16
|
||||
msgid "E-mail address:"
|
||||
@ -1738,7 +1714,7 @@ msgstr "Додади %s"
|
||||
#: contrib/admin/views/main.py:335
|
||||
#, python-format
|
||||
msgid "Added %s."
|
||||
msgstr "Додадено %s"
|
||||
msgstr "Додадено %s."
|
||||
|
||||
#: contrib/admin/views/main.py:337
|
||||
#, python-format
|
||||
@ -1761,8 +1737,7 @@ msgstr "%(name)s \"%(obj)s\" беше успешно изменета."
|
||||
|
||||
#: contrib/admin/views/main.py:353
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr ""
|
||||
"%(name)s \"%(obj)s\" беше успешно додадена.Подолу можете повторно да ја "
|
||||
"уредите."
|
||||
@ -1968,87 +1943,78 @@ msgid "Add user"
|
||||
msgstr "Додади корисник"
|
||||
|
||||
#: contrib/admin/views/auth.py:57
|
||||
#, fuzzy
|
||||
msgid "Password changed successfully."
|
||||
msgstr "Успешна промена на лозинката"
|
||||
msgstr "Успешна промена на лозинката."
|
||||
|
||||
#: contrib/admin/views/auth.py:64
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Change password: %s"
|
||||
msgstr "Промени лозинка"
|
||||
msgstr "Промени лозинка: %s"
|
||||
|
||||
#: newforms/fields.py:101 newforms/fields.py:254
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Ensure this value has at most %d characters."
|
||||
msgstr "Осигурајте се дека вашиот текст има помалку од %s знак."
|
||||
msgstr "Осигурајте се дека оваа вредност има најмногу %d знаци."
|
||||
|
||||
#: newforms/fields.py:103 newforms/fields.py:256
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Ensure this value has at least %d characters."
|
||||
msgstr "Осигурајте се дека вашиот текст има помалку од %s знак."
|
||||
msgstr "Осигурајте се дека оваа вредност има најмалку %d знаци."
|
||||
|
||||
#: newforms/fields.py:126 core/validators.py:120
|
||||
msgid "Enter a whole number."
|
||||
msgstr "Внеси цел број."
|
||||
|
||||
#: newforms/fields.py:128
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Ensure this value is less than or equal to %s."
|
||||
msgstr "Оваа вредноста мора да биде степен од %s."
|
||||
msgstr "Осигурајте се дека оваа вредност е помала или еднаква на %s."
|
||||
|
||||
#: newforms/fields.py:130
|
||||
#, python-format
|
||||
msgid "Ensure this value is greater than or equal to %s."
|
||||
msgstr ""
|
||||
msgstr "Осигурајте се дека оваа вредност е поголема или еднаква со %s."
|
||||
|
||||
#: newforms/fields.py:163
|
||||
#, fuzzy
|
||||
msgid "Enter a valid date."
|
||||
msgstr "Внесите правилно име на датотека."
|
||||
msgstr "Внесете правилен датум."
|
||||
|
||||
#: newforms/fields.py:190
|
||||
#, fuzzy
|
||||
msgid "Enter a valid time."
|
||||
msgstr "Внесите правилно име на датотека."
|
||||
msgstr "Внесете правилно време."
|
||||
|
||||
#: newforms/fields.py:226
|
||||
#, fuzzy
|
||||
msgid "Enter a valid date/time."
|
||||
msgstr "Внесите правилно име на датотека."
|
||||
msgstr "Внесете правилен датум со време."
|
||||
|
||||
#: newforms/fields.py:240
|
||||
#, fuzzy
|
||||
msgid "Enter a valid value."
|
||||
msgstr "Внесите правилно име на датотека."
|
||||
msgstr "Внесете правилна вредност."
|
||||
|
||||
#: newforms/fields.py:269 core/validators.py:161
|
||||
msgid "Enter a valid e-mail address."
|
||||
msgstr "Внесте правилна адреса за е-пошта."
|
||||
msgstr "Внесeте правилна адреса за е-пошта."
|
||||
|
||||
#: newforms/fields.py:287 newforms/fields.py:309
|
||||
#, fuzzy
|
||||
msgid "Enter a valid URL."
|
||||
msgstr "Внесите правилно име на датотека."
|
||||
msgstr "Внесете правилна адреса."
|
||||
|
||||
#: newforms/fields.py:311
|
||||
#, fuzzy
|
||||
msgid "This URL appears to be a broken link."
|
||||
msgstr "Адресата %s е скршена врска."
|
||||
msgstr "Оваа адреса изгледа дека не е достапна."
|
||||
|
||||
#: newforms/fields.py:359
|
||||
#, fuzzy
|
||||
msgid "Select a valid choice. That choice is not one of the available choices."
|
||||
msgstr "Изберете правилно, %(data)s' не е во %(choices)s."
|
||||
msgstr "Изберете правилно. Тоа не е едно од можните избори."
|
||||
|
||||
#: newforms/fields.py:377 newforms/fields.py:453
|
||||
#, fuzzy
|
||||
msgid "Enter a list of values."
|
||||
msgstr "Внесите правилно име на датотека."
|
||||
msgstr "Внесете листа на вредности."
|
||||
|
||||
#: newforms/fields.py:386
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Select a valid choice. %s is not one of the available choices."
|
||||
msgstr "Изберете правилно, %(data)s' не е во %(choices)s."
|
||||
msgstr "Внесете правилно. %s не е еден од достапните вредности."
|
||||
|
||||
#: template/defaultfilters.py:436
|
||||
msgid "yes,no,maybe"
|
||||
@ -2077,8 +2043,7 @@ msgstr "Оваа вредност смее да има само букви, бр
|
||||
msgid ""
|
||||
"This value must contain only letters, numbers, underscores, dashes or "
|
||||
"slashes."
|
||||
msgstr ""
|
||||
"Оваа вредност смее да има само букви, бројки, долни црти, црти или коси црти."
|
||||
msgstr "Оваа вредност смее да има само букви, бројки, долни црти, црти или коси црти."
|
||||
|
||||
#: core/validators.py:72
|
||||
msgid "This value must contain only letters, numbers, underscores or hyphens."
|
||||
@ -2127,7 +2092,7 @@ msgstr "Годината мора да биде 1900 или покасно."
|
||||
#: core/validators.py:143
|
||||
#, python-format
|
||||
msgid "Invalid date: %s."
|
||||
msgstr "Неправилен датум: %s"
|
||||
msgstr "Неправилен датум: %s."
|
||||
|
||||
#: core/validators.py:152
|
||||
msgid "Enter a valid time in HH:MM format."
|
||||
@ -2225,19 +2190,19 @@ msgid "Duplicate values are not allowed."
|
||||
msgstr "Дупликат вредности не се дозволени."
|
||||
|
||||
#: core/validators.py:364
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "This value must be between %s and %s."
|
||||
msgstr "Оваа вредноста мора да биде степен од %s."
|
||||
msgstr "Оваа вредноста мора да биде помеѓу %s и %s."
|
||||
|
||||
#: core/validators.py:366
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "This value must be at least %s."
|
||||
msgstr "Оваа вредноста мора да биде степен од %s."
|
||||
msgstr "Оваа вредноста мора да биде најмалку %s."
|
||||
|
||||
#: core/validators.py:368
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "This value must be no more than %s."
|
||||
msgstr "Оваа вредноста мора да биде степен од %s."
|
||||
msgstr "Оваа вредност не смее да биде поголема од %s."
|
||||
|
||||
#: core/validators.py:404
|
||||
#, python-format
|
||||
@ -2251,18 +2216,14 @@ msgstr "Ве молам внесете правилен децимален бр
|
||||
#: core/validators.py:419
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s total digit."
|
||||
msgid_plural ""
|
||||
"Please enter a valid decimal number with at most %s total digits."
|
||||
msgid_plural "Please enter a valid decimal number with at most %s total digits."
|
||||
msgstr[0] "Ве молам внесете правилен децимален број со најмногу %s цифрa."
|
||||
msgstr[1] ""
|
||||
"Ве молам внесете правилен децимален број со најмногу %s вкупно цифри."
|
||||
msgstr[1] "Ве молам внесете правилен децимален број со најмногу %s вкупно цифри."
|
||||
|
||||
#: core/validators.py:422
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please enter a valid decimal number with a whole part of at most %s digit."
|
||||
msgid_plural ""
|
||||
"Please enter a valid decimal number with a whole part of at most %s digits."
|
||||
msgid "Please enter a valid decimal number with a whole part of at most %s digit."
|
||||
msgid_plural "Please enter a valid decimal number with a whole part of at most %s digits."
|
||||
msgstr[0] ""
|
||||
"Ве молам внесете правилен децимален број кој во целиот број има најмногу %s "
|
||||
"цифра."
|
||||
@ -2273,12 +2234,9 @@ msgstr[1] ""
|
||||
#: core/validators.py:425
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s decimal place."
|
||||
msgid_plural ""
|
||||
"Please enter a valid decimal number with at most %s decimal places."
|
||||
msgstr[0] ""
|
||||
"Ве молам внесете правилен децимален број кој има најмногу %s децимална цифра."
|
||||
msgstr[1] ""
|
||||
"Ве молам внесете правилен децимален број кој има најмногу %s децимални цифри."
|
||||
msgid_plural "Please enter a valid decimal number with at most %s decimal places."
|
||||
msgstr[0] "Ве молам внесете правилен децимален број кој има најмногу %s децимална цифра."
|
||||
msgstr[1] "Ве молам внесете правилен децимален број кој има најмногу %s децимални цифри."
|
||||
|
||||
#: core/validators.py:435
|
||||
#, python-format
|
||||
@ -2305,10 +2263,8 @@ msgstr "Неможев да извадам ништо од %s."
|
||||
|
||||
#: core/validators.py:507
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
|
||||
msgstr ""
|
||||
"Адресата %(url)s врати неправилно заглавје Content-Type „%(contenttype)s“."
|
||||
msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
|
||||
msgstr "Адресата %(url)s врати неправилно заглавје Content-Type „%(contenttype)s“."
|
||||
|
||||
#: core/validators.py:540
|
||||
#, python-format
|
||||
@ -2360,13 +2316,5 @@ msgstr ""
|
||||
msgid ""
|
||||
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
|
||||
"starts with \"%(start)s\".)"
|
||||
msgstr ""
|
||||
"Атрибутот „%(attr)s“ на линијата %(line)s има неправилна вредност (линијата "
|
||||
"започнува со „%(start)s“)."
|
||||
msgstr "Атрибутот „%(attr)s“ на линијата %(line)s има неправилна вредност (линијата започнува со „%(start)s“)."
|
||||
|
||||
#~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
|
||||
#~ msgstr ""
|
||||
#~ "Дали ја <a href=\"/password_reset/\">заборавите вашата лозинката</a>?"
|
||||
|
||||
#~ msgid "Use '[algo]$[salt]$[hexdigest]'"
|
||||
#~ msgstr "Користи '[algo]$[salt]$[hexdigest]'"
|
||||
|
Binary file not shown.
@ -1,12 +1,12 @@
|
||||
# translation of djangojs.po to Macedonian
|
||||
#
|
||||
# Georgi Stanojevski <glisha@gmail.com>, 2006.
|
||||
# Georgi Stanojevski <glisha@gmail.com>, 2006, 2007.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: djangojs\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-02-15 10:53+1100\n"
|
||||
"PO-Revision-Date: 2006-12-04 16:18+0100\n"
|
||||
"PO-Revision-Date: 2007-02-24 13:49+0100\n"
|
||||
"Last-Translator: Georgi Stanojevski <glisha@gmail.com>\n"
|
||||
"Language-Team: Macedonian <ossm-members@hedona.on.net.mk>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -111,8 +111,9 @@ msgstr "Утре"
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
msgstr "Прикажи"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr ""
|
||||
msgstr "Скриј"
|
||||
|
||||
|
Binary file not shown.
@ -1,7 +1,9 @@
|
||||
# translation of django.po to Slovenian
|
||||
# Igor Kolar <ike@email.si), 2006.
|
||||
# Nena Kojadin <nena@kiberpipa.org), 2006.
|
||||
# Jure Cuhalev <gandalf@owca.info>, 2006.
|
||||
# Jure Cuhalev <gandalf@owca.info>, 2006, 2007.
|
||||
# Gasper Koren <gasper@fdvinfo.net>, 2007.
|
||||
# Jozko Skrablin <jozko.skrablin@gmail.com>, 2007.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
msgid ""
|
||||
@ -9,8 +11,8 @@ msgstr ""
|
||||
"Project-Id-Version: django\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-05-16 10:13+0200\n"
|
||||
"PO-Revision-Date: 2006-07-29 11:52+0100\n"
|
||||
"Last-Translator: Jure Čuhalev <gandalf@owca.info>\n"
|
||||
"PO-Revision-Date: 2007-02-15 21:47+0100\n"
|
||||
"Last-Translator: Gasper Koren <gasper@fdvinfo.net>\n"
|
||||
"Language-Team: Slovenian <lugos-slo@lugos.si>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -90,7 +92,7 @@ msgstr "je odstranjen/-a"
|
||||
|
||||
#: contrib/comments/models.py:86
|
||||
msgid "Check this box if the comment is inappropriate. A \"This comment has been removed\" message will be displayed instead."
|
||||
msgstr "Odkljukaj, če je komntar neprimeren. Namesto komentarja bo vidno obvestilo \"Ta komentar je bil odstranjen\"."
|
||||
msgstr "Odkljukaj, če je komentar neprimeren. Namesto komentarja bo vidno obvestilo \"Ta komentar je bil odstranjen\"."
|
||||
|
||||
#: contrib/comments/models.py:91
|
||||
msgid "comments"
|
||||
@ -126,7 +128,7 @@ msgstr "ip naslov"
|
||||
|
||||
#: contrib/comments/models.py:173
|
||||
msgid "approved by staff"
|
||||
msgstr "potrjeno s strani osebja"
|
||||
msgstr "osebje je potrdilo"
|
||||
|
||||
#: contrib/comments/models.py:176
|
||||
msgid "free comment"
|
||||
@ -174,7 +176,7 @@ msgstr "datum označitve (zastavice)"
|
||||
|
||||
#: contrib/comments/models.py:268
|
||||
msgid "user flag"
|
||||
msgstr "uporabnikova zastavica"
|
||||
msgstr "uporabniška zastavica"
|
||||
|
||||
#: contrib/comments/models.py:269
|
||||
msgid "user flags"
|
||||
@ -204,7 +206,7 @@ msgstr "Izbris opravil moderator %r"
|
||||
|
||||
#: contrib/comments/views/karma.py:19
|
||||
msgid "Anonymous users cannot vote"
|
||||
msgstr "Anonimni upirabniki ne morejo glasovati"
|
||||
msgstr "Anonimni uporabniki ne morejo glasovati"
|
||||
|
||||
#: contrib/comments/views/karma.py:23
|
||||
msgid "Invalid comment ID"
|
||||
@ -216,7 +218,7 @@ msgstr "Ni mogoče glasovati zase"
|
||||
|
||||
#: contrib/comments/views/comments.py:28
|
||||
msgid "This rating is required because you've entered at least one other rating."
|
||||
msgstr "Moraš podati tole oceno, ker si podal vsaj še eno drugo oceno."
|
||||
msgstr "To oceno moraš podati, ker si podal vsaj še eno drugo oceno."
|
||||
|
||||
#: contrib/comments/views/comments.py:112
|
||||
#, python-format
|
||||
@ -233,17 +235,17 @@ msgstr[0] ""
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr[1] ""
|
||||
"Ta komentar je poslal uporabnik, ki je do zdaj poslal manj kot %(count)s komentar:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr[2] ""
|
||||
"Ta komentar je poslal uporabnik, ki je do zdaj poslal manj kot %(count)s komentarja:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr[3] ""
|
||||
msgstr[2] ""
|
||||
"Ta komentar je poslal uporabnik, ki je do zdaj poslal manj kot %(count)s komentarje:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr[3] ""
|
||||
"Ta komentar je poslal uporabnik, ki je do zdaj poslal manj kot %(count)s komentarjev:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
|
||||
#: contrib/comments/views/comments.py:117
|
||||
#, python-format
|
||||
@ -259,7 +261,7 @@ msgstr ""
|
||||
#: contrib/comments/views/comments.py:189
|
||||
#: contrib/comments/views/comments.py:280
|
||||
msgid "Only POSTs are allowed"
|
||||
msgstr "Dovoljena je le metoda POST"
|
||||
msgstr "Dovoljena je le POST metoda"
|
||||
|
||||
#: contrib/comments/views/comments.py:193
|
||||
#: contrib/comments/views/comments.py:284
|
||||
@ -398,7 +400,7 @@ msgstr "Neznano"
|
||||
|
||||
#: contrib/admin/models.py:16
|
||||
msgid "action time"
|
||||
msgstr "čas oprave dejanja"
|
||||
msgstr "čas dejanja"
|
||||
|
||||
#: contrib/admin/models.py:19
|
||||
msgid "object id"
|
||||
@ -410,7 +412,7 @@ msgstr "predstavitev objekta"
|
||||
|
||||
#: contrib/admin/models.py:21
|
||||
msgid "action flag"
|
||||
msgstr "zastavica za določeno dejanje"
|
||||
msgstr "zastavica dejanja"
|
||||
|
||||
#: contrib/admin/models.py:22
|
||||
msgid "change message"
|
||||
@ -432,7 +434,7 @@ msgstr "Vsi datumi"
|
||||
#: contrib/auth/forms.py:36
|
||||
#: contrib/auth/forms.py:41
|
||||
msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
|
||||
msgstr "Prosimo, vnesite veljavno uporabniško ime in geslo. Opomba: obe polji sta občutljivi na velikost črk"
|
||||
msgstr "Prosimo, vnesite veljavno uporabniško ime in geslo. Opomba: obe polji upoštevata velikost črk."
|
||||
|
||||
#: contrib/admin/views/decorators.py:23
|
||||
#: contrib/admin/templates/admin/login.html:25
|
||||
@ -441,11 +443,11 @@ msgstr "Prijavite se"
|
||||
|
||||
#: contrib/admin/views/decorators.py:61
|
||||
msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
|
||||
msgstr "Vaša seja je pretekla; prosimo, prijavite se znova. Ne skrbite, vaše objave so varno shranjene."
|
||||
msgstr "Vaša seja je pretekla; prosimo da se ponovno prijavite. Brez skrbi, vaše objave so varno shranjene."
|
||||
|
||||
#: contrib/admin/views/decorators.py:68
|
||||
msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
|
||||
msgstr "Izgleda, da vaš brskalnik nima podpore za piškotke. Prosimo, vključite piškotke, znova naložite to stran in poskusite še enkrat."
|
||||
msgstr "Izgleda, da vaš brskalnik nima podpore za piškotke. Prosimo, vključite piškotke, osvežite stran in poskusite še enkrat."
|
||||
|
||||
#: contrib/admin/views/decorators.py:82
|
||||
msgid "Usernames cannot contain the '@' character."
|
||||
@ -454,7 +456,7 @@ msgstr "Uporabniška imena ne smejo vsebovati znaka '@'."
|
||||
#: contrib/admin/views/decorators.py:84
|
||||
#, python-format
|
||||
msgid "Your e-mail address is not your username. Try '%s' instead."
|
||||
msgstr "Vaš e-mail naslov ne morete uporabljati kot uporabniško ime. Namesto tega uporabite '%s'."
|
||||
msgstr "Vaš e-main naslov ni vaše uporabniško ime. Poskusite uporabiti '%s'."
|
||||
|
||||
#: contrib/admin/views/main.py:226
|
||||
msgid "Site administration"
|
||||
@ -484,7 +486,7 @@ msgstr "Dodaj %s"
|
||||
#: contrib/admin/views/main.py:336
|
||||
#, python-format
|
||||
msgid "Added %s."
|
||||
msgstr "Dodal %s."
|
||||
msgstr "Dodan %s."
|
||||
|
||||
#: contrib/admin/views/main.py:336
|
||||
#: contrib/admin/views/main.py:338
|
||||
@ -495,12 +497,12 @@ msgstr "in"
|
||||
#: contrib/admin/views/main.py:338
|
||||
#, python-format
|
||||
msgid "Changed %s."
|
||||
msgstr "Spremenil %s."
|
||||
msgstr "Spremenjen %s."
|
||||
|
||||
#: contrib/admin/views/main.py:340
|
||||
#, python-format
|
||||
msgid "Deleted %s."
|
||||
msgstr "Izbrisal %s."
|
||||
msgstr "Izbrisn %s."
|
||||
|
||||
#: contrib/admin/views/main.py:343
|
||||
msgid "No fields changed."
|
||||
@ -509,12 +511,12 @@ msgstr "Nobeno polje ni bilo spremenjeno."
|
||||
#: contrib/admin/views/main.py:346
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was changed successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" je bilo uspešno spremenjeno."
|
||||
msgstr "%(name)s \"%(obj)s\" je bil uspešno spremenjeno."
|
||||
|
||||
#: contrib/admin/views/main.py:354
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr "%(name)s \"%(obj)s\" je bilo uspešno dodano. Znova ga lahko urejate spodaj."
|
||||
msgstr "%(name)s \"%(obj)s\" je bil uspešno dodano. Ponovno ga lahko urejdite spodaj."
|
||||
|
||||
#: contrib/admin/views/main.py:392
|
||||
#, python-format
|
||||
@ -534,7 +536,7 @@ msgstr "Eden ali več %(fieldname)s v %(name)s:"
|
||||
#: contrib/admin/views/main.py:508
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was deleted successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" je bilo uspešno izbrisano."
|
||||
msgstr "%(name)s \"%(obj)s\" je bilo uspešno izbrisan."
|
||||
|
||||
#: contrib/admin/views/main.py:511
|
||||
msgid "Are you sure?"
|
||||
@ -562,11 +564,11 @@ msgstr "Izberite %s, ki ga želite spremeniti"
|
||||
#: contrib/admin/views/doc.py:295
|
||||
#: contrib/admin/views/doc.py:297
|
||||
msgid "Integer"
|
||||
msgstr "Število (integer)"
|
||||
msgstr "Celo število (integer)"
|
||||
|
||||
#: contrib/admin/views/doc.py:278
|
||||
msgid "Boolean (Either True or False)"
|
||||
msgstr "Boolean (ali True ali False)"
|
||||
msgstr "Boolean (True ali False)"
|
||||
|
||||
#: contrib/admin/views/doc.py:279
|
||||
#: contrib/admin/views/doc.py:296
|
||||
@ -576,19 +578,19 @@ msgstr "Niz (vse do %(maxlength)s)"
|
||||
|
||||
#: contrib/admin/views/doc.py:280
|
||||
msgid "Comma-separated integers"
|
||||
msgstr "Z vejico ločeni integerji"
|
||||
msgstr "Z vejico ločena cela števila (integer)"
|
||||
|
||||
#: contrib/admin/views/doc.py:281
|
||||
msgid "Date (without time)"
|
||||
msgstr "Datum (brez časa)"
|
||||
msgstr "Datum (brez ure)"
|
||||
|
||||
#: contrib/admin/views/doc.py:282
|
||||
msgid "Date (with time)"
|
||||
msgstr "Datum (s časom)"
|
||||
msgstr "Datum (z uro)"
|
||||
|
||||
#: contrib/admin/views/doc.py:283
|
||||
msgid "E-mail address"
|
||||
msgstr "E-naslov"
|
||||
msgstr "E-mail naslov"
|
||||
|
||||
#: contrib/admin/views/doc.py:284
|
||||
#: contrib/admin/views/doc.py:287
|
||||
@ -601,7 +603,7 @@ msgstr "Decimalno število"
|
||||
|
||||
#: contrib/admin/views/doc.py:291
|
||||
msgid "Boolean (Either True, False or None)"
|
||||
msgstr "Boolean (ali True ali False ali None)"
|
||||
msgstr "Boolean (True, False ali None)"
|
||||
|
||||
#: contrib/admin/views/doc.py:292
|
||||
msgid "Relation to parent model"
|
||||
@ -701,11 +703,11 @@ msgstr "N j, Y, H:i"
|
||||
|
||||
#: 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 "Ta objekt nima zgodovine. Verjetno ni bil dodan preko te administratorske strani."
|
||||
msgstr "Ta objekt nima zgodovine sprememb. Verjetno ni bil dodan preko te strani za administracijo."
|
||||
|
||||
#: contrib/admin/templates/admin/base_site.html:4
|
||||
msgid "Django site admin"
|
||||
msgstr "Django site admin"
|
||||
msgstr "Vmesnik za administracijo Django strani"
|
||||
|
||||
#: contrib/admin/templates/admin/base_site.html:7
|
||||
msgid "Django administration"
|
||||
@ -717,7 +719,7 @@ msgstr "Napaka strežnika"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:6
|
||||
msgid "Server error (500)"
|
||||
msgstr "Django napaka (500)"
|
||||
msgstr "Napaka strežnika (500)"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:9
|
||||
msgid "Server Error <em>(500)</em>"
|
||||
@ -725,7 +727,7 @@ msgstr "Napaka strežnika <em>(500)</em>"
|
||||
|
||||
#: 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 "Prišlo je do nepričakovane napake. Administratorji strani so že obveščeni prekoe-pošte in naj bi jo v kratkem odpravili. Hvala za vaše potrpljenje."
|
||||
msgstr "Prišlo je do nepričakovane napake. Administrator je preko e-pošte prejel obvestilo o napaki in jo bo v kratkem odpravil. Hvala za potrpljenje."
|
||||
|
||||
#: contrib/admin/templates/admin/404.html:4
|
||||
#: contrib/admin/templates/admin/404.html:8
|
||||
@ -734,7 +736,7 @@ msgstr "Strani ni mogoče najti"
|
||||
|
||||
#: contrib/admin/templates/admin/404.html:10
|
||||
msgid "We're sorry, but the requested page could not be found."
|
||||
msgstr "Se opravičujemo, a zahtevane strani ni mogoče najti."
|
||||
msgstr "Opravičujemo se, a zahtevane strani ni mogoče najti."
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:17
|
||||
#, python-format
|
||||
@ -773,7 +775,7 @@ msgstr "Dodaj %(name)s"
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:22
|
||||
msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
|
||||
msgstr "Ste <a href=\"/password_reset/\">pozabili geslo</a>"
|
||||
msgstr "Ste <a href=\"/password_reset/\">pozabili geslo</a>?"
|
||||
|
||||
#: contrib/admin/templates/admin/base.html:23
|
||||
msgid "Welcome,"
|
||||
@ -787,7 +789,7 @@ msgstr "Izbriši"
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:14
|
||||
#, python-format
|
||||
msgid "Deleting the %(object_name)s '%(object)s' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:"
|
||||
msgstr "Izbris %(object_name)s '%(object)s' bi pomenil izbris povezanih objektov, vendarvi nimate dovoljenja za izbris naslednjih tipov objektov:"
|
||||
msgstr "Izbris %(object_name)s '%(object)s' bi pomenil izbris povezanih objektov, vendar nimate dovoljenja za izbris naslednjih tipov objektov:"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:21
|
||||
#, python-format
|
||||
@ -815,17 +817,17 @@ msgstr "Poglej na strani"
|
||||
msgid "Please correct the error below."
|
||||
msgid_plural "Please correct the errors below."
|
||||
msgstr[0] "Prosimo, odpravite sledečo napako."
|
||||
msgstr[1] "Prosimo, odpravite sledeče napake."
|
||||
msgstr[2] "Prosimo, odpravite sledeči napaki."
|
||||
msgstr[1] "Prosimo, odpravite sledeči napaki."
|
||||
msgstr[2] "Prosimo, odpravite sledeče napake."
|
||||
msgstr[3] "Prosimo, odpravite sledeče napake."
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:48
|
||||
msgid "Ordering"
|
||||
msgstr "Urejanje"
|
||||
msgstr "Razvrščanje"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:51
|
||||
msgid "Order:"
|
||||
msgstr "Uredi:"
|
||||
msgstr "Razvrsti:"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:4
|
||||
msgid "Save as new"
|
||||
@ -853,7 +855,7 @@ msgstr "Sprememba gesla"
|
||||
#: contrib/admin/templates/registration/password_change_done.html:6
|
||||
#: contrib/admin/templates/registration/password_change_done.html:10
|
||||
msgid "Password change successful"
|
||||
msgstr "Geslo uspešno spremenjeno"
|
||||
msgstr "Sprememba gesla je uspela"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_done.html:12
|
||||
msgid "Your password was changed."
|
||||
@ -864,23 +866,23 @@ msgstr "Vaše geslo je bilo spremenjeno."
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:10
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:4
|
||||
msgid "Password reset"
|
||||
msgstr "Obnova gesla"
|
||||
msgstr "Ponastavitev gesla"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:12
|
||||
msgid "Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you."
|
||||
msgstr "Ste pozabili geslo? Vnesite vaš e-naslov spodaj in mi vam bomo poslali novo geslo."
|
||||
msgstr "Ste pozabili geslo? Vnesite vaš e-mail naslov in poslali vam bomo novo geslo."
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:16
|
||||
msgid "E-mail address:"
|
||||
msgstr "E-naslov"
|
||||
msgstr "Naslov e-pošte:"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:16
|
||||
msgid "Reset my password"
|
||||
msgstr "Obnova gesla"
|
||||
msgstr "Ponastavi moje geslo"
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:8
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
msgstr "Hvala, ker ste si vzeli nekaj časa za to spletno stran."
|
||||
msgstr "Hvala, ker ste si danes vzeli nekaj časa za to spletno stran."
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:10
|
||||
msgid "Log in again"
|
||||
@ -889,15 +891,15 @@ msgstr "Ponovna prijava"
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:6
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:10
|
||||
msgid "Password reset successful"
|
||||
msgstr "Geslo je bilo uspešno obnovljeno"
|
||||
msgstr "Ponastavitev gesla je uspela"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:12
|
||||
msgid "We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly."
|
||||
msgstr "Po e-pošti smo vam poslali novo geslo.Morali bi ga prejeti v kratkem"
|
||||
msgstr "Po e-pošti smo vam poslali novo geslo. Morali bi ga prejeti v kratkem"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_form.html:12
|
||||
msgid "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly."
|
||||
msgstr "Prosim, vnesite vaše staro geslo (zaradi varnosti) in nato še dvakrat novo(da preverimo, da se niste zatipkali)"
|
||||
msgstr "Prosim, vnesite vaše staro geslo (zaradi varnosti) in nato še dvakrat novo (da preverimo, da se niste zatipkali)"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_form.html:17
|
||||
msgid "Old password:"
|
||||
@ -913,16 +915,16 @@ msgstr "Potrditev gesla:"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_form.html:23
|
||||
msgid "Change my password"
|
||||
msgstr "Sprememba gesla"
|
||||
msgstr "Spremeni moje geslo"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:2
|
||||
msgid "You're receiving this e-mail because you requested a password reset"
|
||||
msgstr "To pošto ste dobili, ker ste zahtevali spremembo gesla"
|
||||
msgstr "Ta e-mail ste dobili, ker ste zahtevali ponastavitev gesla"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:3
|
||||
#, python-format
|
||||
msgid "for your user account at %(site_name)s"
|
||||
msgstr "za vaš uporabniški račun pri %(site_name)s"
|
||||
msgstr "za vaš uporabniški račun na %(site_name)s"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:5
|
||||
#, python-format
|
||||
@ -935,7 +937,7 @@ msgstr "Geslo lahko spremenite z obiskom strani:"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:11
|
||||
msgid "Your username, in case you've forgotten:"
|
||||
msgstr "Vaše uporabniško ime (za vsak primer)"
|
||||
msgstr "Vaše uporabniško ime (za vsak primer):"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:13
|
||||
msgid "Thanks for using our site!"
|
||||
@ -955,6 +957,7 @@ msgid "Documentation bookmarklets"
|
||||
msgstr "Dokumentacijske zaznamkice"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:9
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"\n"
|
||||
"<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n"
|
||||
@ -966,11 +969,11 @@ msgid ""
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p class=\"help\">Za inštalacijo zaznamkic povlečite povezavo v orodno vrstico\n"
|
||||
"z zaznamki, ali kliknite z desno miškino tipko na povezavo in jo dodajte med zaznamkeZdaj lahko uporabite zaznamek s katere koli strani. Opomba: nekatere teh stranilahko gledate le z internega računalnika (preverite s sistemskim administratorjem)</p>\n"
|
||||
"z zaznamki, ali kliknite z desno miškino tipko na povezavo in jo dodajte med zaznamke. Zdaj lahko izberete zaznamkico s katerekoli strani. Opomba: nekatere izmed teh strani lahko gledate le z računalnika, ki je označen kot \"notranji\" (v kolikor niste prepričani, če je vaš računalnik označen kot \"notranji\"se obrnite na sistemskega administratorja).</p>\n"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:19
|
||||
msgid "Documentation for this page"
|
||||
msgstr "Dokumentacija za to stran"
|
||||
msgstr "Dokumentacija te strani"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:20
|
||||
msgid "Jumps you from any page to the documentation for the view that generates that page."
|
||||
@ -986,7 +989,7 @@ msgstr "Pokaže content-type in unikatni ID za strani, ki predstavljajo en objek
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:25
|
||||
msgid "Edit this object (current window)"
|
||||
msgstr "Uredi trenutni objekt (v trenutnem oknu)"
|
||||
msgstr "Uredi objekt (v trenutnem oknu)"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:26
|
||||
msgid "Jumps to the admin page for pages that represent a single object."
|
||||
@ -1006,7 +1009,7 @@ msgstr "Datum:"
|
||||
|
||||
#: contrib/admin/templates/widget/date_time.html:4
|
||||
msgid "Time:"
|
||||
msgstr "Čas:"
|
||||
msgstr "Ura:"
|
||||
|
||||
#: contrib/admin/templates/widget/file.html:2
|
||||
msgid "Currently:"
|
||||
@ -1022,7 +1025,7 @@ msgstr "preusmeritev iz"
|
||||
|
||||
#: contrib/redirects/models.py:8
|
||||
msgid "This should be an absolute path, excluding the domain name. Example: '/events/search/'."
|
||||
msgstr "To mora biti absolutna pot, izključujoč domeno. Primer: '/events/search'-"
|
||||
msgstr "Ta pot mora biti absolutna, brez imena domene. Primer: '/events/search'"
|
||||
|
||||
#: contrib/redirects/models.py:9
|
||||
msgid "redirect to"
|
||||
@ -1030,7 +1033,7 @@ msgstr "preusmeri na"
|
||||
|
||||
#: contrib/redirects/models.py:10
|
||||
msgid "This can be either an absolute path (as above) or a full URL starting with 'http://'."
|
||||
msgstr "To je ali absolutna pot (kot zgoraj) ali popoln URL naslov (začne se z 'http://')"
|
||||
msgstr "To je lahko absolutna pot (kot zgoraj) ali popoln URL naslov (ki se začne s 'http://')"
|
||||
|
||||
#: contrib/redirects/models.py:12
|
||||
msgid "redirect"
|
||||
@ -1042,7 +1045,7 @@ msgstr "preusmeritve"
|
||||
|
||||
#: contrib/flatpages/models.py:8
|
||||
msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
|
||||
msgstr "Primer: '/about/contact/'. Mora vsebovati / (poševnico) na začetku in koncu."
|
||||
msgstr "Primer: '/about/contact/'. Preverite ali vsebuje / (poševnico) na začetku in koncu vnosa."
|
||||
|
||||
#: contrib/flatpages/models.py:9
|
||||
msgid "title"
|
||||
@ -1070,7 +1073,7 @@ msgstr "obvezna registracija"
|
||||
|
||||
#: contrib/flatpages/models.py:14
|
||||
msgid "If this is checked, only logged-in users will be able to view the page."
|
||||
msgstr "Če je to polje odkljukano, si lahko to stran ogledajo le registrirani uporabniki."
|
||||
msgstr "Če je to polje izbrano, si bodo to stran lahko ogledali le prijavljeni uporabniki."
|
||||
|
||||
#: contrib/flatpages/models.py:18
|
||||
msgid "flat page"
|
||||
@ -1121,7 +1124,7 @@ msgstr "priimek"
|
||||
|
||||
#: contrib/auth/models.py:58
|
||||
msgid "e-mail address"
|
||||
msgstr "e-naslov"
|
||||
msgstr "e-mail naslov"
|
||||
|
||||
#: contrib/auth/models.py:59
|
||||
msgid "password"
|
||||
@ -1157,7 +1160,7 @@ msgstr "član od"
|
||||
|
||||
#: contrib/auth/models.py:66
|
||||
msgid "In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."
|
||||
msgstr "Polek ročno določenih dovoljenj bo ta uporabnik dobil tudi vsa dovoljenja,ki pripadajo vsem skupinah, v katerih je."
|
||||
msgstr "Poleg ročno določenih dovoljenj bo ta uporabnik dobil tudi vsa dovoljenja, ki pripadajo skupinam, katerih član je."
|
||||
|
||||
#: contrib/auth/models.py:67
|
||||
msgid "user permissions"
|
||||
@ -1201,19 +1204,19 @@ msgstr "python ime razreda modela"
|
||||
|
||||
#: contrib/contenttypes/models.py:28
|
||||
msgid "content type"
|
||||
msgstr "content type"
|
||||
msgstr "tip vsebine"
|
||||
|
||||
#: contrib/contenttypes/models.py:29
|
||||
msgid "content types"
|
||||
msgstr "content types"
|
||||
msgstr "tipi vsebine"
|
||||
|
||||
#: contrib/sessions/models.py:35
|
||||
msgid "session key"
|
||||
msgstr "sejni ključ"
|
||||
msgstr "ključ seje"
|
||||
|
||||
#: contrib/sessions/models.py:36
|
||||
msgid "session data"
|
||||
msgstr "podatki v seji"
|
||||
msgstr "podatki seje"
|
||||
|
||||
#: contrib/sessions/models.py:37
|
||||
msgid "expire date"
|
||||
@ -1415,50 +1418,50 @@ msgstr "dec."
|
||||
#: utils/timesince.py:12
|
||||
msgid "year"
|
||||
msgid_plural "years"
|
||||
msgstr[0] "let"
|
||||
msgstr[1] "leto"
|
||||
msgstr[2] "leti"
|
||||
msgstr[3] "leta"
|
||||
msgstr[0] "leto"
|
||||
msgstr[1] "leti"
|
||||
msgstr[2] "leta"
|
||||
msgstr[3] "let"
|
||||
|
||||
#: utils/timesince.py:13
|
||||
msgid "month"
|
||||
msgid_plural "months"
|
||||
msgstr[0] "mesecev"
|
||||
msgstr[1] "mesec"
|
||||
msgstr[2] "meseca"
|
||||
msgstr[3] "meseci"
|
||||
msgstr[0] "mesec"
|
||||
msgstr[1] "meseca"
|
||||
msgstr[2] "meseci"
|
||||
msgstr[3] "mesecev"
|
||||
|
||||
#: utils/timesince.py:14
|
||||
msgid "week"
|
||||
msgid_plural "weeks"
|
||||
msgstr[0] "tednov"
|
||||
msgstr[1] "teden"
|
||||
msgstr[2] "tedna"
|
||||
msgstr[0] "teden"
|
||||
msgstr[1] "tedna"
|
||||
msgstr[2] "tedni"
|
||||
msgstr[3] "tednov"
|
||||
|
||||
#: utils/timesince.py:15
|
||||
msgid "day"
|
||||
msgid_plural "days"
|
||||
msgstr[0] "dni"
|
||||
msgstr[1] "dan"
|
||||
msgstr[2] "dneva"
|
||||
msgstr[0] "dan"
|
||||
msgstr[1] "dneva"
|
||||
msgstr[2] "dnevi"
|
||||
msgstr[3] "dni"
|
||||
|
||||
#: utils/timesince.py:16
|
||||
msgid "hour"
|
||||
msgid_plural "hours"
|
||||
msgstr[0] "ur"
|
||||
msgstr[1] "ura"
|
||||
msgstr[2] "uri"
|
||||
msgstr[3] "ure"
|
||||
msgstr[0] "ura"
|
||||
msgstr[1] "uri"
|
||||
msgstr[2] "ure"
|
||||
msgstr[3] "ur"
|
||||
|
||||
#: utils/timesince.py:17
|
||||
msgid "minute"
|
||||
msgid_plural "minutes"
|
||||
msgstr[0] "minut"
|
||||
msgstr[1] "minuta"
|
||||
msgstr[2] "minuti"
|
||||
msgstr[3] "minute"
|
||||
msgstr[0] "minuta"
|
||||
msgstr[1] "minuti"
|
||||
msgstr[2] "minute"
|
||||
msgstr[3] "minut"
|
||||
|
||||
#: conf/global_settings.py:37
|
||||
msgid "Bengali"
|
||||
@ -1562,7 +1565,7 @@ msgstr "Ukrajinski"
|
||||
|
||||
#: conf/global_settings.py:62
|
||||
msgid "Simplified Chinese"
|
||||
msgstr "Poenostavljen kitajski"
|
||||
msgstr "Poenostavljeni kitajski"
|
||||
|
||||
#: conf/global_settings.py:63
|
||||
msgid "Traditional Chinese"
|
||||
@ -1570,27 +1573,27 @@ msgstr "Tradicionalni kitajski"
|
||||
|
||||
#: core/validators.py:60
|
||||
msgid "This value must contain only letters, numbers and underscores."
|
||||
msgstr "To polje lahko vsebuje le črke, števila in podčrtaje (_)."
|
||||
msgstr "Ta vrednost mora vsebovati le črke, števila in podčrtaje (_)."
|
||||
|
||||
#: core/validators.py:64
|
||||
msgid "This value must contain only letters, numbers, underscores, dashes or slashes."
|
||||
msgstr "To polje lahko vsebuje le črke, števila, podčrtaje, poševnice ali pomišljaje."
|
||||
msgstr "Ta vrednost mora vsebovati le črke, števila, podčrtaje, poševnice ali pomišljaje."
|
||||
|
||||
#: core/validators.py:72
|
||||
msgid "Uppercase letters are not allowed here."
|
||||
msgstr "Velike tiskane črke tu niso dovoljene."
|
||||
msgstr "Velike tiskane črke niso dovoljene."
|
||||
|
||||
#: core/validators.py:76
|
||||
msgid "Lowercase letters are not allowed here."
|
||||
msgstr "Majhne tiskane črke tu niso dovoljene."
|
||||
msgstr "Majhne tiskane črke niso dovoljene."
|
||||
|
||||
#: core/validators.py:83
|
||||
msgid "Enter only digits separated by commas."
|
||||
msgstr "Vnesite števila, ločena z vejicami."
|
||||
msgstr "Vnesite samo števila, ločena z vejicami."
|
||||
|
||||
#: core/validators.py:95
|
||||
msgid "Enter valid e-mail addresses separated by commas."
|
||||
msgstr "Vnesite veljavne e-pošne naslove, ločene z vejicami."
|
||||
msgstr "Vnesite veljavne e-mail naslove, ločene z vejicami."
|
||||
|
||||
#: core/validators.py:99
|
||||
msgid "Please enter a valid IP address."
|
||||
@ -1602,11 +1605,11 @@ msgstr "Prazne vrednosti tu niso dovoljene."
|
||||
|
||||
#: core/validators.py:107
|
||||
msgid "Non-numeric characters aren't allowed here."
|
||||
msgstr "Nenumerične vrednosti tukaj niso dovoljne."
|
||||
msgstr "Nenumerični znaki tukaj niso dovoljne."
|
||||
|
||||
#: core/validators.py:111
|
||||
msgid "This value can't be comprised solely of digits."
|
||||
msgstr "To polje ne sme vsebovati le števk."
|
||||
msgstr "Ta vrednost ne sme vsebovati le števk."
|
||||
|
||||
#: core/validators.py:116
|
||||
msgid "Enter a whole number."
|
||||
@ -1614,7 +1617,7 @@ msgstr "Vnesite celo število."
|
||||
|
||||
#: core/validators.py:120
|
||||
msgid "Only alphabetical characters are allowed here."
|
||||
msgstr "Le črke iz abecede so dovoljene tukaj."
|
||||
msgstr "Tukaj so dovoljene samo črke."
|
||||
|
||||
#: core/validators.py:124
|
||||
msgid "Enter a valid date in YYYY-MM-DD format."
|
||||
@ -1631,11 +1634,11 @@ msgstr "Vnesite veljavni datum/čas v zapisu YYYY-MM-DD HH:MM (leto-mesec-dan ur
|
||||
|
||||
#: core/validators.py:136
|
||||
msgid "Enter a valid e-mail address."
|
||||
msgstr "Vnesite veljavni e-naslov."
|
||||
msgstr "Vnesite veljaven e-mail."
|
||||
|
||||
#: core/validators.py:148
|
||||
msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
|
||||
msgstr "Uploadjate veljavno sliko. Trenutna datoteka ni bila niti slika niti okvarjena slika."
|
||||
msgstr "Naložite veljavno sliko. Naložena datoteka ni bila slika ali pa je bila le-ta okvarjena."
|
||||
|
||||
#: core/validators.py:155
|
||||
#, python-format
|
||||
@ -1654,7 +1657,7 @@ msgstr "URL %s ne kaže na veljavni QuickTime video."
|
||||
|
||||
#: core/validators.py:171
|
||||
msgid "A valid URL is required."
|
||||
msgstr "Potreben je veljavni URL naslov."
|
||||
msgstr "Potreben je veljaven URL naslov."
|
||||
|
||||
#: core/validators.py:185
|
||||
#, python-format
|
||||
@ -1662,24 +1665,24 @@ msgid ""
|
||||
"Valid HTML is required. Specific errors are:\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
"Potreben je veljavni HTML. Trenutni ima sledeče napake:\n"
|
||||
"Potreben je veljaven HTML. Trenutni ima sledeče napake:\n"
|
||||
"%s"
|
||||
|
||||
#: core/validators.py:192
|
||||
#, python-format
|
||||
msgid "Badly formed XML: %s"
|
||||
msgstr "Pokvarjen XML: %s"
|
||||
msgstr "Nepravilen XML: %s"
|
||||
|
||||
#: core/validators.py:202
|
||||
#, python-format
|
||||
msgid "Invalid URL: %s"
|
||||
msgstr "Neveljavni URL naslov: %s"
|
||||
msgstr "Neveljaven URL naslov: %s"
|
||||
|
||||
#: core/validators.py:206
|
||||
#: core/validators.py:208
|
||||
#, python-format
|
||||
msgid "The URL %s is a broken link."
|
||||
msgstr "URL povezava %s je polomljena."
|
||||
msgstr "URL povezava %s ne deluje."
|
||||
|
||||
#: core/validators.py:214
|
||||
msgid "Enter a valid U.S. state abbreviation."
|
||||
@ -1690,7 +1693,7 @@ msgstr "Vnesi veljavno okrajšavo za ameriško zvezno državo."
|
||||
msgid "Watch your mouth! The word %s is not allowed here."
|
||||
msgid_plural "Watch your mouth! The words %s are not allowed here."
|
||||
msgstr[0] "Pazite na jezik! Beseda %s tu ni dovoljena."
|
||||
msgstr[1] "Pazite na jezik! Besede %s tu niso dovoljene."
|
||||
msgstr[1] "Pazite na jezik! Besedi %s tu nista dovoljeni."
|
||||
msgstr[2] "Pazite na jezik! Besede %s tu niso dovoljene."
|
||||
msgstr[3] "Pazite na jezik! Besede %s tu niso dovoljene."
|
||||
|
||||
@ -1701,22 +1704,22 @@ msgstr "To polje mora ustrezati polju '%s'."
|
||||
|
||||
#: core/validators.py:255
|
||||
msgid "Please enter something for at least one field."
|
||||
msgstr "Prosim, vnesite nekaj v vsaj eno od polj."
|
||||
msgstr "Prosim, vnesite nekaj v vsaj eno izmed polj."
|
||||
|
||||
#: core/validators.py:264
|
||||
#: core/validators.py:275
|
||||
msgid "Please enter both fields or leave them both empty."
|
||||
msgstr "Prosimo, izpolnite obe polji ali ju pustite obe prazni."
|
||||
msgstr "Prosimo, izpolnite obe polji ali pa pustite obe prazni."
|
||||
|
||||
#: core/validators.py:282
|
||||
#, python-format
|
||||
msgid "This field must be given if %(field)s is %(value)s"
|
||||
msgstr "To polje mora biti izpolnjeno, če je %(field)s %(value)s"
|
||||
msgstr "To polje mora biti podano, če je %(field)s %(value)s"
|
||||
|
||||
#: core/validators.py:294
|
||||
#, python-format
|
||||
msgid "This field must be given if %(field)s is not %(value)s"
|
||||
msgstr "To polje mora biti izpolnjeno, če ni %(field)s %(value)s"
|
||||
msgstr "To polje mora biti podano, če ni %(field)s %(value)s"
|
||||
|
||||
#: core/validators.py:313
|
||||
msgid "Duplicate values are not allowed."
|
||||
@ -1729,7 +1732,7 @@ msgstr "Ta vrednost mora biti potenca od %s."
|
||||
|
||||
#: core/validators.py:347
|
||||
msgid "Please enter a valid decimal number."
|
||||
msgstr "Prosim vnesite decimalno število."
|
||||
msgstr "Prosim vnesite veljavno decimalno število."
|
||||
|
||||
#: core/validators.py:349
|
||||
#, python-format
|
||||
@ -1745,19 +1748,19 @@ msgstr[3] "Prosimo, vnesite veljavno decimalno število z največ %s števkami."
|
||||
msgid "Please enter a valid decimal number with at most %s decimal place."
|
||||
msgid_plural "Please enter a valid decimal number with at most %s decimal places."
|
||||
msgstr[0] "Prosimo, vnesite veljavno decimalno število z največ %s decimalnim mestom."
|
||||
msgstr[1] "Prosimo, vnesite veljavno decimalno število z največ %s decimalnimi mesti."
|
||||
msgstr[1] "Prosimo, vnesite veljavno decimalno število z največ %s decimalnima mestoma."
|
||||
msgstr[2] "Prosimo, vnesite veljavno decimalno število z največ %s decimalnimi mesti."
|
||||
msgstr[3] "Prosimo, vnesite veljavno decimalno število z največ %s decimalnimi mesti."
|
||||
|
||||
#: core/validators.py:362
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at least %s bytes big."
|
||||
msgstr "Prosimo, poskrbite, da bo prenesena datoteka velika vsaj %s bajtov."
|
||||
msgstr "Prosimo, poskrbite, da bo naložena datoteka velika vsaj %s bajtov."
|
||||
|
||||
#: core/validators.py:363
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at most %s bytes big."
|
||||
msgstr "Poskrbite, da bo prenesena datoteka velika največ %s bajtov."
|
||||
msgstr "Poskrbite, da bo naložena datoteka velika največ %s bajtov."
|
||||
|
||||
#: core/validators.py:376
|
||||
msgid "The format for this field is wrong."
|
||||
@ -1770,7 +1773,7 @@ msgstr "To polje ni veljavno."
|
||||
#: core/validators.py:426
|
||||
#, python-format
|
||||
msgid "Could not retrieve anything from %s."
|
||||
msgstr "Iz %s nisem mogel izločiti ničesar."
|
||||
msgstr "Iz %s nisem mogel pridobiti ničesar."
|
||||
|
||||
#: core/validators.py:429
|
||||
#, python-format
|
||||
@ -1780,7 +1783,7 @@ msgstr "URL %(url)s je vrnil neveljavni Content-Type '%(contenttype)s'."
|
||||
#: core/validators.py:462
|
||||
#, python-format
|
||||
msgid "Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with \"%(start)s\".)"
|
||||
msgstr "Prosimo, zaprite nezaprto %(tag)s oznako v vrstici %(line)s. (Vrstica se začne z \"%(start)s\".)"
|
||||
msgstr "Prosimo, zaprite %(tag)s oznako v vrstici %(line)s. (Vrstica se začne z \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:466
|
||||
#, python-format
|
||||
@ -1790,7 +1793,7 @@ msgstr "Tekst z začetka vrstice %(line)s ni dovoljen v tem kontekstu. (Vrstica
|
||||
#: core/validators.py:471
|
||||
#, python-format
|
||||
msgid "\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%(start)s\".)"
|
||||
msgstr "\"%(attr)s\" v vrstici %(line)s je neveljavna oznaka. (Vrstica se začne z \"%(start)s\".)"
|
||||
msgstr "\"%(attr)s\" v vrstici %(line)s je neveljaven atribut. (Vrstica se začne z \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:476
|
||||
#, python-format
|
||||
@ -1800,12 +1803,12 @@ msgstr "\"<%(tag)s>\" v vrstici %(line)s je neveljavna oznaka. (Vrstica se začn
|
||||
#: core/validators.py:480
|
||||
#, python-format
|
||||
msgid "A tag on line %(line)s is missing one or more required attributes. (Line starts with \"%(start)s\".)"
|
||||
msgstr "Oznaki na vrstici %(line)s manjka eden ali več zahtevanih parametrov. (Vrstica se začne z \"%(start)s\".)"
|
||||
msgstr "Oznaki v vrstici %(line)s manjka eden ali več zahtevanih parametrov. (Vrstica se začne z \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:485
|
||||
#, python-format
|
||||
msgid "The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line starts with \"%(start)s\".)"
|
||||
msgstr "Atribut \"%(attr)s\" v vrstici %(line)s vsebuje neveljavno vrednost. (Vrstica se začne z \"%(start)s\".)"
|
||||
msgstr "Parameter \"%(attr)s\" v vrstici %(line)s vsebuje neveljavno vrednost. (Vrstica se začne z \"%(start)s\".)"
|
||||
|
||||
#: db/models/manipulators.py:302
|
||||
#, python-format
|
||||
@ -1827,7 +1830,7 @@ msgstr "To polje je obvezno"
|
||||
|
||||
#: db/models/fields/__init__.py:337
|
||||
msgid "This value must be an integer."
|
||||
msgstr "Ta vrednost mora biti število."
|
||||
msgstr "Ta vrednost mora biti celo število."
|
||||
|
||||
#: db/models/fields/__init__.py:369
|
||||
msgid "This value must be either True or False."
|
||||
@ -1858,8 +1861,8 @@ msgstr "Držite \"Control\" (ali \"Command\" na Mac-u), za izbiro več kot enega
|
||||
#, python-format
|
||||
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
|
||||
msgid_plural "Please enter valid %(self)s IDs. The values %(value)r are invalid."
|
||||
msgstr[0] "Prosimo, vnesite veljavne %(self)s ID-je. Vrednost %(value)r ni veljavna."
|
||||
msgstr[1] "Prosimo, vnesite veljavni %(self)s ID. Vrednosti %(value)r niso veljavne."
|
||||
msgstr[0] "Prosimo, vnesite veljavne %(self)s ID-e. Vrednost %(value)r ni veljavna."
|
||||
msgstr[1] "Prosimo, vnesite veljavne %(self)s ID-je. Vrednosti %(value)r nista veljavni."
|
||||
msgstr[2] "Prosimo, vnesite veljavne %(self)s ID-je. Vrednosti %(value)r niso veljavne."
|
||||
msgstr[3] "Prosimo, vnesite veljavne %(self)s ID-je. Vrednosti %(value)r niso veljavne."
|
||||
|
||||
@ -1867,8 +1870,8 @@ msgstr[3] "Prosimo, vnesite veljavne %(self)s ID-je. Vrednosti %(value)r niso ve
|
||||
#, python-format
|
||||
msgid "Ensure your text is less than %s character."
|
||||
msgid_plural "Ensure your text is less than %s characters."
|
||||
msgstr[0] "Poskrbite, da bo tekst krajši od %s znakov."
|
||||
msgstr[1] "Poskrbite, da bo tekst krajši od %s znaka."
|
||||
msgstr[0] "Poskrbite, da bo tekst krajši od %s znaka."
|
||||
msgstr[1] "Poskrbite, da bo tekst krajši od %s znakov."
|
||||
msgstr[2] "Poskrbite, da bo tekst krajši od %s znakov."
|
||||
msgstr[3] "Poskrbite, da bo tekst krajši od %s znakov."
|
||||
|
||||
@ -1885,11 +1888,11 @@ msgstr "Izberite veljavno možnost; '%(data)s' ni v %(choices)s."
|
||||
|
||||
#: forms/__init__.py:645
|
||||
msgid "The submitted file is empty."
|
||||
msgstr "Poslano polje je prazno."
|
||||
msgstr "Poslana datoteka je prazna."
|
||||
|
||||
#: forms/__init__.py:699
|
||||
msgid "Enter a whole number between -32,768 and 32,767."
|
||||
msgstr "Vnesite celo število med -32,768 in 32,767."
|
||||
msgstr "Vnesite celo število med -32.768 in 32.767."
|
||||
|
||||
#: forms/__init__.py:708
|
||||
msgid "Enter a positive number."
|
||||
@ -1897,11 +1900,11 @@ msgstr "Vnesite pozitivno število."
|
||||
|
||||
#: forms/__init__.py:717
|
||||
msgid "Enter a whole number between 0 and 32,767."
|
||||
msgstr "Vnesite celo število med 0 in 32,767."
|
||||
msgstr "Vnesite celo število med 0 in 32.767."
|
||||
|
||||
#: template/defaultfilters.py:379
|
||||
msgid "yes,no,maybe"
|
||||
msgstr "ja,ne,morda"
|
||||
msgstr "da,ne,morda"
|
||||
|
||||
msgid "Comment"
|
||||
msgstr "Komentar"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -8,13 +8,12 @@ msgstr ""
|
||||
"Project-Id-Version: django\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: 2006-01-15 11:24+0100\n"
|
||||
"Last-Translator: Nebojša Đorđević <nesh@studioquattro.co.yu>\n"
|
||||
"PO-Revision-Date: 2007-02-20 18:51+0100\n"
|
||||
"Last-Translator: Petar Marić <petar.maric@gmail.com>\n"
|
||||
"Language-Team: Nesh <nesh@studioquatro.co.yu> & Petar <petar.maric@gmail.com> <sr@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Serbian\n"
|
||||
"X-Poedit-Country: YUGOSLAVIA\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
@ -25,15 +24,15 @@ msgstr "Dostupno %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr "Izaberi sve"
|
||||
msgstr "Izaberite sve"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr "Dodaj"
|
||||
msgstr "Dodajte"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr "Izbaci"
|
||||
msgstr "Izbacite"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
@ -72,7 +71,7 @@ msgstr "Sat"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
msgid "Choose a time"
|
||||
msgstr "Izaberi vreme"
|
||||
msgstr "Izaberite vreme"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Midnight"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,112 +1,125 @@
|
||||
# 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.
|
||||
# Swedish translation of Django
|
||||
# Copyright (C) 2005
|
||||
# This file is distributed under the same license as the Django package.
|
||||
#
|
||||
#
|
||||
# Robin Sonefors <ozamosi@blinkenlights.se>, 2005.
|
||||
# Mikko Hellsing <mikko@sorl.net>, 2007.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django\n"
|
||||
"Project-Id-Version: djangojs\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: 2005-12-04 14:12+0100\n"
|
||||
"Last-Translator: Robin Sonefors <ozamosi@blinkenlights.se>\n"
|
||||
"Language-Team: Django Translators <Django-I18N@googlegroups.com>\n"
|
||||
"POT-Creation-Date: 2007-03-06 02:29+0100\n"
|
||||
"PO-Revision-Date: 2007-03-06 02:30+0100\n"
|
||||
"Last-Translator: Mikko Hellsing <mikko@sorl.net>\n"
|
||||
"Language-Team: Django translators <djangoi18n@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Language: Swedish\n"
|
||||
"X-Poedit-Country: SWEDEN\n"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr ""
|
||||
msgstr "Tillgänglig %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
#, fuzzy
|
||||
msgid "Choose all"
|
||||
msgstr "Välj en tidpunkt"
|
||||
msgstr "Visa alla"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "Lägg till"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
msgstr "Tag bort"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr ""
|
||||
msgstr "Valde %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr ""
|
||||
msgstr "Välj ditt/dina val och klicka "
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr ""
|
||||
msgstr "Avmarkera alla"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:26
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr ""
|
||||
"Januari Februari Mars April Maj Juni Juli Augusti September Oktober November "
|
||||
"December"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr ""
|
||||
msgstr "Söndag Mondag Tisdag Onsdag Torsdag Fredag Lördag"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr ""
|
||||
msgstr "S M T O T F L"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr "Visa"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr "Göm"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Now"
|
||||
msgstr "Nu"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr "Klocka"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr "Välj en tidpunkt"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr "Midnatt"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr "06.00"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "Mitt på dagen"
|
||||
|
||||
#: 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 "Ångra"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: 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 "Idag"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr "Kalender"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr "Igår"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "Imorgon"
|
||||
|
||||
|
@ -9,7 +9,7 @@ ADMINS = (
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASE_ENGINE = '' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
|
||||
DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
|
||||
DATABASE_NAME = '' # Or path to database file if using sqlite3.
|
||||
DATABASE_USER = '' # Not used with sqlite3.
|
||||
DATABASE_PASSWORD = '' # Not used with sqlite3.
|
||||
|
@ -1,6 +0,0 @@
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('django.views',
|
||||
(r'^$', 'registration.passwords.password_reset', {'is_admin_site' : True}),
|
||||
(r'^done/$', 'registration.passwords.password_reset_done'),
|
||||
)
|
@ -1,19 +0,0 @@
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^login/$', 'django.contrib.auth.views.login'),
|
||||
(r'^logout/$', 'django.contrib.auth.views.logout'),
|
||||
(r'^login_another/$', 'django.contrib.auth.views.logout_then_login'),
|
||||
|
||||
(r'^register/$', 'ellington.registration.views.registration.signup'),
|
||||
(r'^register/(?P<challenge_string>\w{32})/$', 'ellington.registration.views.registration.register_form'),
|
||||
|
||||
(r'^profile/$', 'ellington.registration.views.profile.profile'),
|
||||
(r'^profile/welcome/$', 'ellington.registration.views.profile.profile_welcome'),
|
||||
(r'^profile/edit/$', 'ellington.registration.views.profile.edit_profile'),
|
||||
|
||||
(r'^password_reset/$', 'django.contrib.auth.views.password_reset'),
|
||||
(r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
|
||||
(r'^password_change/$', 'django.contrib.auth.views.password_change'),
|
||||
(r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
|
||||
)
|
@ -84,22 +84,31 @@ def result_headers(cl):
|
||||
header = attr.short_description
|
||||
except AttributeError:
|
||||
header = field_name.replace('_', ' ')
|
||||
# Non-field list_display values don't get ordering capability.
|
||||
yield {"text": header}
|
||||
|
||||
# It is a non-field, but perhaps one that is sortable
|
||||
if not getattr(getattr(cl.model, field_name), "admin_order_field", None):
|
||||
yield {"text": header}
|
||||
continue
|
||||
|
||||
# So this _is_ a sortable non-field. Go to the yield
|
||||
# after the else clause.
|
||||
else:
|
||||
if isinstance(f.rel, models.ManyToOneRel) and f.null:
|
||||
yield {"text": f.verbose_name}
|
||||
continue
|
||||
else:
|
||||
th_classes = []
|
||||
new_order_type = 'asc'
|
||||
if field_name == cl.order_field:
|
||||
th_classes.append('sorted %sending' % cl.order_type.lower())
|
||||
new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type.lower()]
|
||||
header = f.verbose_name
|
||||
|
||||
yield {"text": f.verbose_name,
|
||||
"sortable": True,
|
||||
"url": cl.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}),
|
||||
"class_attrib": (th_classes and ' class="%s"' % ' '.join(th_classes) or '')}
|
||||
th_classes = []
|
||||
new_order_type = 'asc'
|
||||
if field_name == cl.order_field:
|
||||
th_classes.append('sorted %sending' % cl.order_type.lower())
|
||||
new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type.lower()]
|
||||
|
||||
yield {"text": header,
|
||||
"sortable": True,
|
||||
"url": cl.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}),
|
||||
"class_attrib": (th_classes and ' class="%s"' % ' '.join(th_classes) or '')}
|
||||
|
||||
def _boolean_icon(field_val):
|
||||
BOOLEAN_MAPPING = {True: 'yes', False: 'no', None: 'unknown'}
|
||||
|
@ -461,9 +461,12 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
|
||||
opts_seen.append(related.opts)
|
||||
rel_opts_name = related.get_accessor_name()
|
||||
has_related_objs = False
|
||||
rel_objs = getattr(obj, rel_opts_name, None)
|
||||
if rel_objs:
|
||||
has_related_objs = True
|
||||
|
||||
# related.get_accessor_name() could return None for symmetrical relationships
|
||||
if rel_opts_name:
|
||||
rel_objs = getattr(obj, rel_opts_name, None)
|
||||
if rel_objs:
|
||||
has_related_objs = True
|
||||
|
||||
if has_related_objs:
|
||||
for sub_obj in rel_objs.all():
|
||||
@ -655,10 +658,17 @@ class ChangeList(object):
|
||||
order_field, order_type = ordering[0], 'asc'
|
||||
if params.has_key(ORDER_VAR):
|
||||
try:
|
||||
field_name = lookup_opts.admin.list_display[int(params[ORDER_VAR])]
|
||||
try:
|
||||
f = lookup_opts.get_field(lookup_opts.admin.list_display[int(params[ORDER_VAR])])
|
||||
f = lookup_opts.get_field(field_name)
|
||||
except models.FieldDoesNotExist:
|
||||
pass
|
||||
# see if field_name is a name of a non-field
|
||||
# that allows sorting
|
||||
try:
|
||||
attr = getattr(lookup_opts.admin.manager.model, field_name)
|
||||
order_field = attr.admin_order_field
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
if not isinstance(f.rel, models.ManyToOneRel) or not f.null:
|
||||
order_field = f.name
|
||||
|
@ -32,6 +32,7 @@ STATE_CHOICES = (
|
||||
('ME', 'Maine'),
|
||||
('MH', 'Marshall Islands'),
|
||||
('MD', 'Maryland'),
|
||||
('MA', 'Massachusetts'),
|
||||
('MI', 'Michigan'),
|
||||
('MN', 'Minnesota'),
|
||||
('MS', 'Mississippi'),
|
||||
|
@ -3,7 +3,8 @@
|
||||
from django.conf import settings
|
||||
from email.MIMEText import MIMEText
|
||||
from email.Header import Header
|
||||
import smtplib, rfc822
|
||||
from email.Utils import formatdate
|
||||
import smtplib
|
||||
import socket
|
||||
import time
|
||||
import random
|
||||
@ -33,21 +34,34 @@ class SafeMIMEText(MIMEText):
|
||||
val = Header(val, settings.DEFAULT_CHARSET)
|
||||
MIMEText.__setitem__(self, name, val)
|
||||
|
||||
def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD):
|
||||
def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None):
|
||||
"""
|
||||
Easy wrapper for sending a single message to a recipient list. All members
|
||||
of the recipient list will see the other recipients in the 'To' field.
|
||||
|
||||
If auth_user is None, the EMAIL_HOST_USER setting is used.
|
||||
If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
|
||||
"""
|
||||
if auth_user is None:
|
||||
auth_user = settings.EMAIL_HOST_USER
|
||||
if auth_password is None:
|
||||
auth_password = settings.EMAIL_HOST_PASSWORD
|
||||
return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password)
|
||||
|
||||
def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD):
|
||||
def send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None):
|
||||
"""
|
||||
Given a datatuple of (subject, message, from_email, recipient_list), sends
|
||||
each message to each recipient list. Returns the number of e-mails sent.
|
||||
|
||||
If from_email is None, the DEFAULT_FROM_EMAIL setting is used.
|
||||
If auth_user and auth_password are set, they're used to log in.
|
||||
If auth_user is None, the EMAIL_HOST_USER setting is used.
|
||||
If auth_password is None, the EMAIL_HOST_PASSWORD setting is used.
|
||||
"""
|
||||
if auth_user is None:
|
||||
auth_user = settings.EMAIL_HOST_USER
|
||||
if auth_password is None:
|
||||
auth_password = settings.EMAIL_HOST_PASSWORD
|
||||
try:
|
||||
server = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT)
|
||||
if auth_user and auth_password:
|
||||
@ -65,7 +79,7 @@ def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST
|
||||
msg['Subject'] = subject
|
||||
msg['From'] = from_email
|
||||
msg['To'] = ', '.join(recipient_list)
|
||||
msg['Date'] = rfc822.formatdate()
|
||||
msg['Date'] = formatdate()
|
||||
try:
|
||||
random_bits = str(random.getrandbits(64))
|
||||
except AttributeError: # Python 2.3 doesn't have random.getrandbits().
|
||||
|
@ -68,6 +68,25 @@ def _get_table_list():
|
||||
cursor = connection.cursor()
|
||||
return get_introspection_module().get_table_list(cursor)
|
||||
|
||||
def _get_sequence_list():
|
||||
"Returns a list of information about all DB sequences for all models in all apps"
|
||||
from django.db import models
|
||||
|
||||
apps = models.get_apps()
|
||||
sequence_list = []
|
||||
|
||||
for app in apps:
|
||||
for model in models.get_models(app):
|
||||
for f in model._meta.fields:
|
||||
if isinstance(f, models.AutoField):
|
||||
sequence_list.append({'table':model._meta.db_table,'column':f.column,})
|
||||
break # Only one AutoField is allowed per model, so don't bother continuing.
|
||||
|
||||
for f in model._meta.many_to_many:
|
||||
sequence_list.append({'table':f.m2m_db_table(),'column':None,})
|
||||
|
||||
return sequence_list
|
||||
|
||||
# If the foreign key points to an AutoField, a PositiveIntegerField or a
|
||||
# PositiveSmallIntegerField, the foreign key should be an IntegerField, not the
|
||||
# referred field type. Otherwise, the foreign key should be the same type of
|
||||
@ -167,7 +186,8 @@ def _get_sql_model_create(model, known_models=set()):
|
||||
if f.rel.to in known_models:
|
||||
field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \
|
||||
style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \
|
||||
style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')'
|
||||
style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' +
|
||||
backend.get_deferrable_sql()
|
||||
)
|
||||
else:
|
||||
# We haven't yet created the table to which this field
|
||||
@ -210,9 +230,10 @@ def _get_sql_for_pending_references(model, pending_references):
|
||||
# For MySQL, r_name must be unique in the first 64 characters.
|
||||
# So we are careful with character usage here.
|
||||
r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table))))
|
||||
final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \
|
||||
final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \
|
||||
(backend.quote_name(r_table), r_name,
|
||||
backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col)))
|
||||
backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col),
|
||||
backend.get_deferrable_sql()))
|
||||
del pending_references[model]
|
||||
return final_output
|
||||
|
||||
@ -232,18 +253,20 @@ def _get_many_to_many_sql_for_model(model):
|
||||
(style.SQL_FIELD(backend.quote_name('id')),
|
||||
style.SQL_COLTYPE(data_types['AutoField']),
|
||||
style.SQL_KEYWORD('NOT NULL PRIMARY KEY')))
|
||||
table_output.append(' %s %s %s %s (%s),' % \
|
||||
table_output.append(' %s %s %s %s (%s)%s,' % \
|
||||
(style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
|
||||
style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__),
|
||||
style.SQL_KEYWORD('NOT NULL REFERENCES'),
|
||||
style.SQL_TABLE(backend.quote_name(opts.db_table)),
|
||||
style.SQL_FIELD(backend.quote_name(opts.pk.column))))
|
||||
table_output.append(' %s %s %s %s (%s),' % \
|
||||
style.SQL_FIELD(backend.quote_name(opts.pk.column)),
|
||||
backend.get_deferrable_sql()))
|
||||
table_output.append(' %s %s %s %s (%s)%s,' % \
|
||||
(style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())),
|
||||
style.SQL_COLTYPE(data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__),
|
||||
style.SQL_KEYWORD('NOT NULL REFERENCES'),
|
||||
style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)),
|
||||
style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column))))
|
||||
style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)),
|
||||
backend.get_deferrable_sql()))
|
||||
table_output.append(' %s (%s, %s)' % \
|
||||
(style.SQL_KEYWORD('UNIQUE'),
|
||||
style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
|
||||
@ -330,7 +353,15 @@ def get_sql_reset(app):
|
||||
get_sql_reset.help_doc = "Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s)."
|
||||
get_sql_reset.args = APP_ARGS
|
||||
|
||||
def get_sql_initial_data_for_model(model):
|
||||
def get_sql_flush():
|
||||
"Returns a list of the SQL statements used to flush the database"
|
||||
from django.db import backend
|
||||
statements = backend.get_sql_flush(style, _get_table_list(), _get_sequence_list())
|
||||
return statements
|
||||
get_sql_flush.help_doc = "Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed."
|
||||
get_sql_flush.args = ''
|
||||
|
||||
def get_custom_sql_for_model(model):
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
|
||||
@ -357,8 +388,8 @@ def get_sql_initial_data_for_model(model):
|
||||
|
||||
return output
|
||||
|
||||
def get_sql_initial_data(app):
|
||||
"Returns a list of the initial INSERT SQL statements for the given app."
|
||||
def get_custom_sql(app):
|
||||
"Returns a list of the custom table modifying SQL statements for the given app."
|
||||
from django.db.models import get_models
|
||||
output = []
|
||||
|
||||
@ -366,11 +397,17 @@ def get_sql_initial_data(app):
|
||||
app_dir = os.path.normpath(os.path.join(os.path.dirname(app.__file__), 'sql'))
|
||||
|
||||
for model in app_models:
|
||||
output.extend(get_sql_initial_data_for_model(model))
|
||||
output.extend(get_custom_sql_for_model(model))
|
||||
|
||||
return output
|
||||
get_sql_initial_data.help_doc = "Prints the initial INSERT SQL statements for the given app name(s)."
|
||||
get_sql_initial_data.args = APP_ARGS
|
||||
get_custom_sql.help_doc = "Prints the custom table modifying SQL statements for the given app name(s)."
|
||||
get_custom_sql.args = APP_ARGS
|
||||
|
||||
def get_sql_initial_data(apps):
|
||||
"Returns a list of the initial INSERT SQL statements for the given app."
|
||||
return style.ERROR("This action has been renamed. Try './manage.py sqlcustom %s'." % ' '.join(apps and apps or ['app1', 'app2']))
|
||||
get_sql_initial_data.help_doc = "RENAMED: see 'sqlcustom'"
|
||||
get_sql_initial_data.args = ''
|
||||
|
||||
def get_sql_sequence_reset(app):
|
||||
"Returns a list of the SQL statements to reset PostgreSQL sequences for the given app."
|
||||
@ -428,16 +465,26 @@ def get_sql_indexes_for_model(model):
|
||||
|
||||
def get_sql_all(app):
|
||||
"Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
|
||||
return get_sql_create(app) + get_sql_initial_data(app) + get_sql_indexes(app)
|
||||
return get_sql_create(app) + get_custom_sql(app) + get_sql_indexes(app)
|
||||
get_sql_all.help_doc = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)."
|
||||
get_sql_all.args = APP_ARGS
|
||||
|
||||
def _emit_post_sync_signal(created_models, verbosity, interactive):
|
||||
from django.db import models
|
||||
from django.dispatch import dispatcher
|
||||
# Emit the post_sync signal for every application.
|
||||
for app in models.get_apps():
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
if verbosity >= 2:
|
||||
print "Running post-sync handlers for application", app_name
|
||||
dispatcher.send(signal=models.signals.post_syncdb, sender=app,
|
||||
app=app, created_models=created_models,
|
||||
verbosity=verbosity, interactive=interactive)
|
||||
|
||||
def syncdb(verbosity=1, interactive=True):
|
||||
"Creates the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
|
||||
from django.db import connection, transaction, models, get_creation_module
|
||||
from django.db.models import signals
|
||||
from django.conf import settings
|
||||
from django.dispatch import dispatcher
|
||||
|
||||
disable_termcolors()
|
||||
|
||||
@ -499,27 +546,22 @@ def syncdb(verbosity=1, interactive=True):
|
||||
|
||||
# Send the post_syncdb signal, so individual apps can do whatever they need
|
||||
# to do at this point.
|
||||
for app in models.get_apps():
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
if verbosity >= 2:
|
||||
print "Running post-sync handlers for application", app_name
|
||||
dispatcher.send(signal=signals.post_syncdb, sender=app,
|
||||
app=app, created_models=created_models,
|
||||
verbosity=verbosity, interactive=interactive)
|
||||
_emit_post_sync_signal(created_models, verbosity, interactive)
|
||||
|
||||
# Install initial data for the app (but only if this is a model we've
|
||||
# just created)
|
||||
# Install custom SQL for the app (but only if this
|
||||
# is a model we've just created)
|
||||
for app in models.get_apps():
|
||||
for model in models.get_models(app):
|
||||
if model in created_models:
|
||||
initial_sql = get_sql_initial_data_for_model(model)
|
||||
if initial_sql:
|
||||
custom_sql = get_custom_sql_for_model(model)
|
||||
if custom_sql:
|
||||
if verbosity >= 1:
|
||||
print "Installing initial data for %s.%s model" % (app_name, model._meta.object_name)
|
||||
print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name)
|
||||
try:
|
||||
for sql in initial_sql:
|
||||
for sql in custom_sql:
|
||||
cursor.execute(sql)
|
||||
except Exception, e:
|
||||
sys.stderr.write("Failed to install initial SQL data for %s.%s model: %s" % \
|
||||
sys.stderr.write("Failed to install custom SQL for %s.%s model: %s" % \
|
||||
(app_name, model._meta.object_name, e))
|
||||
transaction.rollback_unless_managed()
|
||||
else:
|
||||
@ -544,7 +586,10 @@ def syncdb(verbosity=1, interactive=True):
|
||||
else:
|
||||
transaction.commit_unless_managed()
|
||||
|
||||
syncdb.args = ''
|
||||
# Install the 'initialdata' fixture, using format discovery
|
||||
load_data(['initial_data'], verbosity=verbosity)
|
||||
syncdb.help_doc = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
|
||||
syncdb.args = '[--verbosity] [--interactive]'
|
||||
|
||||
def get_admin_index(app):
|
||||
"Returns admin-index template snippet (in list form) for the given app."
|
||||
@ -597,36 +642,6 @@ def diffsettings():
|
||||
print '\n'.join(output)
|
||||
diffsettings.args = ""
|
||||
|
||||
def install(app):
|
||||
"Executes the equivalent of 'get_sql_all' in the current database."
|
||||
from django.db import connection, transaction
|
||||
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
|
||||
disable_termcolors()
|
||||
|
||||
# First, try validating the models.
|
||||
_check_for_validation_errors(app)
|
||||
|
||||
sql_list = get_sql_all(app)
|
||||
|
||||
try:
|
||||
cursor = connection.cursor()
|
||||
for sql in sql_list:
|
||||
cursor.execute(sql)
|
||||
except Exception, e:
|
||||
sys.stderr.write(style.ERROR("""Error: %s couldn't be installed. Possible reasons:
|
||||
* The database isn't running or isn't configured correctly.
|
||||
* At least one of the database tables already exists.
|
||||
* The SQL was invalid.
|
||||
Hint: Look at the output of 'django-admin.py sqlall %s'. That's the SQL this command wasn't able to run.
|
||||
The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(str(e)) + '\n')
|
||||
transaction.rollback_unless_managed()
|
||||
sys.exit(1)
|
||||
transaction.commit_unless_managed()
|
||||
install.help_doc = "Executes ``sqlall`` for the given app(s) in the current database."
|
||||
install.args = APP_ARGS
|
||||
|
||||
def reset(app, interactive=True):
|
||||
"Executes the equivalent of 'get_sql_reset' in the current database."
|
||||
from django.db import connection, transaction
|
||||
@ -668,7 +683,68 @@ The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(str(e)) + '\n')
|
||||
else:
|
||||
print "Reset cancelled."
|
||||
reset.help_doc = "Executes ``sqlreset`` for the given app(s) in the current database."
|
||||
reset.args = APP_ARGS
|
||||
reset.args = '[--interactive]' + APP_ARGS
|
||||
|
||||
def flush(verbosity=1, interactive=True):
|
||||
"Returns all tables in the database to the same state they were in immediately after syncdb."
|
||||
from django.conf import settings
|
||||
from django.db import connection, transaction, models
|
||||
from django.dispatch import dispatcher
|
||||
|
||||
disable_termcolors()
|
||||
|
||||
# First, try validating the models.
|
||||
_check_for_validation_errors()
|
||||
|
||||
# Import the 'management' module within each installed app, to register
|
||||
# dispatcher events.
|
||||
for app_name in settings.INSTALLED_APPS:
|
||||
try:
|
||||
__import__(app_name + '.management', {}, {}, [''])
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
sql_list = get_sql_flush()
|
||||
|
||||
if interactive:
|
||||
confirm = raw_input("""
|
||||
You have requested a flush of the database.
|
||||
This will IRREVERSIBLY DESTROY all data currently in the database,
|
||||
and return each table to the state it was in after syncdb.
|
||||
Are you sure you want to do this?
|
||||
|
||||
Type 'yes' to continue, or 'no' to cancel: """)
|
||||
else:
|
||||
confirm = 'yes'
|
||||
|
||||
if confirm == 'yes':
|
||||
try:
|
||||
cursor = connection.cursor()
|
||||
for sql in sql_list:
|
||||
cursor.execute(sql)
|
||||
except Exception, e:
|
||||
sys.stderr.write(style.ERROR("""Error: Database %s couldn't be flushed. Possible reasons:
|
||||
* The database isn't running or isn't configured correctly.
|
||||
* At least one of the expected database tables doesn't exist.
|
||||
* The SQL was invalid.
|
||||
Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.
|
||||
The full error: """ % settings.DATABASE_NAME + style.ERROR_OUTPUT(str(e)) + '\n'))
|
||||
transaction.rollback_unless_managed()
|
||||
sys.exit(1)
|
||||
transaction.commit_unless_managed()
|
||||
|
||||
# Emit the post sync signal. This allows individual
|
||||
# applications to respond as if the database had been
|
||||
# sync'd from scratch.
|
||||
_emit_post_sync_signal(models.get_models(), verbosity, interactive)
|
||||
|
||||
# Reinstall the initial_data fixture
|
||||
load_data(['initial_data'], verbosity=verbosity)
|
||||
|
||||
else:
|
||||
print "Flush cancelled."
|
||||
flush.help_doc = "Executes ``sqlflush`` on the current database."
|
||||
flush.args = '[--verbosity] [--interactive]'
|
||||
|
||||
def _start_helper(app_or_project, name, directory, other_name=''):
|
||||
other = {'project': 'app', 'app': 'project'}[app_or_project]
|
||||
@ -751,7 +827,7 @@ def inspectdb():
|
||||
yield "# * Make sure each model has one field with primary_key=True"
|
||||
yield "# Feel free to rename the models, but don't rename db_table values or field names."
|
||||
yield "#"
|
||||
yield "# Also note: You'll have to insert the output of 'django-admin.py sqlinitialdata [appname]'"
|
||||
yield "# Also note: You'll have to insert the output of 'django-admin.py sqlcustom [appname]'"
|
||||
yield "# into your database."
|
||||
yield ''
|
||||
yield 'from django.db import models'
|
||||
@ -1240,10 +1316,131 @@ def test(app_labels, verbosity=1):
|
||||
test_module = __import__(test_module_name, {}, {}, test_path[-1])
|
||||
test_runner = getattr(test_module, test_path[-1])
|
||||
|
||||
test_runner(app_list, verbosity)
|
||||
failures = test_runner(app_list, verbosity)
|
||||
if failures:
|
||||
sys.exit(failures)
|
||||
|
||||
test.help_doc = 'Runs the test suite for the specified applications, or the entire site if no apps are specified'
|
||||
test.args = '[--verbosity] ' + APP_ARGS
|
||||
|
||||
def load_data(fixture_labels, verbosity=1):
|
||||
"Installs the provided fixture file(s) as data in the database."
|
||||
from django.db.models import get_apps
|
||||
from django.core import serializers
|
||||
from django.db import connection, transaction
|
||||
from django.conf import settings
|
||||
import sys
|
||||
|
||||
# Keep a count of the installed objects and fixtures
|
||||
count = [0,0]
|
||||
|
||||
humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
|
||||
|
||||
# Get a cursor (even though we don't need one yet). This has
|
||||
# the side effect of initializing the test database (if
|
||||
# it isn't already initialized).
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Start transaction management. All fixtures are installed in a
|
||||
# single transaction to ensure that all references are resolved.
|
||||
transaction.commit_unless_managed()
|
||||
transaction.enter_transaction_management()
|
||||
transaction.managed(True)
|
||||
|
||||
app_fixtures = [os.path.join(os.path.dirname(app.__file__),'fixtures') for app in get_apps()]
|
||||
for fixture_label in fixture_labels:
|
||||
if verbosity > 0:
|
||||
print "Loading '%s' fixtures..." % fixture_label
|
||||
for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']:
|
||||
if verbosity > 1:
|
||||
print "Checking %s for fixtures..." % humanize(fixture_dir)
|
||||
try:
|
||||
fixture_name, format = fixture_label.rsplit('.', 1)
|
||||
formats = [format]
|
||||
except ValueError:
|
||||
fixture_name = fixture_label
|
||||
formats = serializers.get_serializer_formats()
|
||||
|
||||
label_found = False
|
||||
for format in formats:
|
||||
serializer = serializers.get_serializer(format)
|
||||
if verbosity > 1:
|
||||
print "Trying %s for %s fixture '%s'..." % \
|
||||
(humanize(fixture_dir), format, fixture_name)
|
||||
try:
|
||||
full_path = os.path.join(fixture_dir, '.'.join([fixture_name, format]))
|
||||
fixture = open(full_path, 'r')
|
||||
if label_found:
|
||||
fixture.close()
|
||||
print style.ERROR("Multiple fixtures named '%s' in %s. Aborting." %
|
||||
(fixture_name, humanize(fixture_dir)))
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
return
|
||||
else:
|
||||
count[1] += 1
|
||||
if verbosity > 0:
|
||||
print "Installing %s fixture '%s' from %s." % \
|
||||
(format, fixture_name, humanize(fixture_dir))
|
||||
try:
|
||||
objects = serializers.deserialize(format, fixture)
|
||||
for obj in objects:
|
||||
count[0] += 1
|
||||
obj.save()
|
||||
label_found = True
|
||||
except Exception, e:
|
||||
fixture.close()
|
||||
sys.stderr.write(
|
||||
style.ERROR("Problem installing fixture '%s': %s\n" %
|
||||
(full_path, str(e))))
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
return
|
||||
fixture.close()
|
||||
except:
|
||||
if verbosity > 1:
|
||||
print "No %s fixture '%s' in %s." % \
|
||||
(format, fixture_name, humanize(fixture_dir))
|
||||
if count[0] == 0:
|
||||
if verbosity > 0:
|
||||
print "No fixtures found."
|
||||
else:
|
||||
if verbosity > 0:
|
||||
print "Installed %d object(s) from %d fixture(s)" % tuple(count)
|
||||
transaction.commit()
|
||||
transaction.leave_transaction_management()
|
||||
|
||||
load_data.help_doc = 'Installs the named fixture(s) in the database'
|
||||
load_data.args = "[--verbosity] fixture, fixture, ..."
|
||||
|
||||
def dump_data(app_labels, format='json', indent=None):
|
||||
"Output the current contents of the database as a fixture of the given format"
|
||||
from django.db.models import get_app, get_apps, get_models
|
||||
from django.core import serializers
|
||||
|
||||
if len(app_labels) == 0:
|
||||
app_list = get_apps()
|
||||
else:
|
||||
app_list = [get_app(app_label) for app_label in app_labels]
|
||||
|
||||
# Check that the serialization format exists; this is a shortcut to
|
||||
# avoid collating all the objects and _then_ failing.
|
||||
try:
|
||||
serializers.get_serializer(format)
|
||||
except KeyError:
|
||||
sys.stderr.write(style.ERROR("Unknown serialization format: %s\n" % format))
|
||||
|
||||
objects = []
|
||||
for app in app_list:
|
||||
for model in get_models(app):
|
||||
objects.extend(model.objects.all())
|
||||
try:
|
||||
print serializers.serialize(format, objects, indent=indent)
|
||||
except Exception, e:
|
||||
sys.stderr.write(style.ERROR("Unable to serialize database: %s\n" % e))
|
||||
dump_data.help_doc = 'Output the contents of the database as a fixture of the given format'
|
||||
dump_data.args = '[--format]' + APP_ARGS
|
||||
|
||||
# Utilities for command-line script
|
||||
|
||||
DEFAULT_ACTION_MAPPING = {
|
||||
@ -1251,8 +1448,10 @@ DEFAULT_ACTION_MAPPING = {
|
||||
'createcachetable' : createcachetable,
|
||||
'dbshell': dbshell,
|
||||
'diffsettings': diffsettings,
|
||||
'dumpdata': dump_data,
|
||||
'flush': flush,
|
||||
'inspectdb': inspectdb,
|
||||
'install': install,
|
||||
'loaddata': load_data,
|
||||
'reset': reset,
|
||||
'runfcgi': runfcgi,
|
||||
'runserver': runserver,
|
||||
@ -1260,6 +1459,8 @@ DEFAULT_ACTION_MAPPING = {
|
||||
'sql': get_sql_create,
|
||||
'sqlall': get_sql_all,
|
||||
'sqlclear': get_sql_delete,
|
||||
'sqlcustom': get_custom_sql,
|
||||
'sqlflush': get_sql_flush,
|
||||
'sqlindexes': get_sql_indexes,
|
||||
'sqlinitialdata': get_sql_initial_data,
|
||||
'sqlreset': get_sql_reset,
|
||||
@ -1276,7 +1477,6 @@ NO_SQL_TRANSACTION = (
|
||||
'createcachetable',
|
||||
'dbshell',
|
||||
'diffsettings',
|
||||
'install',
|
||||
'reset',
|
||||
'sqlindexes',
|
||||
'syncdb',
|
||||
@ -1323,6 +1523,10 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
|
||||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_option('--noreload', action='store_false', dest='use_reloader', default=True,
|
||||
help='Tells Django to NOT use the auto-reloader when running the development server.')
|
||||
parser.add_option('--format', default='json', dest='format',
|
||||
help='Specifies the output serialization format for fixtures')
|
||||
parser.add_option('--indent', default=None, dest='indent',
|
||||
type='int', help='Specifies the indent level to use when pretty-printing output')
|
||||
parser.add_option('--verbosity', action='store', dest='verbosity', default='1',
|
||||
type='choice', choices=['0', '1', '2'],
|
||||
help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
|
||||
@ -1356,7 +1560,7 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
|
||||
action_mapping[action](options.plain is True)
|
||||
elif action in ('validate', 'diffsettings', 'dbshell'):
|
||||
action_mapping[action]()
|
||||
elif action == 'syncdb':
|
||||
elif action in ('flush', 'syncdb'):
|
||||
action_mapping[action](int(options.verbosity), options.interactive)
|
||||
elif action == 'inspectdb':
|
||||
try:
|
||||
@ -1370,11 +1574,16 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
|
||||
action_mapping[action](args[1])
|
||||
except IndexError:
|
||||
parser.print_usage_and_exit()
|
||||
elif action == 'test':
|
||||
elif action in ('test', 'loaddata'):
|
||||
try:
|
||||
action_mapping[action](args[1:], int(options.verbosity))
|
||||
except IndexError:
|
||||
parser.print_usage_and_exit()
|
||||
elif action == 'dumpdata':
|
||||
try:
|
||||
action_mapping[action](args[1:], options.format, options.indent)
|
||||
except IndexError:
|
||||
parser.print_usage_and_exit()
|
||||
elif action in ('startapp', 'startproject'):
|
||||
try:
|
||||
name = args[1]
|
||||
@ -1393,6 +1602,10 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
|
||||
action_mapping[action](addr, port, options.use_reloader, options.admin_media_path)
|
||||
elif action == 'runfcgi':
|
||||
action_mapping[action](args[1:])
|
||||
elif action == 'sqlinitialdata':
|
||||
print action_mapping[action](args[1:])
|
||||
elif action == 'sqlflush':
|
||||
print '\n'.join(action_mapping[action]())
|
||||
else:
|
||||
from django.db import models
|
||||
validate(silent_success=True)
|
||||
|
@ -41,6 +41,11 @@ def get_serializer(format):
|
||||
_load_serializers()
|
||||
return _serializers[format].Serializer
|
||||
|
||||
def get_serializer_formats():
|
||||
if not _serializers:
|
||||
_load_serializers()
|
||||
return _serializers.keys()
|
||||
|
||||
def get_deserializer(format):
|
||||
if not _serializers:
|
||||
_load_serializers()
|
||||
|
@ -141,7 +141,7 @@ class Deserializer(object):
|
||||
|
||||
class DeserializedObject(object):
|
||||
"""
|
||||
A deserialzed model.
|
||||
A deserialized model.
|
||||
|
||||
Basically a container for holding the pre-saved deserialized data along
|
||||
with the many-to-many data saved with the object.
|
||||
|
@ -67,20 +67,19 @@ def Deserializer(object_list, **options):
|
||||
|
||||
field = Model._meta.get_field(field_name)
|
||||
|
||||
# Handle M2M relations (with in_bulk() for performance)
|
||||
# Handle M2M relations
|
||||
if field.rel and isinstance(field.rel, models.ManyToManyRel):
|
||||
pks = []
|
||||
for pk in field_value:
|
||||
if isinstance(pk, unicode):
|
||||
pk = pk.encode(options.get("encoding", settings.DEFAULT_CHARSET))
|
||||
m2m_data[field.name] = field.rel.to._default_manager.in_bulk(field_value).values()
|
||||
pks.append(pk.encode(options.get("encoding", settings.DEFAULT_CHARSET)))
|
||||
else:
|
||||
pks.append(pk)
|
||||
m2m_data[field.name] = pks
|
||||
|
||||
# Handle FK fields
|
||||
elif field.rel and isinstance(field.rel, models.ManyToOneRel) and field_value is not None:
|
||||
try:
|
||||
data[field.name] = field.rel.to._default_manager.get(pk=field_value)
|
||||
except field.rel.to.DoesNotExist:
|
||||
data[field.name] = None
|
||||
elif field.rel and isinstance(field.rel, models.ManyToOneRel):
|
||||
data[field.attname] = field_value
|
||||
|
||||
# Handle all other fields
|
||||
else:
|
||||
|
@ -150,7 +150,7 @@ class Deserializer(base.Deserializer):
|
||||
if field.rel and isinstance(field.rel, models.ManyToManyRel):
|
||||
m2m_data[field.name] = self._handle_m2m_field_node(field_node)
|
||||
elif field.rel and isinstance(field.rel, models.ManyToOneRel):
|
||||
data[field.name] = self._handle_fk_field_node(field_node)
|
||||
data[field.attname] = self._handle_fk_field_node(field_node)
|
||||
else:
|
||||
value = field.to_python(getInnerText(field_node).strip().encode(self.encoding))
|
||||
data[field.name] = value
|
||||
@ -162,27 +162,17 @@ class Deserializer(base.Deserializer):
|
||||
"""
|
||||
Handle a <field> node for a ForeignKey
|
||||
"""
|
||||
# Try to set the foreign key by looking up the foreign related object.
|
||||
# If it doesn't exist, set the field to None (which might trigger
|
||||
# validation error, but that's expected).
|
||||
RelatedModel = self._get_model_from_node(node, "to")
|
||||
# Check if there is a child node named 'None', returning None if so.
|
||||
if len(node.childNodes) == 1 and node.childNodes[0].nodeName == 'None':
|
||||
return None
|
||||
else:
|
||||
return RelatedModel.objects.get(pk=getInnerText(node).strip().encode(self.encoding))
|
||||
return getInnerText(node).strip().encode(self.encoding)
|
||||
|
||||
def _handle_m2m_field_node(self, node):
|
||||
"""
|
||||
Handle a <field> node for a ManyToManyField
|
||||
"""
|
||||
# Load the related model
|
||||
RelatedModel = self._get_model_from_node(node, "to")
|
||||
|
||||
# Look up all the related objects. Using the in_bulk() lookup ensures
|
||||
# that missing related objects don't cause an exception
|
||||
related_ids = [c.getAttribute("pk").encode(self.encoding) for c in node.getElementsByTagName("object")]
|
||||
return RelatedModel._default_manager.in_bulk(related_ids).values()
|
||||
return [c.getAttribute("pk").encode(self.encoding) for c in node.getElementsByTagName("object")]
|
||||
|
||||
def _get_model_from_node(self, node, attr):
|
||||
"""
|
||||
|
@ -110,7 +110,7 @@ class RegexURLPattern(object):
|
||||
kwargs = match.groupdict()
|
||||
if kwargs:
|
||||
args = ()
|
||||
if not kwargs:
|
||||
else:
|
||||
args = match.groups()
|
||||
# In both cases, pass any extra_kwargs as **kwargs.
|
||||
kwargs.update(self.default_args)
|
||||
|
@ -312,11 +312,12 @@ class RequiredIfOtherFieldGiven(RequiredIfOtherFieldsGiven):
|
||||
RequiredIfOtherFieldsGiven.__init__(self, [other_field_name], error_message)
|
||||
|
||||
class RequiredIfOtherFieldEquals(object):
|
||||
def __init__(self, other_field, other_value, error_message=None):
|
||||
def __init__(self, other_field, other_value, error_message=None, other_label=None):
|
||||
self.other_field = other_field
|
||||
self.other_value = other_value
|
||||
other_label = other_label or other_value
|
||||
self.error_message = error_message or lazy_inter(gettext_lazy("This field must be given if %(field)s is %(value)s"), {
|
||||
'field': other_field, 'value': other_value})
|
||||
'field': other_field, 'value': other_label})
|
||||
self.always_test = True
|
||||
|
||||
def __call__(self, field_data, all_data):
|
||||
@ -324,11 +325,12 @@ class RequiredIfOtherFieldEquals(object):
|
||||
raise ValidationError(self.error_message)
|
||||
|
||||
class RequiredIfOtherFieldDoesNotEqual(object):
|
||||
def __init__(self, other_field, other_value, error_message=None):
|
||||
def __init__(self, other_field, other_value, other_label=None, error_message=None):
|
||||
self.other_field = other_field
|
||||
self.other_value = other_value
|
||||
other_label = other_label or other_value
|
||||
self.error_message = error_message or lazy_inter(gettext_lazy("This field must be given if %(field)s is not %(value)s"), {
|
||||
'field': other_field, 'value': other_value})
|
||||
'field': other_field, 'value': other_label})
|
||||
self.always_test = True
|
||||
|
||||
def __call__(self, field_data, all_data):
|
||||
|
@ -125,6 +125,9 @@ def get_limit_offset_sql(limit, offset=None):
|
||||
def get_random_function_sql():
|
||||
return "RAND()"
|
||||
|
||||
def get_deferrable_sql():
|
||||
return " DEFERRABLE INITIALLY DEFERRED"
|
||||
|
||||
def get_fulltext_search_sql(field_name):
|
||||
raise NotImplementedError
|
||||
|
||||
@ -134,6 +137,19 @@ def get_drop_foreignkey_sql():
|
||||
def get_pk_default_value():
|
||||
return "DEFAULT"
|
||||
|
||||
def get_sql_flush(sql_styler, full_table_list):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
themselves) and put the database in an empty 'initial' state
|
||||
"""
|
||||
# Return a list of 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
|
||||
# TODO - SQL not actually tested against ADO MSSQL yet!
|
||||
# TODO - autoincrement indices reset required? See other get_sql_flush() implementations
|
||||
sql_list = ['%s %s;' % \
|
||||
(sql_styler.SQL_KEYWORD('TRUNCATE'),
|
||||
sql_styler.SQL_FIELD(quote_name(table))
|
||||
) for table in full_table_list]
|
||||
|
||||
OPERATOR_MAPPING = {
|
||||
'exact': '= %s',
|
||||
'iexact': 'LIKE %s',
|
||||
|
@ -36,6 +36,9 @@ get_date_extract_sql = complain
|
||||
get_date_trunc_sql = complain
|
||||
get_limit_offset_sql = complain
|
||||
get_random_function_sql = complain
|
||||
get_deferrable_sql = complain
|
||||
get_fulltext_search_sql = complain
|
||||
get_drop_foreignkey_sql = complain
|
||||
get_sql_flush = complain
|
||||
|
||||
OPERATOR_MAPPING = {}
|
||||
|
@ -174,6 +174,9 @@ def get_limit_offset_sql(limit, offset=None):
|
||||
def get_random_function_sql():
|
||||
return "RAND()"
|
||||
|
||||
def get_deferrable_sql():
|
||||
return ""
|
||||
|
||||
def get_fulltext_search_sql(field_name):
|
||||
return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name
|
||||
|
||||
@ -183,6 +186,36 @@ def get_drop_foreignkey_sql():
|
||||
def get_pk_default_value():
|
||||
return "DEFAULT"
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
themselves) and put the database in an empty 'initial' state
|
||||
|
||||
"""
|
||||
# NB: The generated SQL below is specific to MySQL
|
||||
# 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
|
||||
# to clear all tables of all data
|
||||
if tables:
|
||||
sql = ['SET FOREIGN_KEY_CHECKS = 0;'] + \
|
||||
['%s %s;' % \
|
||||
(style.SQL_KEYWORD('TRUNCATE'),
|
||||
style.SQL_FIELD(quote_name(table))
|
||||
) for table in tables] + \
|
||||
['SET FOREIGN_KEY_CHECKS = 1;']
|
||||
|
||||
# 'ALTER TABLE table AUTO_INCREMENT = 1;'... style SQL statements
|
||||
# to reset sequence indices
|
||||
sql.extend(["%s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('TABLE'),
|
||||
style.SQL_TABLE(quote_name(sequence['table'])),
|
||||
style.SQL_KEYWORD('AUTO_INCREMENT'),
|
||||
style.SQL_FIELD('= 1'),
|
||||
) for sequence in sequences])
|
||||
return sql
|
||||
else:
|
||||
return []
|
||||
|
||||
OPERATOR_MAPPING = {
|
||||
'exact': '= %s',
|
||||
'iexact': 'LIKE %s',
|
||||
|
@ -108,6 +108,9 @@ def get_limit_offset_sql(limit, offset=None):
|
||||
def get_random_function_sql():
|
||||
return "DBMS_RANDOM.RANDOM"
|
||||
|
||||
def get_deferrable_sql():
|
||||
return " DEFERRABLE INITIALLY DEFERRED"
|
||||
|
||||
def get_fulltext_search_sql(field_name):
|
||||
raise NotImplementedError
|
||||
|
||||
@ -117,6 +120,20 @@ def get_drop_foreignkey_sql():
|
||||
def get_pk_default_value():
|
||||
return "DEFAULT"
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
themselves) and put the database in an empty 'initial' state
|
||||
"""
|
||||
# Return a list of 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
|
||||
# TODO - SQL not actually tested against Oracle yet!
|
||||
# TODO - autoincrement indices reset required? See other get_sql_flush() implementations
|
||||
sql = ['%s %s;' % \
|
||||
(style.SQL_KEYWORD('TRUNCATE'),
|
||||
style.SQL_FIELD(quote_name(table))
|
||||
) for table in tables]
|
||||
|
||||
|
||||
OPERATOR_MAPPING = {
|
||||
'exact': '= %s',
|
||||
'iexact': 'LIKE %s',
|
||||
|
@ -52,6 +52,8 @@ class UnicodeCursorWrapper(object):
|
||||
else:
|
||||
return getattr(self.cursor, attr)
|
||||
|
||||
postgres_version = None
|
||||
|
||||
class DatabaseWrapper(local):
|
||||
def __init__(self, **kwargs):
|
||||
self.connection = None
|
||||
@ -60,7 +62,9 @@ class DatabaseWrapper(local):
|
||||
|
||||
def cursor(self):
|
||||
from django.conf import settings
|
||||
set_tz = False
|
||||
if self.connection is None:
|
||||
set_tz = True
|
||||
if settings.DATABASE_NAME == '':
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
raise ImproperlyConfigured, "You need to specify DATABASE_NAME in your Django settings file."
|
||||
@ -76,8 +80,13 @@ class DatabaseWrapper(local):
|
||||
self.connection = Database.connect(conn_string, **self.options)
|
||||
self.connection.set_isolation_level(1) # make transactions transparent to all cursors
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
|
||||
if set_tz:
|
||||
cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
|
||||
cursor = UnicodeCursorWrapper(cursor, settings.DEFAULT_CHARSET)
|
||||
global postgres_version
|
||||
if not postgres_version:
|
||||
cursor.execute("SELECT version()")
|
||||
postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')]
|
||||
if settings.DEBUG:
|
||||
return util.CursorDebugWrapper(cursor, self)
|
||||
return cursor
|
||||
@ -136,6 +145,9 @@ def get_limit_offset_sql(limit, offset=None):
|
||||
def get_random_function_sql():
|
||||
return "RANDOM()"
|
||||
|
||||
def get_deferrable_sql():
|
||||
return " DEFERRABLE INITIALLY DEFERRED"
|
||||
|
||||
def get_fulltext_search_sql(field_name):
|
||||
raise NotImplementedError
|
||||
|
||||
@ -145,6 +157,62 @@ def get_drop_foreignkey_sql():
|
||||
def get_pk_default_value():
|
||||
return "DEFAULT"
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
themselves) and put the database in an empty 'initial' state
|
||||
|
||||
"""
|
||||
if tables:
|
||||
if postgres_version[0] >= 8 and postgres_version[1] >= 1:
|
||||
# Postgres 8.1+ can do 'TRUNCATE x, y, z...;'. In fact, it *has to* in order to be able to
|
||||
# truncate tables referenced by a foreign key in any other table. The result is a
|
||||
# single SQL TRUNCATE statement.
|
||||
sql = ['%s %s;' % \
|
||||
(style.SQL_KEYWORD('TRUNCATE'),
|
||||
style.SQL_FIELD(', '.join([quote_name(table) for table in tables]))
|
||||
)]
|
||||
else:
|
||||
# Older versions of Postgres can't do TRUNCATE in a single call, so they must use
|
||||
# a simple delete.
|
||||
sql = ['%s %s %s;' % \
|
||||
(style.SQL_KEYWORD('DELETE'),
|
||||
style.SQL_KEYWORD('FROM'),
|
||||
style.SQL_FIELD(quote_name(table))
|
||||
) for table in tables]
|
||||
|
||||
# 'ALTER SEQUENCE sequence_name RESTART WITH 1;'... style SQL statements
|
||||
# to reset sequence indices
|
||||
for sequence_info in sequences:
|
||||
table_name = sequence_info['table']
|
||||
column_name = sequence_info['column']
|
||||
if column_name and len(column_name)>0:
|
||||
# sequence name in this case will be <table>_<column>_seq
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_%s_seq' % (table_name, column_name)),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
)
|
||||
)
|
||||
else:
|
||||
# sequence name in this case will be <table>_id_seq
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_id_seq' % table_name),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
)
|
||||
)
|
||||
return sql
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
# Register these custom typecasts, because Django expects dates/times to be
|
||||
# in Python's native (standard-library) datetime/time format, whereas psycopg
|
||||
# use mx.DateTime by default.
|
||||
|
@ -20,6 +20,8 @@ except ImportError:
|
||||
# Import copy of _thread_local.py from Python 2.4
|
||||
from django.utils._threading_local import local
|
||||
|
||||
postgres_version = None
|
||||
|
||||
class DatabaseWrapper(local):
|
||||
def __init__(self, **kwargs):
|
||||
self.connection = None
|
||||
@ -28,7 +30,9 @@ class DatabaseWrapper(local):
|
||||
|
||||
def cursor(self):
|
||||
from django.conf import settings
|
||||
set_tz = False
|
||||
if self.connection is None:
|
||||
set_tz = True
|
||||
if settings.DATABASE_NAME == '':
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
raise ImproperlyConfigured, "You need to specify DATABASE_NAME in your Django settings file."
|
||||
@ -45,7 +49,12 @@ class DatabaseWrapper(local):
|
||||
self.connection.set_isolation_level(1) # make transactions transparent to all cursors
|
||||
cursor = self.connection.cursor()
|
||||
cursor.tzinfo_factory = None
|
||||
cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
|
||||
if set_tz:
|
||||
cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
|
||||
global postgres_version
|
||||
if not postgres_version:
|
||||
cursor.execute("SELECT version()")
|
||||
postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')]
|
||||
if settings.DEBUG:
|
||||
return util.CursorDebugWrapper(cursor, self)
|
||||
return cursor
|
||||
@ -96,6 +105,9 @@ def get_limit_offset_sql(limit, offset=None):
|
||||
def get_random_function_sql():
|
||||
return "RANDOM()"
|
||||
|
||||
def get_deferrable_sql():
|
||||
return " DEFERRABLE INITIALLY DEFERRED"
|
||||
|
||||
def get_fulltext_search_sql(field_name):
|
||||
raise NotImplementedError
|
||||
|
||||
@ -105,6 +117,58 @@ def get_drop_foreignkey_sql():
|
||||
def get_pk_default_value():
|
||||
return "DEFAULT"
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
themselves) and put the database in an empty 'initial' state
|
||||
"""
|
||||
if tables:
|
||||
if postgres_version[0] >= 8 and postgres_version[1] >= 1:
|
||||
# Postgres 8.1+ can do 'TRUNCATE x, y, z...;'. In fact, it *has to* in order to be able to
|
||||
# truncate tables referenced by a foreign key in any other table. The result is a
|
||||
# single SQL TRUNCATE statement
|
||||
sql = ['%s %s;' % \
|
||||
(style.SQL_KEYWORD('TRUNCATE'),
|
||||
style.SQL_FIELD(', '.join([quote_name(table) for table in tables]))
|
||||
)]
|
||||
else:
|
||||
sql = ['%s %s %s;' % \
|
||||
(style.SQL_KEYWORD('DELETE'),
|
||||
style.SQL_KEYWORD('FROM'),
|
||||
style.SQL_FIELD(quote_name(table))
|
||||
) for table in tables]
|
||||
|
||||
# 'ALTER SEQUENCE sequence_name RESTART WITH 1;'... style SQL statements
|
||||
# to reset sequence indices
|
||||
for sequence in sequences:
|
||||
table_name = sequence['table']
|
||||
column_name = sequence['column']
|
||||
if column_name and len(column_name) > 0:
|
||||
# sequence name in this case will be <table>_<column>_seq
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_%s_seq' % (table_name, column_name)),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
)
|
||||
)
|
||||
else:
|
||||
# sequence name in this case will be <table>_id_seq
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_id_seq' % table_name),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
)
|
||||
)
|
||||
return sql
|
||||
else:
|
||||
return []
|
||||
|
||||
OPERATOR_MAPPING = {
|
||||
'exact': '= %s',
|
||||
'iexact': 'ILIKE %s',
|
||||
|
@ -139,6 +139,9 @@ def get_limit_offset_sql(limit, offset=None):
|
||||
def get_random_function_sql():
|
||||
return "RANDOM()"
|
||||
|
||||
def get_deferrable_sql():
|
||||
return ""
|
||||
|
||||
def get_fulltext_search_sql(field_name):
|
||||
raise NotImplementedError
|
||||
|
||||
@ -148,6 +151,24 @@ def get_drop_foreignkey_sql():
|
||||
def get_pk_default_value():
|
||||
return "NULL"
|
||||
|
||||
def get_sql_flush(style, tables, sequences):
|
||||
"""Return a list of SQL statements required to remove all data from
|
||||
all tables in the database (without actually removing the tables
|
||||
themselves) and put the database in an empty 'initial' state
|
||||
|
||||
"""
|
||||
# NB: The generated SQL below is specific to SQLite
|
||||
# Note: The DELETE FROM... SQL generated below works for SQLite databases
|
||||
# because constraints don't exist
|
||||
sql = ['%s %s %s;' % \
|
||||
(style.SQL_KEYWORD('DELETE'),
|
||||
style.SQL_KEYWORD('FROM'),
|
||||
style.SQL_FIELD(quote_name(table))
|
||||
) for table in tables]
|
||||
# Note: No requirement for reset of auto-incremented indices (cf. other
|
||||
# get_sql_flush() implementations). Just return SQL at this point
|
||||
return sql
|
||||
|
||||
def _sqlite_date_trunc(lookup_type, dt):
|
||||
try:
|
||||
dt = util.typecast_timestamp(dt)
|
||||
|
@ -13,6 +13,7 @@ from django.dispatch import dispatcher
|
||||
from django.utils.datastructures import SortedDict
|
||||
from django.utils.functional import curry
|
||||
from django.conf import settings
|
||||
from itertools import izip
|
||||
import types
|
||||
import sys
|
||||
import os
|
||||
@ -21,8 +22,8 @@ class ModelBase(type):
|
||||
"Metaclass for all models"
|
||||
def __new__(cls, name, bases, attrs):
|
||||
# If this isn't a subclass of Model, don't do anything special.
|
||||
if not bases or bases == (object,):
|
||||
return type.__new__(cls, name, bases, attrs)
|
||||
if name == 'Model' or not filter(lambda b: issubclass(b, Model), bases):
|
||||
return super(ModelBase, cls).__new__(cls, name, bases, attrs)
|
||||
|
||||
# Create the class.
|
||||
new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')})
|
||||
@ -90,41 +91,74 @@ class Model(object):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs)
|
||||
for f in self._meta.fields:
|
||||
if isinstance(f.rel, ManyToOneRel):
|
||||
try:
|
||||
# Assume object instance was passed in.
|
||||
rel_obj = kwargs.pop(f.name)
|
||||
except KeyError:
|
||||
|
||||
# There is a rather weird disparity here; if kwargs, it's set, then args
|
||||
# overrides it. It should be one or the other; don't duplicate the work
|
||||
# The reason for the kwargs check is that standard iterator passes in by
|
||||
# args, and nstantiation for iteration is 33% faster.
|
||||
args_len = len(args)
|
||||
if args_len > len(self._meta.fields):
|
||||
# Daft, but matches old exception sans the err msg.
|
||||
raise IndexError("Number of args exceeds number of fields")
|
||||
|
||||
fields_iter = iter(self._meta.fields)
|
||||
if not kwargs:
|
||||
# The ordering of the izip calls matter - izip throws StopIteration
|
||||
# when an iter throws it. So if the first iter throws it, the second
|
||||
# is *not* consumed. We rely on this, so don't change the order
|
||||
# without changing the logic.
|
||||
for val, field in izip(args, fields_iter):
|
||||
setattr(self, field.attname, val)
|
||||
else:
|
||||
# Slower, kwargs-ready version.
|
||||
for val, field in izip(args, fields_iter):
|
||||
setattr(self, field.attname, val)
|
||||
kwargs.pop(field.name, None)
|
||||
# Maintain compatibility with existing calls.
|
||||
if isinstance(field.rel, ManyToOneRel):
|
||||
kwargs.pop(field.attname, None)
|
||||
|
||||
# Now we're left with the unprocessed fields that *must* come from
|
||||
# keywords, or default.
|
||||
|
||||
for field in fields_iter:
|
||||
if kwargs:
|
||||
if isinstance(field.rel, ManyToOneRel):
|
||||
try:
|
||||
# Object instance wasn't passed in -- must be an ID.
|
||||
val = kwargs.pop(f.attname)
|
||||
# Assume object instance was passed in.
|
||||
rel_obj = kwargs.pop(field.name)
|
||||
except KeyError:
|
||||
val = f.get_default()
|
||||
else:
|
||||
# Object instance was passed in.
|
||||
# Special case: You can pass in "None" for related objects if it's allowed.
|
||||
if rel_obj is None and f.null:
|
||||
val = None
|
||||
else:
|
||||
try:
|
||||
val = getattr(rel_obj, f.rel.get_related_field().attname)
|
||||
except AttributeError:
|
||||
raise TypeError, "Invalid value: %r should be a %s instance, not a %s" % (f.name, f.rel.to, type(rel_obj))
|
||||
setattr(self, f.attname, val)
|
||||
# Object instance wasn't passed in -- must be an ID.
|
||||
val = kwargs.pop(field.attname)
|
||||
except KeyError:
|
||||
val = field.get_default()
|
||||
else:
|
||||
# Object instance was passed in. Special case: You can
|
||||
# pass in "None" for related objects if it's allowed.
|
||||
if rel_obj is None and field.null:
|
||||
val = None
|
||||
else:
|
||||
try:
|
||||
val = getattr(rel_obj, field.rel.get_related_field().attname)
|
||||
except AttributeError:
|
||||
raise TypeError("Invalid value: %r should be a %s instance, not a %s" %
|
||||
(field.name, field.rel.to, type(rel_obj)))
|
||||
else:
|
||||
val = kwargs.pop(field.attname, field.get_default())
|
||||
else:
|
||||
val = kwargs.pop(f.attname, f.get_default())
|
||||
setattr(self, f.attname, val)
|
||||
for prop in kwargs.keys():
|
||||
try:
|
||||
if isinstance(getattr(self.__class__, prop), property):
|
||||
setattr(self, prop, kwargs.pop(prop))
|
||||
except AttributeError:
|
||||
pass
|
||||
val = field.get_default()
|
||||
setattr(self, field.attname, val)
|
||||
|
||||
if kwargs:
|
||||
raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
|
||||
for i, arg in enumerate(args):
|
||||
setattr(self, self._meta.fields[i].attname, arg)
|
||||
for prop in kwargs.keys():
|
||||
try:
|
||||
if isinstance(getattr(self.__class__, prop), property):
|
||||
setattr(self, prop, kwargs.pop(prop))
|
||||
except AttributeError:
|
||||
pass
|
||||
if kwargs:
|
||||
raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
|
||||
dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)
|
||||
|
||||
def add_to_class(cls, name, value):
|
||||
@ -322,7 +356,7 @@ class Model(object):
|
||||
def _get_FIELD_size(self, field):
|
||||
return os.path.getsize(self._get_FIELD_filename(field))
|
||||
|
||||
def _save_FIELD_file(self, field, filename, raw_contents):
|
||||
def _save_FIELD_file(self, field, filename, raw_contents, save=True):
|
||||
directory = field.get_directory_name()
|
||||
try: # Create the date-based directory if it doesn't exist.
|
||||
os.makedirs(os.path.join(settings.MEDIA_ROOT, directory))
|
||||
@ -357,8 +391,9 @@ class Model(object):
|
||||
if field.height_field:
|
||||
setattr(self, field.height_field, height)
|
||||
|
||||
# Save the object, because it has changed.
|
||||
self.save()
|
||||
# Save the object because it has changed unless save is False
|
||||
if save:
|
||||
self.save()
|
||||
|
||||
_save_FIELD_file.alters_data = True
|
||||
|
||||
|
@ -443,6 +443,8 @@ class DateField(Field):
|
||||
Field.__init__(self, verbose_name, name, **kwargs)
|
||||
|
||||
def to_python(self, value):
|
||||
if value is None:
|
||||
return value
|
||||
if isinstance(value, datetime.datetime):
|
||||
return value.date()
|
||||
if isinstance(value, datetime.date):
|
||||
@ -505,6 +507,8 @@ class DateField(Field):
|
||||
|
||||
class DateTimeField(DateField):
|
||||
def to_python(self, value):
|
||||
if value is None:
|
||||
return value
|
||||
if isinstance(value, datetime.datetime):
|
||||
return value
|
||||
if isinstance(value, datetime.date):
|
||||
@ -631,7 +635,7 @@ class FileField(Field):
|
||||
setattr(cls, 'get_%s_filename' % self.name, curry(cls._get_FIELD_filename, field=self))
|
||||
setattr(cls, 'get_%s_url' % self.name, curry(cls._get_FIELD_url, field=self))
|
||||
setattr(cls, 'get_%s_size' % self.name, curry(cls._get_FIELD_size, field=self))
|
||||
setattr(cls, 'save_%s_file' % self.name, lambda instance, filename, raw_contents: instance._save_FIELD_file(self, filename, raw_contents))
|
||||
setattr(cls, 'save_%s_file' % self.name, lambda instance, filename, raw_contents, save=True: instance._save_FIELD_file(self, filename, raw_contents, save))
|
||||
dispatcher.connect(self.delete_file, signal=signals.post_delete, sender=cls)
|
||||
|
||||
def delete_file(self, instance):
|
||||
@ -649,14 +653,14 @@ class FileField(Field):
|
||||
def get_manipulator_field_names(self, name_prefix):
|
||||
return [name_prefix + self.name + '_file', name_prefix + self.name]
|
||||
|
||||
def save_file(self, new_data, new_object, original_object, change, rel):
|
||||
def save_file(self, new_data, new_object, original_object, change, rel, save=True):
|
||||
upload_field_name = self.get_manipulator_field_names('')[0]
|
||||
if new_data.get(upload_field_name, False):
|
||||
func = getattr(new_object, 'save_%s_file' % self.name)
|
||||
if rel:
|
||||
func(new_data[upload_field_name][0]["filename"], new_data[upload_field_name][0]["content"])
|
||||
func(new_data[upload_field_name][0]["filename"], new_data[upload_field_name][0]["content"], save)
|
||||
else:
|
||||
func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"])
|
||||
func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"], save)
|
||||
|
||||
def get_directory_name(self):
|
||||
return os.path.normpath(datetime.datetime.now().strftime(self.upload_to))
|
||||
@ -700,12 +704,12 @@ class ImageField(FileField):
|
||||
if not self.height_field:
|
||||
setattr(cls, 'get_%s_height' % self.name, curry(cls._get_FIELD_height, field=self))
|
||||
|
||||
def save_file(self, new_data, new_object, original_object, change, rel):
|
||||
FileField.save_file(self, new_data, new_object, original_object, change, rel)
|
||||
def save_file(self, new_data, new_object, original_object, change, rel, save=True):
|
||||
FileField.save_file(self, new_data, new_object, original_object, change, rel, save)
|
||||
# If the image has height and/or width field(s) and they haven't
|
||||
# changed, set the width and/or height field(s) back to their original
|
||||
# values.
|
||||
if change and (self.width_field or self.height_field):
|
||||
if change and (self.width_field or self.height_field) and save:
|
||||
if self.width_field:
|
||||
setattr(new_object, self.width_field, getattr(original_object, self.width_field))
|
||||
if self.height_field:
|
||||
|
@ -621,7 +621,7 @@ class OneToOneField(RelatedField, IntegerField):
|
||||
def formfield(self, **kwargs):
|
||||
defaults = {'queryset': self.rel.to._default_manager.all(), 'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
|
||||
defaults.update(kwargs)
|
||||
return forms.ModelChoiceField(**kwargs)
|
||||
return forms.ModelChoiceField(**defaults)
|
||||
|
||||
class ManyToManyField(RelatedField, Field):
|
||||
def __init__(self, to, **kwargs):
|
||||
|
@ -96,14 +96,16 @@ class AutomaticManipulator(oldforms.Manipulator):
|
||||
if self.change:
|
||||
params[self.opts.pk.attname] = self.obj_key
|
||||
|
||||
# First, save the basic object itself.
|
||||
# First, create the basic object itself.
|
||||
new_object = self.model(**params)
|
||||
new_object.save()
|
||||
|
||||
# Now that the object's been saved, save any uploaded files.
|
||||
# Now that the object's been created, save any uploaded files.
|
||||
for f in self.opts.fields:
|
||||
if isinstance(f, FileField):
|
||||
f.save_file(new_data, new_object, self.change and self.original_object or None, self.change, rel=False)
|
||||
f.save_file(new_data, new_object, self.change and self.original_object or None, self.change, rel=False, save=False)
|
||||
|
||||
# Now save the object
|
||||
new_object.save()
|
||||
|
||||
# Calculate which primary fields have changed.
|
||||
if self.change:
|
||||
|
@ -84,6 +84,7 @@ class QuerySet(object):
|
||||
self._filters = Q()
|
||||
self._order_by = None # Ordering, e.g. ('date', '-name'). If None, use model's ordering.
|
||||
self._select_related = False # Whether to fill cache for related objects.
|
||||
self._max_related_depth = 0 # Maximum "depth" for select_related
|
||||
self._distinct = False # Whether the query should use SELECT DISTINCT.
|
||||
self._select = {} # Dictionary of attname -> SQL.
|
||||
self._where = [] # List of extra WHERE clauses to use.
|
||||
@ -186,7 +187,8 @@ class QuerySet(object):
|
||||
raise StopIteration
|
||||
for row in rows:
|
||||
if fill_cache:
|
||||
obj, index_end = get_cached_row(self.model, row, 0)
|
||||
obj, index_end = get_cached_row(klass=self.model, row=row,
|
||||
index_start=0, max_depth=self._max_related_depth)
|
||||
else:
|
||||
obj = self.model(*row[:index_end])
|
||||
for i, k in enumerate(extra_select):
|
||||
@ -394,9 +396,9 @@ class QuerySet(object):
|
||||
else:
|
||||
return self._filter_or_exclude(None, **filter_obj)
|
||||
|
||||
def select_related(self, true_or_false=True):
|
||||
def select_related(self, true_or_false=True, depth=0):
|
||||
"Returns a new QuerySet instance with '_select_related' modified."
|
||||
return self._clone(_select_related=true_or_false)
|
||||
return self._clone(_select_related=true_or_false, _max_related_depth=depth)
|
||||
|
||||
def order_by(self, *field_names):
|
||||
"Returns a new QuerySet instance with the ordering changed."
|
||||
@ -430,6 +432,7 @@ class QuerySet(object):
|
||||
c._filters = self._filters
|
||||
c._order_by = self._order_by
|
||||
c._select_related = self._select_related
|
||||
c._max_related_depth = self._max_related_depth
|
||||
c._distinct = self._distinct
|
||||
c._select = self._select.copy()
|
||||
c._where = self._where[:]
|
||||
@ -483,7 +486,10 @@ class QuerySet(object):
|
||||
|
||||
# Add additional tables and WHERE clauses based on select_related.
|
||||
if self._select_related:
|
||||
fill_table_cache(opts, select, tables, where, opts.db_table, [opts.db_table])
|
||||
fill_table_cache(opts, select, tables, where,
|
||||
old_prefix=opts.db_table,
|
||||
cache_tables_seen=[opts.db_table],
|
||||
max_depth=self._max_related_depth)
|
||||
|
||||
# Add any additional SELECTs.
|
||||
if self._select:
|
||||
@ -728,21 +734,33 @@ def get_where_clause(lookup_type, table_prefix, field_name, value):
|
||||
return backend.get_fulltext_search_sql(table_prefix + field_name)
|
||||
raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
|
||||
|
||||
def get_cached_row(klass, row, index_start):
|
||||
"Helper function that recursively returns an object with cache filled"
|
||||
def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0):
|
||||
"""Helper function that recursively returns an object with cache filled"""
|
||||
|
||||
# If we've got a max_depth set and we've exceeded that depth, bail now.
|
||||
if max_depth and cur_depth > max_depth:
|
||||
return None
|
||||
|
||||
index_end = index_start + len(klass._meta.fields)
|
||||
obj = klass(*row[index_start:index_end])
|
||||
for f in klass._meta.fields:
|
||||
if f.rel and not f.null:
|
||||
rel_obj, index_end = get_cached_row(f.rel.to, row, index_end)
|
||||
setattr(obj, f.get_cache_name(), rel_obj)
|
||||
cached_row = get_cached_row(f.rel.to, row, index_end, max_depth, cur_depth+1)
|
||||
if cached_row:
|
||||
rel_obj, index_end = cached_row
|
||||
setattr(obj, f.get_cache_name(), rel_obj)
|
||||
return obj, index_end
|
||||
|
||||
def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen):
|
||||
def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen, max_depth=0, cur_depth=0):
|
||||
"""
|
||||
Helper function that recursively populates the select, tables and where (in
|
||||
place) for select_related queries.
|
||||
"""
|
||||
|
||||
# If we've got a max_depth set and we've exceeded that depth, bail now.
|
||||
if max_depth and cur_depth > max_depth:
|
||||
return None
|
||||
|
||||
qn = backend.quote_name
|
||||
for f in opts.fields:
|
||||
if f.rel and not f.null:
|
||||
@ -757,7 +775,7 @@ def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen)
|
||||
where.append('%s.%s = %s.%s' % \
|
||||
(qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column)))
|
||||
select.extend(['%s.%s' % (qn(db_table), qn(f2.column)) for f2 in f.rel.to._meta.fields])
|
||||
fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen)
|
||||
fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen, max_depth, cur_depth+1)
|
||||
|
||||
def parse_lookup(kwarg_items, opts):
|
||||
# Helper function that handles converting API kwargs
|
||||
|
@ -25,7 +25,6 @@ Internal attributes:
|
||||
deletion, (considerably speeds up the cleanup process
|
||||
vs. the original code.)
|
||||
"""
|
||||
from __future__ import generators
|
||||
import types, weakref
|
||||
from django.dispatch import saferef, robustapply, errors
|
||||
|
||||
@ -33,11 +32,6 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id: dispatcher.py,v 1.9 2005/09/17 04:55:57 mcfletch Exp $"
|
||||
__version__ = "$Revision: 1.9 $"[11:-2]
|
||||
|
||||
try:
|
||||
True
|
||||
except NameError:
|
||||
True = 1==1
|
||||
False = 1==0
|
||||
|
||||
class _Parameter:
|
||||
"""Used to represent default parameter values."""
|
||||
@ -140,10 +134,9 @@ def connect(receiver, signal=Any, sender=Any, weak=True):
|
||||
if weak:
|
||||
receiver = saferef.safeRef(receiver, onDelete=_removeReceiver)
|
||||
senderkey = id(sender)
|
||||
if connections.has_key(senderkey):
|
||||
signals = connections[senderkey]
|
||||
else:
|
||||
connections[senderkey] = signals = {}
|
||||
|
||||
signals = connections.setdefault(senderkey, {})
|
||||
|
||||
# Keep track of senders for cleanup.
|
||||
# Is Anonymous something we want to clean up?
|
||||
if sender not in (None, Anonymous, Any):
|
||||
@ -251,10 +244,10 @@ def getReceivers( sender = Any, signal = Any ):
|
||||
to retrieve the actual receiver objects as an iterable
|
||||
object.
|
||||
"""
|
||||
try:
|
||||
return connections[id(sender)][signal]
|
||||
except KeyError:
|
||||
return []
|
||||
existing = connections.get(id(sender))
|
||||
if existing is not None:
|
||||
return existing.get(signal, [])
|
||||
return []
|
||||
|
||||
def liveReceivers(receivers):
|
||||
"""Filter sequence of receivers to get resolved, live receivers
|
||||
@ -278,30 +271,48 @@ def liveReceivers(receivers):
|
||||
def getAllReceivers( sender = Any, signal = Any ):
|
||||
"""Get list of all receivers from global tables
|
||||
|
||||
This gets all receivers which should receive
|
||||
This gets all dereferenced receivers which should receive
|
||||
the given signal from sender, each receiver should
|
||||
be produced only once by the resulting generator
|
||||
"""
|
||||
receivers = {}
|
||||
for set in (
|
||||
# Get receivers that receive *this* signal from *this* sender.
|
||||
getReceivers( sender, signal ),
|
||||
# Add receivers that receive *any* signal from *this* sender.
|
||||
getReceivers( sender, Any ),
|
||||
# Add receivers that receive *this* signal from *any* sender.
|
||||
getReceivers( Any, signal ),
|
||||
# Add receivers that receive *any* signal from *any* sender.
|
||||
getReceivers( Any, Any ),
|
||||
):
|
||||
for receiver in set:
|
||||
if receiver: # filter out dead instance-method weakrefs
|
||||
try:
|
||||
if not receivers.has_key( receiver ):
|
||||
receivers[receiver] = 1
|
||||
yield receiver
|
||||
except TypeError:
|
||||
# dead weakrefs raise TypeError on hash...
|
||||
pass
|
||||
# Get receivers that receive *this* signal from *this* sender.
|
||||
# Add receivers that receive *any* signal from *this* sender.
|
||||
# Add receivers that receive *this* signal from *any* sender.
|
||||
# Add receivers that receive *any* signal from *any* sender.
|
||||
l = []
|
||||
i = id(sender)
|
||||
if i in connections:
|
||||
sender_receivers = connections[i]
|
||||
if signal in sender_receivers:
|
||||
l.extend(sender_receivers[signal])
|
||||
if signal is not Any and Any in sender_receivers:
|
||||
l.extend(sender_receivers[Any])
|
||||
|
||||
if sender is not Any:
|
||||
i = id(Any)
|
||||
if i in connections:
|
||||
sender_receivers = connections[i]
|
||||
if sender_receivers is not None:
|
||||
if signal in sender_receivers:
|
||||
l.extend(sender_receivers[signal])
|
||||
if signal is not Any and Any in sender_receivers:
|
||||
l.extend(sender_receivers[Any])
|
||||
|
||||
for receiver in l:
|
||||
try:
|
||||
if not receiver in receivers:
|
||||
if isinstance(receiver, WEAKREF_TYPES):
|
||||
receiver = receiver()
|
||||
# this should only (rough guess) be possible if somehow, deref'ing
|
||||
# triggered a wipe.
|
||||
if receiver is None:
|
||||
continue
|
||||
receivers[receiver] = 1
|
||||
yield receiver
|
||||
except TypeError:
|
||||
# dead weakrefs raise TypeError on hash...
|
||||
pass
|
||||
|
||||
def send(signal=Any, sender=Anonymous, *arguments, **named):
|
||||
"""Send signal from sender to all connected receivers.
|
||||
@ -340,7 +351,7 @@ def send(signal=Any, sender=Anonymous, *arguments, **named):
|
||||
# Call each receiver with whatever arguments it can accept.
|
||||
# Return a list of tuple pairs [(receiver, response), ... ].
|
||||
responses = []
|
||||
for receiver in liveReceivers(getAllReceivers(sender, signal)):
|
||||
for receiver in getAllReceivers(sender, signal):
|
||||
response = robustapply.robustApply(
|
||||
receiver,
|
||||
signal=signal,
|
||||
@ -350,6 +361,8 @@ def send(signal=Any, sender=Anonymous, *arguments, **named):
|
||||
)
|
||||
responses.append((receiver, response))
|
||||
return responses
|
||||
|
||||
|
||||
def sendExact( signal=Any, sender=Anonymous, *arguments, **named ):
|
||||
"""Send signal only to those receivers registered for exact message
|
||||
|
||||
@ -421,33 +434,18 @@ def _cleanupConnections(senderkey, signal):
|
||||
def _removeSender(senderkey):
|
||||
"""Remove senderkey from connections."""
|
||||
_removeBackrefs(senderkey)
|
||||
try:
|
||||
del connections[senderkey]
|
||||
except KeyError:
|
||||
pass
|
||||
# Senderkey will only be in senders dictionary if sender
|
||||
# could be weakly referenced.
|
||||
try:
|
||||
del senders[senderkey]
|
||||
except:
|
||||
pass
|
||||
|
||||
connections.pop(senderkey, None)
|
||||
senders.pop(senderkey, None)
|
||||
|
||||
|
||||
def _removeBackrefs( senderkey):
|
||||
"""Remove all back-references to this senderkey"""
|
||||
try:
|
||||
signals = connections[senderkey]
|
||||
except KeyError:
|
||||
signals = None
|
||||
else:
|
||||
items = signals.items()
|
||||
def allReceivers( ):
|
||||
for signal,set in items:
|
||||
for item in set:
|
||||
yield item
|
||||
for receiver in allReceivers():
|
||||
for receiver_list in connections.pop(senderkey, {}).values():
|
||||
for receiver in receiver_list:
|
||||
_killBackref( receiver, senderkey )
|
||||
|
||||
|
||||
def _removeOldBackRefs(senderkey, signal, receiver, receivers):
|
||||
"""Kill old sendersBack references from receiver
|
||||
|
||||
@ -483,13 +481,13 @@ def _removeOldBackRefs(senderkey, signal, receiver, receivers):
|
||||
def _killBackref( receiver, senderkey ):
|
||||
"""Do the actual removal of back reference from receiver to senderkey"""
|
||||
receiverkey = id(receiver)
|
||||
set = sendersBack.get( receiverkey, () )
|
||||
while senderkey in set:
|
||||
receivers_list = sendersBack.get( receiverkey, () )
|
||||
while senderkey in receivers_list:
|
||||
try:
|
||||
set.remove( senderkey )
|
||||
receivers_list.remove( senderkey )
|
||||
except:
|
||||
break
|
||||
if not set:
|
||||
if not receivers_list:
|
||||
try:
|
||||
del sendersBack[ receiverkey ]
|
||||
except KeyError:
|
||||
|
@ -52,7 +52,7 @@ def parse_file_upload(header_dict, post_data):
|
||||
POST = MultiValueDict()
|
||||
FILES = MultiValueDict()
|
||||
for submessage in msg.get_payload():
|
||||
if isinstance(submessage, email.Message.Message):
|
||||
if submessage and isinstance(submessage, email.Message.Message):
|
||||
name_dict = parse_header(submessage['Content-Disposition'])[1]
|
||||
# name_dict is something like {'name': 'file', 'filename': 'test.txt'} for file uploads
|
||||
# or {'name': 'blah'} for POST fields
|
||||
|
@ -667,7 +667,11 @@ def resolve_variable(path, context):
|
||||
except (TypeError, AttributeError):
|
||||
try: # list-index lookup
|
||||
current = current[int(bits[0])]
|
||||
except (IndexError, ValueError, KeyError):
|
||||
except (IndexError, # list index out of range
|
||||
ValueError, # invalid literal for int()
|
||||
KeyError, # current is a dict without `int(bits[0])` key
|
||||
TypeError, # unsubscriptable object
|
||||
):
|
||||
raise VariableDoesNotExist("Failed lookup for key [%s] in %r", (bits[0], current)) # missing attribute
|
||||
except Exception, e:
|
||||
if getattr(e, 'silent_variable_failure', False):
|
||||
|
@ -0,0 +1,6 @@
|
||||
"""
|
||||
Django Unit Test and Doctest framework.
|
||||
"""
|
||||
|
||||
from django.test.client import Client
|
||||
from django.test.testcases import TestCase
|
@ -63,6 +63,8 @@ def run_tests(module_list, verbosity=1, extra_tests=[]):
|
||||
looking for doctests and unittests in models.py or tests.py within
|
||||
the module. A list of 'extra' tests may also be provided; these tests
|
||||
will be added to the test suite.
|
||||
|
||||
Returns the number of tests that failed.
|
||||
"""
|
||||
setup_test_environment()
|
||||
|
||||
@ -77,7 +79,10 @@ def run_tests(module_list, verbosity=1, extra_tests=[]):
|
||||
|
||||
old_name = settings.DATABASE_NAME
|
||||
create_test_db(verbosity)
|
||||
unittest.TextTestRunner(verbosity=verbosity).run(suite)
|
||||
result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
|
||||
destroy_test_db(old_name, verbosity)
|
||||
|
||||
teardown_test_environment()
|
||||
|
||||
return len(result.failures)
|
||||
|
@ -1,5 +1,7 @@
|
||||
import re, doctest, unittest
|
||||
from django.db import transaction
|
||||
from django.core import management
|
||||
from django.db.models import get_apps
|
||||
|
||||
normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
|
||||
|
||||
@ -28,3 +30,21 @@ class DocTestRunner(doctest.DocTestRunner):
|
||||
from django.db import transaction
|
||||
transaction.rollback_unless_managed()
|
||||
|
||||
class TestCase(unittest.TestCase):
|
||||
def install_fixtures(self):
|
||||
"""If the Test Case class has a 'fixtures' member, clear the database and
|
||||
install the named fixtures at the start of each test.
|
||||
|
||||
"""
|
||||
management.flush(verbosity=0, interactive=False)
|
||||
if hasattr(self, 'fixtures'):
|
||||
management.load_data(self.fixtures, verbosity=0)
|
||||
|
||||
def run(self, result=None):
|
||||
"""Wrapper around default run method so that user-defined Test Cases
|
||||
automatically call install_fixtures without having to include a call to
|
||||
super().
|
||||
|
||||
"""
|
||||
self.install_fixtures()
|
||||
super(TestCase, self).run(result)
|
||||
|
@ -17,7 +17,10 @@ class MergeDict(object):
|
||||
def __contains__(self, key):
|
||||
return self.has_key(key)
|
||||
|
||||
def get(self, key, default):
|
||||
def __copy__(self):
|
||||
return self.__class__(*self.dicts)
|
||||
|
||||
def get(self, key, default=None):
|
||||
try:
|
||||
return self[key]
|
||||
except KeyError:
|
||||
@ -43,6 +46,10 @@ class MergeDict(object):
|
||||
return True
|
||||
return False
|
||||
|
||||
def copy(self):
|
||||
""" returns a copy of this object"""
|
||||
return self.__copy__()
|
||||
|
||||
class SortedDict(dict):
|
||||
"A dictionary that keeps its keys in the order in which they're inserted."
|
||||
def __init__(self, data=None):
|
||||
|
@ -16,7 +16,7 @@ from django.utils.tzinfo import LocalTimezone
|
||||
from calendar import isleap, monthrange
|
||||
import re, time
|
||||
|
||||
re_formatchars = re.compile(r'(?<!\\)([aABdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])')
|
||||
re_formatchars = re.compile(r'(?<!\\)([aAbBdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])')
|
||||
re_escaped = re.compile(r'\\(.)')
|
||||
|
||||
class Formatter(object):
|
||||
@ -110,6 +110,10 @@ class DateFormat(TimeFormat):
|
||||
if hasattr(self.data, 'hour') and not self.timezone:
|
||||
self.timezone = LocalTimezone(dt)
|
||||
|
||||
def b(self):
|
||||
"Month, textual, 3 letters, lowercase; e.g. 'jan'"
|
||||
return MONTHS_3[self.data.month]
|
||||
|
||||
def d(self):
|
||||
"Day of the month, 2 digits with leading zeros; i.e. '01' to '31'"
|
||||
return '%02d' % self.data.day
|
||||
|
@ -75,7 +75,7 @@ def page_not_found(request, template_name='404.html'):
|
||||
request_path
|
||||
The path of the requested URL (e.g., '/app/pages/bad_page/')
|
||||
"""
|
||||
t = loader.get_template(template_name)
|
||||
t = loader.get_template(template_name) # You need to create a 404.html template.
|
||||
return http.HttpResponseNotFound(t.render(RequestContext(request, {'request_path': request.path})))
|
||||
|
||||
def server_error(request, template_name='500.html'):
|
||||
@ -85,5 +85,5 @@ def server_error(request, template_name='500.html'):
|
||||
Templates: `500.html`
|
||||
Context: None
|
||||
"""
|
||||
t = loader.get_template(template_name)
|
||||
t = loader.get_template(template_name) # You need to create a 500.html template.
|
||||
return http.HttpResponseServerError(t.render(Context({})))
|
||||
|
@ -33,6 +33,12 @@ def object_list(request, queryset, paginate_by=None, page=None,
|
||||
number of pages, total
|
||||
hits
|
||||
number of objects, total
|
||||
last_on_page
|
||||
the result number of the last of object in the
|
||||
object_list (1-indexed)
|
||||
first_on_page
|
||||
the result number of the first object in the
|
||||
object_list (1-indexed)
|
||||
"""
|
||||
if extra_context is None: extra_context = {}
|
||||
queryset = queryset._clone()
|
||||
@ -57,6 +63,8 @@ def object_list(request, queryset, paginate_by=None, page=None,
|
||||
'page': page,
|
||||
'next': page + 1,
|
||||
'previous': page - 1,
|
||||
'last_on_page': paginator.last_on_page(page - 1),
|
||||
'first_on_page': paginator.first_on_page(page - 1),
|
||||
'pages': paginator.pages,
|
||||
'hits' : paginator.hits,
|
||||
}, context_processors)
|
||||
|
@ -86,10 +86,10 @@ objects in the same way as any other `Django model`_::
|
||||
myuser.groups.add(group, group,...)
|
||||
myuser.groups.remove(group, group,...)
|
||||
myuser.groups.clear()
|
||||
myuser.permissions = [permission_list]
|
||||
myuser.permissions.add(permission, permission, ...)
|
||||
myuser.permissions.remove(permission, permission, ...]
|
||||
myuser.permissions.clear()
|
||||
myuser.user_permissions = [permission_list]
|
||||
myuser.user_permissions.add(permission, permission, ...)
|
||||
myuser.user_permissions.remove(permission, permission, ...]
|
||||
myuser.user_permissions.clear()
|
||||
|
||||
In addition to those automatic API methods, ``User`` objects have the following
|
||||
custom methods:
|
||||
@ -317,6 +317,16 @@ This example shows how you might use both ``authenticate()`` and ``login()``::
|
||||
else:
|
||||
# Return an 'invalid login' error message.
|
||||
|
||||
Manually checking a user's password
|
||||
-----------------------------------
|
||||
|
||||
If you'd like to manually authenticate a user by comparing a
|
||||
plain-text password to the hashed password in the database, use the
|
||||
convenience function `django.contrib.auth.models.check_password`. It
|
||||
takes two arguments: the plain-text password to check, and the full
|
||||
value of a user's ``password`` field in the database to check against,
|
||||
and returns ``True`` if they match, ``False`` otherwise.
|
||||
|
||||
How to log a user out
|
||||
---------------------
|
||||
|
||||
@ -388,7 +398,7 @@ To do this, add the following line to your URLconf::
|
||||
|
||||
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
||||
|
||||
Here's what ``django.contrib.auth.views.login`` does::
|
||||
Here's what ``django.contrib.auth.views.login`` does:
|
||||
|
||||
* If called via ``GET``, it displays a login form that POSTs to the same
|
||||
URL. More on this in a bit.
|
||||
@ -444,6 +454,147 @@ block::
|
||||
.. _forms documentation: ../forms/
|
||||
.. _site framework docs: ../sites/
|
||||
|
||||
Other built-in views
|
||||
--------------------
|
||||
|
||||
In addition to the `login` view, the authentication system includes a
|
||||
few other useful built-in views:
|
||||
|
||||
``django.contrib.auth.views.logout``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Description:**
|
||||
|
||||
Logs a user out.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
* ``template_name``: The full name of a template to display after
|
||||
logging the user out. This will default to
|
||||
``registration/logged_out.html`` if no argument is supplied.
|
||||
|
||||
**Template context:**
|
||||
|
||||
* ``title``: The string "Logged out", localized.
|
||||
|
||||
``django.contrib.auth.views.logout_then_login``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Description:**
|
||||
|
||||
Logs a user out, then redirects to the login page.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
* ``login_url``: The URL of the login page to redirect to. This
|
||||
will default to ``/accounts/login/`` if not supplied.
|
||||
|
||||
``django.contrib.auth.views.password_change``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Description:**
|
||||
|
||||
Allows a user to change their password.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
* ``template_name``: The full name of a template to use for
|
||||
displaying the password change form. This will default to
|
||||
``registration/password_change_form.html`` if not supplied.
|
||||
|
||||
**Template context:**
|
||||
|
||||
* ``form``: The password change form.
|
||||
|
||||
``django.contrib.auth.views.password_change_done``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Description:**
|
||||
|
||||
The page shown after a user has changed their password.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
* ``template_name``: The full name of a template to use. This will
|
||||
default to ``registration/password_change_done.html`` if not
|
||||
supplied.
|
||||
|
||||
``django.contrib.auth.views.password_reset``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Description:**
|
||||
|
||||
Allows a user to reset their password, and sends them the new password
|
||||
in an email.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
* ``template_name``: The full name of a template to use for
|
||||
displaying the password reset form. This will default to
|
||||
``registration/password_reset_form.html`` if not supplied.
|
||||
|
||||
* ``email_template_name``: The full name of a template to use for
|
||||
generating the email with the new password. This will default to
|
||||
``registration/password_reset_email.html`` if not supplied.
|
||||
|
||||
**Template context:**
|
||||
|
||||
* ``form``: The form for resetting the user's password.
|
||||
|
||||
``django.contrib.auth.views.password_reset_done``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Description:**
|
||||
|
||||
The page shown after a user has reset their password.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
* ``template_name``: The full name of a template to use. This will
|
||||
default to ``registration/password_reset_done.html`` if not
|
||||
supplied.
|
||||
|
||||
``django.contrib.auth.views.redirect_to_login``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Description:**
|
||||
|
||||
Redirects to the login page, and then back to another URL after a
|
||||
successful login.
|
||||
|
||||
**Required arguments:**
|
||||
|
||||
* ``next``: The URL to redirect to after a successful login.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
* ``login_url``: The URL of the login page to redirect to. This
|
||||
will default to ``/accounts/login/`` if not supplied.
|
||||
|
||||
Built-in manipulators
|
||||
---------------------
|
||||
|
||||
If you don't want to use the built-in views, but want the convenience
|
||||
of not having to write manipulators for this functionality, the
|
||||
authentication system provides several built-in manipulators:
|
||||
|
||||
* ``django.contrib.auth.forms.AdminPasswordChangeForm``: A
|
||||
manipulator used in the admin interface to change a user's
|
||||
password.
|
||||
|
||||
* ``django.contrib.auth.forms.AuthenticationForm``: A manipulator
|
||||
for logging a user in.
|
||||
|
||||
* ``django.contrib.auth.forms.PasswordChangeForm``: A manipulator
|
||||
for allowing a user to change their password.
|
||||
|
||||
* ``django.contrib.auth.forms.PasswordResetForm``: A manipulator
|
||||
for resetting a user's password and emailing the new password to
|
||||
them.
|
||||
|
||||
* ``django.contrib.auth.forms.UserCreationForm``: A manipulator
|
||||
for creating a new user.
|
||||
|
||||
Limiting access to logged-in users that pass a test
|
||||
---------------------------------------------------
|
||||
|
||||
@ -813,13 +964,13 @@ The ``authenticate`` method takes credentials as keyword arguments. Most of
|
||||
the time, it'll just look like this::
|
||||
|
||||
class MyBackend:
|
||||
def authenticate(username=None, password=None):
|
||||
def authenticate(self, username=None, password=None):
|
||||
# Check the username/password and return a User.
|
||||
|
||||
But it could also authenticate a token, like so::
|
||||
|
||||
class MyBackend:
|
||||
def authenticate(token=None):
|
||||
def authenticate(self, token=None):
|
||||
# Check the token and return a User.
|
||||
|
||||
Either way, ``authenticate`` should check the credentials it gets, and it
|
||||
|
@ -596,6 +596,21 @@ related ``Person`` *and* the related ``City``::
|
||||
Note that ``select_related()`` does not follow foreign keys that have
|
||||
``null=True``.
|
||||
|
||||
Usually, using ``select_related()`` can vastly improve performance because your
|
||||
app can avoid many database calls. However, in situations with deeply nested
|
||||
sets of relationships ``select_related()`` can sometimes end up following "too
|
||||
many" relations, and can generate queries so large that they end up being slow.
|
||||
|
||||
In these situations, you can use the ``depth`` argument to ``select_related()``
|
||||
to control how many "levels" of relations ``select_related()`` will actually
|
||||
follow::
|
||||
|
||||
b = Book.objects.select_related(depth=1).get(id=4)
|
||||
p = b.author # Doesn't hit the database.
|
||||
c = p.hometown # Requires a database call.
|
||||
|
||||
The ``depth`` argument is new in the Django development version.
|
||||
|
||||
``extra(select=None, where=None, params=None, tables=None)``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -1621,6 +1636,15 @@ For example, this deletes all ``Entry`` objects with a ``pub_date`` year of
|
||||
|
||||
Entry.objects.filter(pub_date__year=2005).delete()
|
||||
|
||||
When Django deletes an object, it emulates the behavior of the SQL
|
||||
constraint ``ON DELETE CASCADE`` -- in other words, any objects which
|
||||
had foreign keys pointing at the object to be deleted will be deleted
|
||||
along with it. For example::
|
||||
|
||||
b = Blog.objects.get(pk=1)
|
||||
# This will delete the Blog and all of its Entry objects.
|
||||
b.delete()
|
||||
|
||||
Note that ``delete()`` is the only ``QuerySet`` method that is not exposed on a
|
||||
``Manager`` itself. This is a safety mechanism to prevent you from accidentally
|
||||
requesting ``Entry.objects.delete()``, and deleting *all* the entries. If you
|
||||
|
76
docs/distributions.txt
Normal file
76
docs/distributions.txt
Normal file
@ -0,0 +1,76 @@
|
||||
===================================
|
||||
Third-party distributions of Django
|
||||
===================================
|
||||
|
||||
Several third-party distributors are now providing versions of Django integrated
|
||||
with their package-management systems. These can make installation and upgrading
|
||||
much easier for users of Django since the integration includes the ability to
|
||||
automatically install dependancies (like database adapters) that Django
|
||||
requires.
|
||||
|
||||
Typically, these packages are based on the latest stable release of Django, so
|
||||
if you want to use the development version of Django you'll need to follow the
|
||||
instructions for `installing the development version`_ from our Subversion
|
||||
repository.
|
||||
|
||||
.. _installing the development version: ../install/#installing-the-development-version
|
||||
|
||||
Linux distributions
|
||||
===================
|
||||
|
||||
Debian
|
||||
------
|
||||
|
||||
A `packaged version of Django`_ is available for `Debian GNU/Linux`_, and can be
|
||||
installed from either the "testing" or the "unstable" repositories by typing
|
||||
``apt-get install python-django``.
|
||||
|
||||
When you install this package, ``apt`` will recommend installing a database
|
||||
adapter; you should select and install the adapter for whichever database you
|
||||
plan to use with Django.
|
||||
|
||||
.. _Debian GNU/Linux: http://www.debian.org/
|
||||
.. _packaged version of Django: http://packages.debian.org/testing/python/python-django
|
||||
|
||||
Ubuntu
|
||||
------
|
||||
|
||||
The Debian ``python-django`` package is also available for `Ubuntu Linux`_, in
|
||||
the "universe" repository for Ubuntu 7.04 ("Feisty Fawn"). The `current Ubuntu
|
||||
package`_ is also based on Django 0.95.1 and can be installed in the same
|
||||
fashion as for Debian.
|
||||
|
||||
.. _Ubuntu Linux: http://www.ubuntu.com/
|
||||
.. _current Ubuntu package: http://packages.ubuntu.com/feisty/python/python-django
|
||||
|
||||
Fedora
|
||||
------
|
||||
|
||||
A Django package is available for `Fedora Linux`_, in the "Fedora Extras"
|
||||
repository. The `current Fedora package`_ is based on Django 0.95.1, and can be
|
||||
installed by typing ``yum install Django``.
|
||||
|
||||
.. _Fedora Linux: http://fedora.redhat.com/
|
||||
.. _current Fedora package: http://fedoraproject.org/extras/6/i386/repodata/repoview/Django-0-0.95.1-1.fc6.html
|
||||
|
||||
Gentoo
|
||||
------
|
||||
|
||||
A Django build is available for `Gentoo Linux`_, and is based on Django 0.95.1.
|
||||
The `current Gentoo build`_ can be installed by typing ``emerge Django``.
|
||||
|
||||
.. _Gentoo Linux: http://www.gentoo.org/
|
||||
.. _current Gentoo build: http://packages.gentoo.org/packages/?category=dev-python;name=django
|
||||
|
||||
For distributors
|
||||
================
|
||||
|
||||
If you'd like to package Django for distribution, we'd be happy to help out!
|
||||
Please join the `django-developers mailing list`_ and introduce yourself.
|
||||
|
||||
We also encourage all distributors to subscribe to the `django-announce mailing
|
||||
list`_, which is a (very) low-traffic list for announcing new releases of Django
|
||||
and important bugfixes.
|
||||
|
||||
.. _django-developers mailing list: http://groups.google.com/group/django-developers/
|
||||
.. _django-announce mailing list: http://groups.google.com/group/django-announce/
|
@ -97,6 +97,33 @@ example, the default settings don't define ``ROOT_URLCONF``, so
|
||||
Note that Django's default settings live in ``django/conf/global_settings.py``,
|
||||
if you're ever curious to see the full list of defaults.
|
||||
|
||||
dumpdata [appname appname ...]
|
||||
------------------------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Output to standard output all data in the database associated with the named
|
||||
application(s).
|
||||
|
||||
By default, the database will be dumped in JSON format. If you want the output
|
||||
to be in another format, use the ``--format`` option (e.g., ``format=xml``).
|
||||
You may specify any Django serialization backend (including any user specified
|
||||
serialization backends named in the ``SERIALIZATION_MODULES`` setting).
|
||||
|
||||
If no application name is provided, all installed applications will be dumped.
|
||||
|
||||
The output of ``dumpdata`` can be used as input for ``loaddata``.
|
||||
|
||||
flush
|
||||
-----
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Return the database to the state it was in immediately after syncdb was
|
||||
executed. This means that all data will be removed from the database, any
|
||||
post-synchronization handlers will be re-executed, and the ``initial_data``
|
||||
fixture will be re-installed.
|
||||
|
||||
inspectdb
|
||||
---------
|
||||
|
||||
@ -141,8 +168,92 @@ only works in PostgreSQL and with certain types of MySQL tables.
|
||||
install [appname appname ...]
|
||||
-----------------------------
|
||||
|
||||
**Removed in Django development version**
|
||||
|
||||
Executes the equivalent of ``sqlall`` for the given appnames.
|
||||
|
||||
loaddata [fixture fixture ...]
|
||||
------------------------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Searches for and loads the contents of the named fixture into the database.
|
||||
|
||||
A *Fixture* is a collection of files that contain the serialized contents of
|
||||
the database. Each fixture has a unique name; however, the files that
|
||||
comprise the fixture can be distributed over multiple directories, in
|
||||
multiple applications.
|
||||
|
||||
Django will search in three locations for fixtures:
|
||||
|
||||
1. In the ``fixtures`` directory of every installed application
|
||||
2. In any directory named in the ``FIXTURE_DIRS`` setting
|
||||
3. In the literal path named by the fixture
|
||||
|
||||
Django will load any and all fixtures it finds in these locations that match
|
||||
the provided fixture names.
|
||||
|
||||
If the named fixture has a file extension, only fixtures of that type
|
||||
will be loaded. For example::
|
||||
|
||||
django-admin.py loaddata mydata.json
|
||||
|
||||
would only load JSON fixtures called ``mydata``. The fixture extension
|
||||
must correspond to the registered name of a serializer (e.g., ``json`` or
|
||||
``xml``).
|
||||
|
||||
If you omit the extension, Django will search all available fixture types
|
||||
for a matching fixture. For example::
|
||||
|
||||
django-admin.py loaddata mydata
|
||||
|
||||
would look for any fixture of any fixture type called ``mydata``. If a fixture
|
||||
directory contained ``mydata.json``, that fixture would be loaded
|
||||
as a JSON fixture. However, if two fixtures with the same name but different
|
||||
fixture type are discovered (for example, if ``mydata.json`` and
|
||||
``mydata.xml`` were found in the same fixture directory), fixture
|
||||
installation will be aborted, and any data installed in the call to
|
||||
``loaddata`` will be removed from the database.
|
||||
|
||||
The fixtures that are named can include directory components. These
|
||||
directories will be inluded in the search path. For example::
|
||||
|
||||
django-admin.py loaddata foo/bar/mydata.json
|
||||
|
||||
would search ``<appname>/fixtures/foo/bar/mydata.json`` for each installed
|
||||
application, ``<dirname>/foo/bar/mydata.json`` for each directory in
|
||||
``FIXTURE_DIRS``, and the literal path ``foo/bar/mydata.json``.
|
||||
|
||||
Note that the order in which fixture files are processed is undefined. However,
|
||||
all fixture data is installed as a single transaction, so data in
|
||||
one fixture can reference data in another fixture. If the database backend
|
||||
supports row-level constraints, these constraints will be checked at the
|
||||
end of the transaction.
|
||||
|
||||
.. admonition:: MySQL and Fixtures
|
||||
|
||||
Unfortunately, MySQL isn't capable of completely supporting all the
|
||||
features of Django fixtures. If you use MyISAM tables, MySQL doesn't
|
||||
support transactions or constraints, so you won't get a rollback if
|
||||
multiple transaction files are found, or validation of fixture data.
|
||||
If you use InnoDB tables, you won't be able to have any forward
|
||||
references in your data files - MySQL doesn't provide a mechanism to
|
||||
defer checking of row constraints until a transaction is committed.
|
||||
|
||||
reset [appname appname ...]
|
||||
---------------------------
|
||||
Executes the equivalent of ``sqlreset`` for the given appnames.
|
||||
|
||||
runfcgi [options]
|
||||
-----------------
|
||||
Starts a set of FastCGI processes suitable for use with any web server
|
||||
which supports the FastCGI protocol. See the `FastCGI deployment
|
||||
documentation`_ for details. Requires the Python FastCGI module from
|
||||
`flup`_.
|
||||
|
||||
.. _FastCGI deployment documentation: ../fastcgi/
|
||||
.. _flup: http://www.saddi.com/software/flup/
|
||||
|
||||
runserver [optional port number, or ipaddr:port]
|
||||
------------------------------------------------
|
||||
|
||||
@ -236,15 +347,12 @@ sqlclear [appname appname ...]
|
||||
|
||||
Prints the DROP TABLE SQL statements for the given appnames.
|
||||
|
||||
sqlindexes [appname appname ...]
|
||||
----------------------------------------
|
||||
sqlcustom [appname appname ...]
|
||||
-------------------------------
|
||||
|
||||
Prints the CREATE INDEX SQL statements for the given appnames.
|
||||
**New in Django development version**
|
||||
|
||||
sqlinitialdata [appname appname ...]
|
||||
--------------------------------------------
|
||||
|
||||
Prints the initial INSERT SQL statements for the given appnames.
|
||||
Prints the custom SQL statements for the given appnames.
|
||||
|
||||
For each model in each specified app, this command looks for the file
|
||||
``<appname>/sql/<modelname>.sql``, where ``<appname>`` is the given appname and
|
||||
@ -255,11 +363,23 @@ command.
|
||||
|
||||
Each of the SQL files, if given, is expected to contain valid SQL. The SQL
|
||||
files are piped directly into the database after all of the models'
|
||||
table-creation statements have been executed. Use this SQL hook to populate
|
||||
tables with any necessary initial records, SQL functions or test data.
|
||||
table-creation statements have been executed. Use this SQL hook to make any
|
||||
table modifications, or insert any SQL functions into the database.
|
||||
|
||||
Note that the order in which the SQL files are processed is undefined.
|
||||
|
||||
sqlindexes [appname appname ...]
|
||||
----------------------------------------
|
||||
|
||||
Prints the CREATE INDEX SQL statements for the given appnames.
|
||||
|
||||
sqlinitialdata [appname appname ...]
|
||||
--------------------------------------------
|
||||
|
||||
**Removed in Django development version**
|
||||
|
||||
This method has been renamed ``sqlcustom`` in the development version of Django.
|
||||
|
||||
sqlreset [appname appname ...]
|
||||
--------------------------------------
|
||||
|
||||
@ -299,6 +419,10 @@ this command to install the default apps.
|
||||
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
|
||||
give you the option of creating a superuser immediately.
|
||||
|
||||
``syncdb`` will also search for and install any fixture named ``initial_data``.
|
||||
See the documentation for ``loaddata`` for details on the specification of
|
||||
fixture data files.
|
||||
|
||||
test
|
||||
----
|
||||
|
||||
@ -348,12 +472,37 @@ setting the Python path for you.
|
||||
|
||||
.. _import search path: http://diveintopython.org/getting_to_know_python/everything_is_an_object.html
|
||||
|
||||
--format
|
||||
--------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Example usage::
|
||||
|
||||
django-admin.py dumpdata --format=xml
|
||||
|
||||
Specifies the output format that will be used. The name provided must be the name
|
||||
of a registered serializer.
|
||||
|
||||
--help
|
||||
------
|
||||
|
||||
Displays a help message that includes a terse list of all available actions and
|
||||
options.
|
||||
|
||||
--indent
|
||||
--------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Example usage::
|
||||
|
||||
django-admin.py dumpdata --indent=4
|
||||
|
||||
Specifies the number of spaces that will be used for indentation when
|
||||
pretty-printing output. By default, output will *not* be pretty-printed.
|
||||
Pretty-printing will only be enabled if the indent option is provided.
|
||||
|
||||
--noinput
|
||||
---------
|
||||
|
||||
|
@ -34,8 +34,8 @@ The simplest way to send e-mail is using the function
|
||||
``django.core.mail.send_mail()``. Here's its definition::
|
||||
|
||||
send_mail(subject, message, from_email, recipient_list,
|
||||
fail_silently=False, auth_user=EMAIL_HOST_USER,
|
||||
auth_password=EMAIL_HOST_PASSWORD)
|
||||
fail_silently=False, auth_user=None,
|
||||
auth_password=None)
|
||||
|
||||
The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters
|
||||
are required.
|
||||
@ -65,7 +65,7 @@ send_mass_mail()
|
||||
Here's the definition::
|
||||
|
||||
send_mass_mail(datatuple, fail_silently=False,
|
||||
auth_user=EMAIL_HOST_USER, auth_password=EMAIL_HOST_PASSWORD):
|
||||
auth_user=None, auth_password=None):
|
||||
|
||||
``datatuple`` is a tuple in which each element is in this format::
|
||||
|
||||
|
@ -608,6 +608,10 @@ fails. If no message is passed in, a default message is used.
|
||||
order). If the given field does (or does not have, in the latter case) the
|
||||
given value, then the current field being validated is required.
|
||||
|
||||
An optional ``other_label`` argument can be passed which, if given, is used
|
||||
in error messages instead of the value. This allows more user friendly error
|
||||
messages if the value itself is not descriptive enough.
|
||||
|
||||
Note that because validators are called before any ``do_html2python()``
|
||||
functions, the value being compared against is a string. So
|
||||
``RequiredIfOtherFieldEquals('choice', '1')`` is correct, whilst
|
||||
|
@ -686,7 +686,7 @@ A page representing a list of objects.
|
||||
* ``paginate_by``: An integer specifying how many objects should be
|
||||
displayed per page. If this is given, the view will paginate objects with
|
||||
``paginate_by`` objects per page. The view will expect either a ``page``
|
||||
query string parameter (via ``GET``) containing a zero-indexed page
|
||||
query string parameter (via ``GET``) containing a 1-based page
|
||||
number, or a ``page`` variable specified in the URLconf. See
|
||||
"Notes on pagination" below.
|
||||
|
||||
@ -752,6 +752,12 @@ If the results are paginated, the context will contain these extra variables:
|
||||
|
||||
* ``previous``: The previous page number, as an integer. This is 1-based.
|
||||
|
||||
* `last_on_page`: **New in Django development version** The number of the
|
||||
last result on the current page. This is 1-based.
|
||||
|
||||
* `first_on_page`: **New in Django development version** The number of the
|
||||
first result on the current page. This is 1-based.
|
||||
|
||||
* ``pages``: The total number of pages, as an integer.
|
||||
|
||||
* ``hits``: The total number of objects across *all* pages, not just this
|
||||
|
@ -51,16 +51,20 @@ make sure a database server is running. Django works with PostgreSQL_
|
||||
Additionally, you'll need to make sure your Python database bindings are
|
||||
installed.
|
||||
|
||||
* If you're using PostgreSQL, you'll need the psycopg_ package (version 1.1 --
|
||||
not version 1.0 or version 2, which is still in beta). If you're on Windows,
|
||||
check out the unofficial `compiled Windows version`_.
|
||||
* If you're using MySQL, you'll need MySQLdb_.
|
||||
* If you're using PostgreSQL, you'll need the psycopg_ package (version 2 is
|
||||
recommended with ``postgresql_psycopg2`` backend, version 1.1 works also with the
|
||||
``postgresql``` backend).
|
||||
|
||||
If you're on Windows, check out the unofficial `compiled Windows version`_.
|
||||
|
||||
* If you're using MySQL, you'll need MySQLdb_, version 1.2.1p2 or higher.
|
||||
|
||||
* If you're using SQLite, you'll need pysqlite_. Use version 2.0.3 or higher.
|
||||
|
||||
.. _PostgreSQL: http://www.postgresql.org/
|
||||
.. _MySQL: http://www.mysql.com/
|
||||
.. _Django's ticket system: http://code.djangoproject.com/report/1
|
||||
.. _psycopg: http://initd.org/projects/psycopg1
|
||||
.. _psycopg: http://initd.org/tracker/psycopg
|
||||
.. _compiled Windows version: http://stickpeople.com/projects/python/win-psycopg/
|
||||
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
|
||||
.. _SQLite: http://www.sqlite.org/
|
||||
@ -77,10 +81,18 @@ It's easy either way.
|
||||
Installing the official version
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Download Django-0.95.tar.gz from our `download page`_.
|
||||
2. ``tar xzvf Django-0.95.tar.gz``
|
||||
3. ``cd Django-0.95``
|
||||
4. ``sudo python setup.py install``
|
||||
1. Check the `distribution specific notes`_ to see if your
|
||||
platform/distribution provides official Django packages/installers.
|
||||
Distribution-provided packages will typically allow for automatic
|
||||
installation of dependancies and easy upgrade paths.
|
||||
|
||||
2. Download Django-0.95.tar.gz from our `download page`_.
|
||||
|
||||
3. ``tar xzvf Django-0.95.tar.gz``
|
||||
|
||||
4. ``cd Django-0.95``
|
||||
|
||||
5. ``sudo python setup.py install``
|
||||
|
||||
Note that the last command will automatically download and install setuptools_
|
||||
if you don't already have it installed. This requires a working Internet
|
||||
@ -93,6 +105,7 @@ The command will install Django in your Python installation's ``site-packages``
|
||||
directory.
|
||||
|
||||
.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
|
||||
.. _distribution specific notes: ../distributions/
|
||||
|
||||
Installing the development version
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -498,6 +498,12 @@ or outside your model class altogether::
|
||||
class Foo(models.Model):
|
||||
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
||||
|
||||
For each model field that has ``choices`` set, Django will add a method to
|
||||
retrieve the human-readable name for the field's current value. See
|
||||
`get_FOO_display`_ in the database API documentation.
|
||||
|
||||
.. _get_FOO_display: ../db_api/#get-foo-display
|
||||
|
||||
Finally, note that choices can be any iterable object -- not necessarily a
|
||||
list or tuple. This lets you construct choices dynamically. But if you find
|
||||
yourself hacking ``choices`` to be dynamic, you're probably better off using
|
||||
@ -1295,10 +1301,30 @@ A few special cases to note about ``list_display``:
|
||||
|
||||
list_display = ('__str__', 'some_other_field')
|
||||
|
||||
* For any element of ``list_display`` that is not a field on the model, the
|
||||
change list page will not allow ordering by that column. This is because
|
||||
ordering is done at the database level, and Django has no way of knowing
|
||||
how to order the result of a custom method at the SQL level.
|
||||
* Usually, elements of ``list_display`` that aren't actual database fields
|
||||
can't be used in sorting (because Django does all the sorting at the
|
||||
database level).
|
||||
|
||||
However, if an element of ``list_display`` represents a certain database
|
||||
field, you can indicate this fact by setting the ``admin_order_field``
|
||||
attribute of the item.
|
||||
|
||||
For example::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
color_code = models.CharField(maxlength=6)
|
||||
|
||||
class Admin:
|
||||
list_display = ('first_name', 'colored_first_name')
|
||||
|
||||
def colored_first_name(self):
|
||||
return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
|
||||
colored_first_name.allow_tags = True
|
||||
colored_first_name.admin_order_field = 'first_name'
|
||||
|
||||
The above will tell Django to order by the ``first_name`` field when
|
||||
trying to sort by ``colored_first_name`` in the admin.
|
||||
|
||||
``list_display_links``
|
||||
----------------------
|
||||
|
@ -197,6 +197,9 @@ of (Full name, e-mail address). Example::
|
||||
|
||||
(('John', 'john@example.com'), ('Mary', 'mary@example.com'))
|
||||
|
||||
Note that Django will e-mail *all* of these people whenever an error happens. See the
|
||||
section on `error reporting via e-mail`_ for more information.
|
||||
|
||||
ALLOWED_INCLUDE_ROOTS
|
||||
---------------------
|
||||
|
||||
@ -236,10 +239,10 @@ The cache key prefix that the cache middleware should use. See the
|
||||
DATABASE_ENGINE
|
||||
---------------
|
||||
|
||||
Default: ``'postgresql'``
|
||||
Default: ``''`` (Empty string)
|
||||
|
||||
Which database backend to use. Either ``'postgresql'``, ``'mysql'``,
|
||||
``'sqlite3'`` or ``'ado_mssql'``.
|
||||
Which database backend to use. Either ``'postgresql_psycopg2'``,
|
||||
``'postgresql'``, ``'mysql'``, ``'sqlite3'`` or ``'ado_mssql'``.
|
||||
|
||||
DATABASE_HOST
|
||||
-------------
|
||||
@ -328,6 +331,16 @@ Default: ``False``
|
||||
|
||||
A boolean that turns on/off debug mode.
|
||||
|
||||
If you define custom settings, django/views/debug.py has a ``HIDDEN_SETTINGS``
|
||||
regular expression which will hide from the DEBUG view anything that contins
|
||||
``'SECRET``, ``PASSWORD``, or ``PROFANITIES'``. This allows untrusted users to
|
||||
be able to give backtraces without seeing sensitive (or offensive) settings.
|
||||
|
||||
Still, note that there are always going to be sections of your debug output that
|
||||
are inapporpriate for public consumption. File paths, configuration options, and
|
||||
the like all give attackers extra information about your server. Never deploy a
|
||||
site with ``DEBUG`` turned on.
|
||||
|
||||
DEFAULT_CHARSET
|
||||
---------------
|
||||
|
||||
@ -409,12 +422,25 @@ Subject-line prefix for e-mail messages sent with ``django.core.mail.mail_admins
|
||||
or ``django.core.mail.mail_managers``. You'll probably want to include the
|
||||
trailing space.
|
||||
|
||||
FIXTURE_DIRS
|
||||
-------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Default: ``()`` (Empty tuple)
|
||||
|
||||
List of locations of the fixture data files, in search order. Note that
|
||||
these paths should use Unix-style forward slashes, even on Windows. See
|
||||
`Testing Django Applications`_.
|
||||
|
||||
.. _Testing Django Applications: ../testing/
|
||||
|
||||
IGNORABLE_404_ENDS
|
||||
------------------
|
||||
|
||||
Default: ``('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', 'favicon.ico', '.php')``
|
||||
|
||||
See also ``IGNORABLE_404_STARTS``.
|
||||
See also ``IGNORABLE_404_STARTS`` and ``Error reporting via e-mail``.
|
||||
|
||||
IGNORABLE_404_STARTS
|
||||
--------------------
|
||||
@ -422,7 +448,8 @@ IGNORABLE_404_STARTS
|
||||
Default: ``('/cgi-bin/', '/_vti_bin', '/_vti_inf')``
|
||||
|
||||
A tuple of strings that specify beginnings of URLs that should be ignored by
|
||||
the 404 e-mailer. See ``SEND_BROKEN_LINK_EMAILS`` and ``IGNORABLE_404_ENDS``.
|
||||
the 404 e-mailer. See ``SEND_BROKEN_LINK_EMAILS``, ``IGNORABLE_404_ENDS`` and
|
||||
the section on `error reporting via e-mail`_.
|
||||
|
||||
INSTALLED_APPS
|
||||
--------------
|
||||
@ -636,8 +663,19 @@ Default: ``False``
|
||||
Whether to send an e-mail to the ``MANAGERS`` each time somebody visits a
|
||||
Django-powered page that is 404ed with a non-empty referer (i.e., a broken
|
||||
link). This is only used if ``CommonMiddleware`` is installed (see the
|
||||
`middleware docs`_). See also ``IGNORABLE_404_STARTS`` and
|
||||
``IGNORABLE_404_ENDS``.
|
||||
`middleware docs`_). See also ``IGNORABLE_404_STARTS``,
|
||||
``IGNORABLE_404_ENDS`` and the section on `error reporting via e-mail`_
|
||||
|
||||
SERIALIZATION_MODULES
|
||||
---------------------
|
||||
|
||||
Default: Not defined.
|
||||
|
||||
A dictionary of modules containing serializer definitions (provided as
|
||||
strings), keyed by a string identifier for that serialization type. For
|
||||
example, to define a YAML serializer, use::
|
||||
|
||||
SERIALIZATION_MODULES = { 'yaml' : 'path.to.yaml_serializer' }
|
||||
|
||||
SERVER_EMAIL
|
||||
------------
|
||||
@ -977,3 +1015,36 @@ Also, it's an error to call ``configure()`` more than once, or to call
|
||||
|
||||
It boils down to this: Use exactly one of either ``configure()`` or
|
||||
``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
|
||||
|
||||
Error reporting via e-mail
|
||||
==========================
|
||||
|
||||
Server errors
|
||||
-------------
|
||||
|
||||
When ``DEBUG`` is ``False``, Django will e-mail the users listed in the
|
||||
``ADMIN`` setting whenever your code raises an unhandled exception and results
|
||||
in an internal server error (HTTP status code 500). This gives the
|
||||
administrators immediate notification of any errors.
|
||||
|
||||
To disable this behavior, just remove all entries from the ``ADMINS`` setting.
|
||||
|
||||
404 errors
|
||||
----------
|
||||
|
||||
When ``DEBUG`` is ``False`` and your ``MIDDLEWARE_CLASSES`` setting includes
|
||||
``CommonMiddleware``, Django will e-mail the users listed in the ``MANAGERS``
|
||||
setting whenever your code raises a 404 and the request has a referer.
|
||||
(It doesn't bother to e-mail for 404s that don't have a referer.)
|
||||
|
||||
You can tell Django to stop reporting particular 404s by tweaking the
|
||||
``IGNORABLE_404_ENDS`` and ``IGNORABLE_404_STARTS`` settings. Both should be a
|
||||
tuple of strings. For example::
|
||||
|
||||
IGNORABLE_404_ENDS = ('.php', '.cgi')
|
||||
IGNORABLE_404_STARTS = ('/phpmyadmin/')
|
||||
|
||||
In this example, a 404 to any URL ending with ``.php`` or ``.cgi`` will *not*
|
||||
be reported. Neither will any URL starting with ``/phpmyadmin/``.
|
||||
|
||||
To disable this behavior, just remove all entries from the ``MANAGERS`` setting.
|
||||
|
@ -645,6 +645,7 @@ Available format strings:
|
||||
output, because this includes periods
|
||||
to match Associated Press style.)
|
||||
A ``'AM'`` or ``'PM'``. ``'AM'``
|
||||
b Month, textual, 3 letters, lowercase. ``'jan'``
|
||||
B Not implemented.
|
||||
d Day of the month, 2 digits with ``'01'`` to ``'31'``
|
||||
leading zeros.
|
||||
|
@ -198,7 +198,6 @@ used as test conditions.
|
||||
.. _Twill: http://twill.idyll.org/
|
||||
.. _Selenium: http://www.openqa.org/selenium/
|
||||
|
||||
|
||||
Making requests
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@ -357,7 +356,55 @@ The following is a simple unit test using the Test Client::
|
||||
Fixtures
|
||||
--------
|
||||
|
||||
Feature still to come...
|
||||
A test case for a database-backed website isn't much use if there isn't any
|
||||
data in the database. To make it easy to put test data into the database,
|
||||
Django provides a fixtures framework.
|
||||
|
||||
A *Fixture* is a collection of files that contain the serialized contents of
|
||||
the database. Each fixture has a unique name; however, the files that
|
||||
comprise the fixture can be distributed over multiple directories, in
|
||||
multiple applications.
|
||||
|
||||
.. note::
|
||||
If you have synchronized a Django project, you have already experienced
|
||||
the use of one fixture -- the ``initial_data`` fixture. Every time you
|
||||
synchronize the database, Django installs the ``initial_data`` fixture.
|
||||
This provides a mechanism to populate a new database with any initial
|
||||
data (such as a default set of categories). Fixtures with other names
|
||||
can be installed manually using ``django-admin.py loaddata``.
|
||||
|
||||
|
||||
However, for the purposes of unit testing, each test must be able to
|
||||
guarantee the contents of the database at the start of each and every
|
||||
test. To do this, Django provides a TestCase baseclass that can integrate
|
||||
with fixtures.
|
||||
|
||||
Moving from a normal unittest TestCase to a Django TestCase is easy - just
|
||||
change the base class of your test, and define a list of fixtures
|
||||
to be used. For example, the test case from `Writing unittests`_ would
|
||||
look like::
|
||||
|
||||
from django.test import TestCase
|
||||
from myapp.models import Animal
|
||||
|
||||
class AnimalTestCase(TestCase):
|
||||
fixtures = ['mammals.json', 'birds']
|
||||
|
||||
def setUp(self):
|
||||
# test definitions as before
|
||||
|
||||
At the start of each test case, before ``setUp()`` is run, Django will
|
||||
flush the database, returning the database the state it was in directly
|
||||
after ``syncdb`` was called. Then, all the named fixtures are installed.
|
||||
In this example, any JSON fixture called ``mammals``, and any fixture
|
||||
named ``birds`` will be installed. See the documentation on
|
||||
`loading fixtures`_ for more details on defining and installing fixtures.
|
||||
|
||||
.. _`loading fixtures`: ../django_admin/#loaddata-fixture-fixture
|
||||
|
||||
This flush/load procedure is repeated for each test in the test case, so you
|
||||
can be certain that the outcome of a test will not be affected by
|
||||
another test, or the order of test execution.
|
||||
|
||||
Running tests
|
||||
=============
|
||||
@ -417,7 +464,10 @@ failed::
|
||||
|
||||
FAILED (failures=1)
|
||||
|
||||
When the tests have all been executed, the test database is destroyed.
|
||||
The return code for the script will indicate the number of tests that failed.
|
||||
|
||||
Regardless of whether the tests pass or fail, the test database is destroyed when
|
||||
all the tests have been executed.
|
||||
|
||||
Using a different testing framework
|
||||
===================================
|
||||
@ -428,7 +478,8 @@ it does provide a mechanism to allow you to invoke tests constructed for
|
||||
an alternative framework as if they were normal Django tests.
|
||||
|
||||
When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER``
|
||||
setting to determine what to do. By default, ``TEST_RUNNER`` points to ``django.test.simple.run_tests``. This method defines the default Django
|
||||
setting to determine what to do. By default, ``TEST_RUNNER`` points to
|
||||
``django.test.simple.run_tests``. This method defines the default Django
|
||||
testing behavior. This behavior involves:
|
||||
|
||||
#. Performing global pre-test setup
|
||||
@ -436,7 +487,7 @@ testing behavior. This behavior involves:
|
||||
#. Running ``syncdb`` to install models and initial data into the test database
|
||||
#. Looking for Unit Tests and Doctests in ``models.py`` and ``tests.py`` file for each installed application
|
||||
#. Running the Unit Tests and Doctests that are found
|
||||
#. Destroying the test database.
|
||||
#. Destroying the test database
|
||||
#. Performing global post-test teardown
|
||||
|
||||
If you define your own test runner method and point ``TEST_RUNNER``
|
||||
@ -458,6 +509,8 @@ arguments:
|
||||
will be printed to the console; `0` is no output, `1` is normal output,
|
||||
and `2` is verbose output.
|
||||
|
||||
This method should return the number of tests that failed.
|
||||
|
||||
Testing utilities
|
||||
-----------------
|
||||
|
||||
|
@ -19,6 +19,15 @@ installed.
|
||||
|
||||
.. _`Django installed`: ../install/
|
||||
|
||||
.. admonition:: Where to get help:
|
||||
|
||||
If you're having trouble going through this tutorial, please post a message
|
||||
to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll
|
||||
try to help.
|
||||
|
||||
.. _django-users: http://groups.google.com/group/django-users
|
||||
.. _#django: irc://irc.freenode.net/django
|
||||
|
||||
Creating a project
|
||||
==================
|
||||
|
||||
@ -32,6 +41,13 @@ From the command line, ``cd`` into a directory where you'd like to store your
|
||||
code, then run the command ``django-admin.py startproject mysite``. This
|
||||
will create a ``mysite`` directory in your current directory.
|
||||
|
||||
.. note::
|
||||
|
||||
You'll need to avoid naming projects after built-in Python or Django
|
||||
components. In particular, this means you should avoid using names like
|
||||
``django`` (which will conflict with Django itself) or ``site`` (which
|
||||
conflicts with a built-in Python package).
|
||||
|
||||
(``django-admin.py`` should be on your system path if you installed Django via
|
||||
``python setup.py``. If it's not on your path, you can find it in
|
||||
``site-packages/django/bin``, where ``site-packages`` is a directory within
|
||||
|
@ -206,6 +206,21 @@ for the polls app, we manually specify a template name for the results view:
|
||||
``template_name='polls/results.html'``. Otherwise, both views would use the same
|
||||
template. Note that we use ``dict()`` to return an altered dictionary in place.
|
||||
|
||||
.. note:: ``all()`` is lazy
|
||||
|
||||
It might look a little frightening to see ``Poll.objects.all()`` being used
|
||||
in a detail view which only needs one ``Poll`` object, but don't worry;
|
||||
``Poll.objects.all()`` is actually a special object called a ``QuerySet``,
|
||||
which is "lazy" and doesn't hit your database until it absolutely has to. By
|
||||
the time the database query happens, the ``object_detail`` generic view will
|
||||
have narrowed its scope down to a single object, so the eventual query will
|
||||
only select one row from the database.
|
||||
|
||||
If you'd like to know more about how that works, The Django database API
|
||||
documentation `explains the lazy nature of QuerySet objects`_.
|
||||
|
||||
.. _explains the lazy nature of QuerySet objects: ../db_api/#querysets-are-lazy
|
||||
|
||||
In previous parts of the tutorial, the templates have been provided with a context
|
||||
that contains the ``poll`` and ``latest_poll_list`` context variables. However,
|
||||
the generic views provide the variables ``object`` and ``object_list`` as context.
|
||||
|
@ -390,6 +390,13 @@ to pass metadata and options to views.
|
||||
.. _generic views: ../generic_views/
|
||||
.. _syndication framework: ../syndication/
|
||||
|
||||
.. admonition:: Dealing with conflicts
|
||||
|
||||
It's possible to have a URL pattern which captures named keyword arguments,
|
||||
and also passes arguments with the same names in its dictionary of extra
|
||||
arguments. When this happens, the arguments in the dictionary will be used
|
||||
instead of the arguments captured in the URL.
|
||||
|
||||
Passing extra options to ``include()``
|
||||
--------------------------------------
|
||||
|
||||
|
@ -31,6 +31,9 @@
|
||||
#
|
||||
# To uninstall, just remove the line from your .bash_profile and .bashrc.
|
||||
|
||||
# Enable extended pattern matching operators.
|
||||
shopt -s extglob
|
||||
|
||||
_django_completion()
|
||||
{
|
||||
local cur prev opts actions action_shell_opts action_runfcgi_opts
|
||||
@ -58,8 +61,13 @@ _django_completion()
|
||||
||
|
||||
# python manage.py, /some/path/python manage.py (if manage.py exists)
|
||||
( ${COMP_CWORD} -eq 2 &&
|
||||
( $( basename ${COMP_WORDS[0]} ) == python ) &&
|
||||
( $( basename ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
|
||||
( $( basename ${COMP_WORDS[1]} ) == manage.py) &&
|
||||
( -r ${COMP_WORDS[1]} ) )
|
||||
||
|
||||
( ${COMP_CWORD} -eq 2 &&
|
||||
( $( basename ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
|
||||
( $( basename ${COMP_WORDS[1]} ) == django-admin.py) &&
|
||||
( -r ${COMP_WORDS[1]} ) ) ]] ; then
|
||||
|
||||
case ${cur} in
|
||||
@ -79,10 +87,28 @@ _django_completion()
|
||||
adminindex|install|reset| \
|
||||
sql|sqlall|sqlclear|sqlindexes| \
|
||||
sqlinitialdata|sqlreset|sqlsequencereset)
|
||||
# App completion isn't yet implemented, but here's where that
|
||||
# would go.
|
||||
# COMPREPLY=( $(compgen -W "auth core" -- ${cur}) )
|
||||
COMPREPLY=()
|
||||
# App completion
|
||||
settings=""
|
||||
# If settings.py in the PWD, use that
|
||||
if [ -e settings.py ] ; then
|
||||
settings="$PWD/settings.py"
|
||||
else
|
||||
# Use the ENV variable if it is set
|
||||
if [ $DJANGO_SETTINGS_MODULE ] ; then
|
||||
settings=$DJANGO_SETTINGS_MODULE
|
||||
fi
|
||||
fi
|
||||
# Couldn't find settings so return nothing
|
||||
if [ -z $settings ] ; then
|
||||
COMPREPLY=()
|
||||
# Otherwise inspect settings.py file
|
||||
else
|
||||
apps=`sed -n "/INSTALLED_APPS = (/,/)/p" $settings | \
|
||||
grep -v "django.contrib" |
|
||||
sed -n "s/^[ ]*'\(.*\.\)*\(.*\)'.*$/\2 /pg" | \
|
||||
tr -d "\n"`
|
||||
COMPREPLY=( $(compgen -W "${apps}" -- ${cur}) )
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
|
||||
@ -117,3 +143,17 @@ _django_completion()
|
||||
}
|
||||
|
||||
complete -F _django_completion django-admin.py manage.py
|
||||
|
||||
# Support for multiple interpreters.
|
||||
unset pythons
|
||||
if command -v whereis &>/dev/null; then
|
||||
python_interpreters=$(whereis -b python | cut -d " " -f 2-)
|
||||
for python in $python_interpreters; do
|
||||
pythons="${pythons} $(basename $python)"
|
||||
done
|
||||
pythons=$(echo $pythons | tr " " "\n" | sort -u | tr "\n" " ")
|
||||
else
|
||||
pythons=python
|
||||
fi
|
||||
|
||||
complete -F _django_completion -o default $pythons
|
||||
|
2
tests/modeltests/fixtures/__init__.py
Normal file
2
tests/modeltests/fixtures/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
|
18
tests/modeltests/fixtures/fixtures/fixture1.json
Normal file
18
tests/modeltests/fixtures/fixtures/fixture1.json
Normal file
@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"pk": "2",
|
||||
"model": "fixtures.article",
|
||||
"fields": {
|
||||
"headline": "Poker has no place on ESPN",
|
||||
"pub_date": "2006-06-16 12:00:00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": "3",
|
||||
"model": "fixtures.article",
|
||||
"fields": {
|
||||
"headline": "Time to reform copyright",
|
||||
"pub_date": "2006-06-16 13:00:00"
|
||||
}
|
||||
}
|
||||
]
|
18
tests/modeltests/fixtures/fixtures/fixture2.json
Normal file
18
tests/modeltests/fixtures/fixtures/fixture2.json
Normal file
@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"pk": "3",
|
||||
"model": "fixtures.article",
|
||||
"fields": {
|
||||
"headline": "Copyright is fine the way it is",
|
||||
"pub_date": "2006-06-16 14:00:00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": "4",
|
||||
"model": "fixtures.article",
|
||||
"fields": {
|
||||
"headline": "Django conquers world!",
|
||||
"pub_date": "2006-06-16 15:00:00"
|
||||
}
|
||||
}
|
||||
]
|
11
tests/modeltests/fixtures/fixtures/fixture2.xml
Normal file
11
tests/modeltests/fixtures/fixtures/fixture2.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
<object pk="2" model="fixtures.article">
|
||||
<field type="CharField" name="headline">Poker on TV is great!</field>
|
||||
<field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field>
|
||||
</object>
|
||||
<object pk="5" model="fixtures.article">
|
||||
<field type="CharField" name="headline">XML identified as leading cause of cancer</field>
|
||||
<field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field>
|
||||
</object>
|
||||
</django-objects>
|
11
tests/modeltests/fixtures/fixtures/fixture3.xml
Normal file
11
tests/modeltests/fixtures/fixtures/fixture3.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
<object pk="2" model="fixtures.article">
|
||||
<field type="CharField" name="headline">Poker on TV is great!</field>
|
||||
<field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field>
|
||||
</object>
|
||||
<object pk="5" model="fixtures.article">
|
||||
<field type="CharField" name="headline">XML identified as leading cause of cancer</field>
|
||||
<field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field>
|
||||
</object>
|
||||
</django-objects>
|
10
tests/modeltests/fixtures/fixtures/initial_data.json
Normal file
10
tests/modeltests/fixtures/fixtures/initial_data.json
Normal file
@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"pk": "1",
|
||||
"model": "fixtures.article",
|
||||
"fields": {
|
||||
"headline": "Python program becomes self aware",
|
||||
"pub_date": "2006-06-16 11:00:00"
|
||||
}
|
||||
}
|
||||
]
|
88
tests/modeltests/fixtures/models.py
Normal file
88
tests/modeltests/fixtures/models.py
Normal file
@ -0,0 +1,88 @@
|
||||
"""
|
||||
39. Fixtures.
|
||||
|
||||
Fixtures are a way of loading data into the database in bulk. Fixure data
|
||||
can be stored in any serializable format (including JSON and XML). Fixtures
|
||||
are identified by name, and are stored in either a directory named 'fixtures'
|
||||
in the application directory, on in one of the directories named in the
|
||||
FIXTURE_DIRS setting.
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
|
||||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=100, default='Default headline')
|
||||
pub_date = models.DateTimeField()
|
||||
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
class Meta:
|
||||
ordering = ('-pub_date', 'headline')
|
||||
|
||||
__test__ = {'API_TESTS': """
|
||||
>>> from django.core import management
|
||||
>>> from django.db.models import get_app
|
||||
|
||||
# Reset the database representation of this app.
|
||||
# This will return the database to a clean initial state.
|
||||
>>> management.flush(verbosity=0, interactive=False)
|
||||
|
||||
# Syncdb introduces 1 initial data object from initial_data.json.
|
||||
>>> Article.objects.all()
|
||||
[<Article: Python program becomes self aware>]
|
||||
|
||||
# Load fixture 1. Single JSON file, with two objects.
|
||||
>>> management.load_data(['fixture1.json'], verbosity=0)
|
||||
>>> Article.objects.all()
|
||||
[<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]
|
||||
|
||||
# Load fixture 2. JSON file imported by default. Overwrites some existing objects
|
||||
>>> management.load_data(['fixture2.json'], verbosity=0)
|
||||
>>> Article.objects.all()
|
||||
[<Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]
|
||||
|
||||
# Load fixture 3, XML format.
|
||||
>>> management.load_data(['fixture3.xml'], verbosity=0)
|
||||
>>> Article.objects.all()
|
||||
[<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>]
|
||||
|
||||
# Load a fixture that doesn't exist
|
||||
>>> management.load_data(['unknown.json'], verbosity=0)
|
||||
|
||||
# object list is unaffected
|
||||
>>> Article.objects.all()
|
||||
[<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>]
|
||||
|
||||
# Reset the database representation of this app. This will delete all data.
|
||||
>>> management.flush(verbosity=0, interactive=False)
|
||||
>>> Article.objects.all()
|
||||
[<Article: Python program becomes self aware>]
|
||||
|
||||
# Load fixture 1 again, using format discovery
|
||||
>>> management.load_data(['fixture1'], verbosity=0)
|
||||
>>> Article.objects.all()
|
||||
[<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]
|
||||
|
||||
# Try to load fixture 2 using format discovery; this will fail
|
||||
# because there are two fixture2's in the fixtures directory
|
||||
>>> management.load_data(['fixture2'], verbosity=0) # doctest: +ELLIPSIS
|
||||
Multiple fixtures named 'fixture2' in '.../fixtures'. Aborting.
|
||||
|
||||
>>> Article.objects.all()
|
||||
[<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]
|
||||
|
||||
# Dump the current contents of the database as a JSON fixture
|
||||
>>> management.dump_data(['fixtures'], format='json')
|
||||
[{"pk": "3", "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": "2", "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": "1", "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
|
||||
"""}
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
class SampleTestCase(TestCase):
|
||||
fixtures = ['fixture1.json', 'fixture2.json']
|
||||
|
||||
def testClassFixtures(self):
|
||||
"Check that test case has installed 4 fixture objects"
|
||||
self.assertEqual(Article.objects.count(), 4)
|
||||
self.assertEquals(str(Article.objects.all()), "[<Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]")
|
0
tests/modeltests/select_related/__init__.py
Normal file
0
tests/modeltests/select_related/__init__.py
Normal file
152
tests/modeltests/select_related/models.py
Normal file
152
tests/modeltests/select_related/models.py
Normal file
@ -0,0 +1,152 @@
|
||||
"""
|
||||
XXX. Tests for ``select_related()``
|
||||
|
||||
``select_related()`` follows all relationships and pre-caches any foreign key
|
||||
values so that complex trees can be fetched in a single query. However, this
|
||||
isn't always a good idea, so the ``depth`` argument control how many "levels"
|
||||
the select-related behavior will traverse.
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
|
||||
# Who remembers high school biology?
|
||||
|
||||
class Domain(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Kingdom(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
domain = models.ForeignKey(Domain)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Phylum(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
kingdom = models.ForeignKey(Kingdom)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Klass(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
phylum = models.ForeignKey(Phylum)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Order(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
klass = models.ForeignKey(Klass)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Family(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
order = models.ForeignKey(Order)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Genus(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
family = models.ForeignKey(Family)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Species(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
genus = models.ForeignKey(Genus)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def create_tree(stringtree):
|
||||
"""Helper to create a complete tree"""
|
||||
names = stringtree.split()
|
||||
models = [Domain, Kingdom, Phylum, Klass, Order, Family, Genus, Species]
|
||||
assert len(names) == len(models), (names, models)
|
||||
|
||||
parent = None
|
||||
for name, model in zip(names, models):
|
||||
try:
|
||||
obj = model.objects.get(name=name)
|
||||
except model.DoesNotExist:
|
||||
obj = model(name=name)
|
||||
if parent:
|
||||
setattr(obj, parent.__class__.__name__.lower(), parent)
|
||||
obj.save()
|
||||
parent = obj
|
||||
|
||||
__test__ = {'API_TESTS':"""
|
||||
|
||||
# Set up.
|
||||
# The test runner sets settings.DEBUG to False, but we want to gather queries
|
||||
# so we'll set it to True here and reset it at the end of the test suite.
|
||||
>>> from django.conf import settings
|
||||
>>> settings.DEBUG = True
|
||||
|
||||
>>> create_tree("Eukaryota Animalia Anthropoda Insecta Diptera Drosophilidae Drosophila melanogaster")
|
||||
>>> create_tree("Eukaryota Animalia Chordata Mammalia Primates Hominidae Homo sapiens")
|
||||
>>> create_tree("Eukaryota Plantae Magnoliophyta Magnoliopsida Fabales Fabaceae Pisum sativum")
|
||||
>>> create_tree("Eukaryota Fungi Basidiomycota Homobasidiomycatae Agaricales Amanitacae Amanita muscaria")
|
||||
|
||||
>>> from django import db
|
||||
|
||||
# Normally, accessing FKs doesn't fill in related objects:
|
||||
>>> db.reset_queries()
|
||||
>>> fly = Species.objects.get(name="melanogaster")
|
||||
>>> fly.genus.family.order.klass.phylum.kingdom.domain
|
||||
<Domain: Eukaryota>
|
||||
>>> len(db.connection.queries)
|
||||
8
|
||||
|
||||
# However, a select_related() call will fill in those related objects without any extra queries:
|
||||
>>> db.reset_queries()
|
||||
>>> person = Species.objects.select_related().get(name="sapiens")
|
||||
>>> person.genus.family.order.klass.phylum.kingdom.domain
|
||||
<Domain: Eukaryota>
|
||||
>>> len(db.connection.queries)
|
||||
1
|
||||
|
||||
# select_related() also of course applies to entire lists, not just items.
|
||||
# Without select_related()
|
||||
>>> db.reset_queries()
|
||||
>>> world = Species.objects.all()
|
||||
>>> [o.genus.family for o in world]
|
||||
[<Family: Drosophilidae>, <Family: Hominidae>, <Family: Fabaceae>, <Family: Amanitacae>]
|
||||
>>> len(db.connection.queries)
|
||||
9
|
||||
|
||||
# With select_related():
|
||||
>>> db.reset_queries()
|
||||
>>> world = Species.objects.all().select_related()
|
||||
>>> [o.genus.family for o in world]
|
||||
[<Family: Drosophilidae>, <Family: Hominidae>, <Family: Fabaceae>, <Family: Amanitacae>]
|
||||
>>> len(db.connection.queries)
|
||||
1
|
||||
|
||||
# The "depth" argument to select_related() will stop the descent at a particular level:
|
||||
>>> db.reset_queries()
|
||||
>>> pea = Species.objects.select_related(depth=1).get(name="sativum")
|
||||
>>> pea.genus.family.order.klass.phylum.kingdom.domain
|
||||
<Domain: Eukaryota>
|
||||
|
||||
# Notice: one few query than above because of depth=1
|
||||
>>> len(db.connection.queries)
|
||||
7
|
||||
|
||||
>>> db.reset_queries()
|
||||
>>> pea = Species.objects.select_related(depth=5).get(name="sativum")
|
||||
>>> pea.genus.family.order.klass.phylum.kingdom.domain
|
||||
<Domain: Eukaryota>
|
||||
>>> len(db.connection.queries)
|
||||
3
|
||||
|
||||
>>> db.reset_queries()
|
||||
>>> world = Species.objects.all().select_related(depth=2)
|
||||
>>> [o.genus.family.order for o in world]
|
||||
[<Order: Diptera>, <Order: Primates>, <Order: Fabales>, <Order: Agaricales>]
|
||||
>>> len(db.connection.queries)
|
||||
5
|
||||
|
||||
# Reset DEBUG to where we found it.
|
||||
>>> settings.DEBUG = False
|
||||
"""}
|
@ -139,4 +139,24 @@ __test__ = {'API_TESTS':"""
|
||||
... print obj
|
||||
<DeserializedObject: Profile of Joe>
|
||||
|
||||
# Objects ids can be referenced before they are defined in the serialization data
|
||||
# However, the deserialization process will need to be contained within a transaction
|
||||
>>> json = '[{"pk": "3", "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00", "categories": [4, 1], "author": 4}}, {"pk": "4", "model": "serializers.category", "fields": {"name": "Reference"}}, {"pk": "4", "model": "serializers.author", "fields": {"name": "Agnes"}}]'
|
||||
>>> from django.db import transaction
|
||||
>>> transaction.enter_transaction_management()
|
||||
>>> transaction.managed(True)
|
||||
>>> for obj in serializers.deserialize("json", json):
|
||||
... obj.save()
|
||||
|
||||
>>> transaction.commit()
|
||||
>>> transaction.leave_transaction_management()
|
||||
|
||||
>>> article = Article.objects.get(pk=3)
|
||||
>>> article
|
||||
<Article: Forward references pose no problem>
|
||||
>>> article.categories.all()
|
||||
[<Category: Reference>, <Category: Sports>]
|
||||
>>> article.author
|
||||
<Author: Agnes>
|
||||
|
||||
"""}
|
||||
|
20
tests/modeltests/test_client/fixtures/testdata.json
Normal file
20
tests/modeltests/test_client/fixtures/testdata.json
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"pk": "1",
|
||||
"model": "auth.user",
|
||||
"fields": {
|
||||
"username": "testclient",
|
||||
"first_name": "Test",
|
||||
"last_name": "Client",
|
||||
"is_active": true,
|
||||
"is_superuser": false,
|
||||
"is_staff": false,
|
||||
"last_login": "2006-12-17 07:03:31",
|
||||
"groups": [],
|
||||
"user_permissions": [],
|
||||
"password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161",
|
||||
"email": "testclient@example.com",
|
||||
"date_joined": "2006-12-17 07:03:31"
|
||||
}
|
||||
}
|
||||
]
|
@ -1,10 +0,0 @@
|
||||
from django.dispatch import dispatcher
|
||||
from django.db.models import signals
|
||||
import models as test_client_app
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
def setup_test(app, created_models, verbosity):
|
||||
# Create a user account for the login-based tests
|
||||
User.objects.create_user('testclient','testclient@example.com', 'password')
|
||||
|
||||
dispatcher.connect(setup_test, sender=test_client_app, signal=signals.post_syncdb)
|
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