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

[full-history]

* Merge from trunk revisions 4733-4812 (with svnmerge)



git-svn-id: http://code.djangoproject.com/svn/django/branches/full-history@4815 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Uroš Trebec 2007-03-24 00:24:29 +00:00
parent 994b52661a
commit 77518506b5
79 changed files with 5008 additions and 1519 deletions

View File

@ -133,6 +133,7 @@ answer newbie questions, and generally made Django that much better:
masonsimon+django@gmail.com
Manuzhai
Petar Marić <http://www.petarmaric.com/>
Nuno Mariz <nmariz@gmail.com>
mark@junklight.com
Yasushi Masuda <whosaysni@gmail.com>
mattycakes@gmail.com

View File

@ -1 +1 @@
VERSION = (0, 96, 'pre')
VERSION = (0, 96, None)

View File

@ -61,6 +61,7 @@ LANGUAGES = (
('nl', gettext_noop('Dutch')),
('no', gettext_noop('Norwegian')),
('pl', gettext_noop('Polish')),
('pt', gettext_noop('Portugese')),
('pt-br', gettext_noop('Brazilian')),
('ro', gettext_noop('Romanian')),
('ru', gettext_noop('Russian')),

View File

@ -11,7 +11,7 @@ msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-02-26 20:44+0100\n"
"PO-Revision-Date: 2007-02-27 20:06+0100\n"
"PO-Revision-Date: 2007-03-14 19:29+0100\n"
"Last-Translator: Nicola Larosa <nico@tekNico.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -523,7 +523,7 @@ msgstr ""
#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
msgid "The two password fields didn't match."
msgstr "I due campi parola chiave non corrispondono."
msgstr "I due campi password non corrispondono."
#: contrib/auth/forms.py:25
msgid "A user with that username already exists."
@ -555,7 +555,7 @@ msgstr "Questo indirizzo email non è associato ad alcun account utente. Sei sic
#: contrib/auth/forms.py:117
msgid "The two 'new password' fields didn't match."
msgstr "I due campi 'nuova parola chiave' non corrispondono."
msgstr "I due campi 'nuova password' non corrispondono."
#: contrib/auth/forms.py:124
msgid "Your old password was entered incorrectly. Please enter it again."
@ -609,13 +609,13 @@ msgstr "indirizzo e-mail"
#: contrib/auth/models.py:94
msgid "password"
msgstr "parola chiave"
msgstr "password"
#: contrib/auth/models.py:94
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
msgstr "Usare '[algo]$[salt]$[hexdigest]' oppure la maschera di <a href=\"password/\">cambio parola chiave</a>."
msgstr "Usare '[algo]$[salt]$[hexdigest]' oppure la maschera di <a href=\"password/\">cambio password</a>."
#: contrib/auth/models.py:95
msgid "staff status"
@ -1040,12 +1040,12 @@ msgstr "Aggiungi utente"
#: contrib/admin/views/auth.py:57
msgid "Password changed successfully."
msgstr "La parola chiave è stata cambiata correttamente."
msgstr "La password è stata cambiata correttamente."
#: contrib/admin/views/auth.py:64
#, python-format
msgid "Change password: %s"
msgstr "Cambia la parola chiave: %s"
msgstr "Cambia la password: %s"
#: contrib/admin/templatetags/admin_list.py:247
msgid "All dates"
@ -1088,7 +1088,7 @@ msgstr "Documentazione"
#: contrib/admin/templates/registration/password_change_form.html:3
#: contrib/admin/templates/registration/password_change_done.html:3
msgid "Change password"
msgstr "Cambia la parola chiave"
msgstr "Cambia la password"
#: contrib/admin/templates/admin/delete_confirmation.html:3
#: contrib/admin/templates/admin/change_form.html:10
@ -1335,11 +1335,11 @@ msgstr "Nome utente:"
#: contrib/admin/templates/admin/login.html:20
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Parola chiave:"
msgstr "Password:"
#: contrib/admin/templates/admin/login.html:22
msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
msgstr "Hai <a href=\"/password_reset/\">dimenticato la parola chiave</a>?"
msgstr "Hai <a href=\"/password_reset/\">dimenticato la password</a>?"
#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
@ -1349,7 +1349,7 @@ msgstr "Benvenuto,"
msgid ""
"First, enter a username and password. Then, you'll be able to edit more user "
"options."
msgstr "Inserire innanzitutto nome utente e parola chiave. Si potrà quindi modificare le altre impostazioni dell'utente."
msgstr "Inserire innanzitutto nome utente e password. Si potrà quindi modificare le altre impostazioni dell'utente."
#: contrib/admin/templates/admin/auth/user/add_form.html:12
msgid "Username"
@ -1358,22 +1358,22 @@ msgstr "Nome utente"
#: contrib/admin/templates/admin/auth/user/add_form.html:18
#: contrib/admin/templates/admin/auth/user/change_password.html:34
msgid "Password"
msgstr "Parola chiave"
msgstr "Password"
#: contrib/admin/templates/admin/auth/user/add_form.html:23
#: contrib/admin/templates/admin/auth/user/change_password.html:39
msgid "Password (again)"
msgstr "Parola chiave (di nuovo)"
msgstr "Password (di nuovo)"
#: contrib/admin/templates/admin/auth/user/add_form.html:24
#: contrib/admin/templates/admin/auth/user/change_password.html:40
msgid "Enter the same password as above, for verification."
msgstr "Inserire la stessa parola chiave inserita sopra, come verifica."
msgstr "Inserire la stessa password inserita sopra, come verifica."
#: 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 "Inserire una nuova parola chiave per l'utente <strong>%(username)s</strong>."
msgstr "Inserire una nuova password per l'utente <strong>%(username)s</strong>."
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
msgid "Bookmarklets"
@ -1460,13 +1460,13 @@ msgstr "Modifica:"
#: contrib/admin/templates/registration/password_reset_form.html:10
#: contrib/admin/templates/registration/password_reset_done.html:4
msgid "Password reset"
msgstr "Reimposta la parola chiave"
msgstr "Reimposta la password"
#: 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 "Dimenticata la parola chiave? Inserire il proprio indirizzo e-mail qui sotto: la parola chiave sarà reimpostata, e la nuova ti verrà inviata per e-mail."
msgstr "Dimenticata la password? Inserire il proprio indirizzo e-mail qui sotto: la password sarà reimpostata, e la nuova ti verrà inviata per e-mail."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@ -1474,11 +1474,11 @@ msgstr "Indirizzo e-mail:"
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "Reset my password"
msgstr "Reimposta la mia parola chiave"
msgstr "Reimposta la mia password"
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
msgstr "Hai ricevuto questa e-mail perché hai chiesto di reimpostare la parola chiave"
msgstr "Hai ricevuto questa e-mail perché hai chiesto di reimpostare la password"
#: contrib/admin/templates/registration/password_reset_email.html:3
#, python-format
@ -1488,11 +1488,11 @@ msgstr "per il tuo account utente su %(site_name)s"
#: contrib/admin/templates/registration/password_reset_email.html:5
#, python-format
msgid "Your new password is: %(new_password)s"
msgstr "La tua nuova parola chiave è: %(new_password)s"
msgstr "La tua nuova password è: %(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 "Puoi liberamente cambiare la tua parola chiave tramite questa pagina:"
msgstr "Puoi liberamente cambiare la tua password tramite questa pagina:"
#: contrib/admin/templates/registration/password_reset_email.html:11
msgid "Your username, in case you've forgotten:"
@ -1518,51 +1518,51 @@ msgstr "Accedi di nuovo"
#: contrib/admin/templates/registration/password_reset_done.html:6
#: contrib/admin/templates/registration/password_reset_done.html:10
msgid "Password reset successful"
msgstr "Parola chiave reimpostata correttamente"
msgstr "Password reimpostata correttamente"
#: 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 "La nuova parola chiave è stata inviata all'indirizzo e-mail inserito. Arriverà a breve."
msgstr "La nuova password è stata inviata all'indirizzo e-mail inserito. Arriverà a breve."
#: contrib/admin/templates/registration/password_change_form.html:4
#: contrib/admin/templates/registration/password_change_form.html:6
#: contrib/admin/templates/registration/password_change_form.html:10
#: contrib/admin/templates/registration/password_change_done.html:4
msgid "Password change"
msgstr "Cambio di parola chiave"
msgstr "Cambio password"
#: 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 "Inserire l'attuale parola chiave, per ragioni di sicurezza, e poi la nuova parola chiave due volte, per verificare di averla scritta correttamente."
msgstr "Inserire l'attuale password, per ragioni di sicurezza, e poi la nuova password due volte, per verificare di averla scritta correttamente."
#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Parola chiave attuale:"
msgstr "Password attuale:"
#: contrib/admin/templates/registration/password_change_form.html:19
msgid "New password:"
msgstr "Nuova parola chiave:"
msgstr "Nuova password:"
#: contrib/admin/templates/registration/password_change_form.html:21
msgid "Confirm password:"
msgstr "Confermare la parola chiave:"
msgstr "Confermare la password:"
#: contrib/admin/templates/registration/password_change_form.html:23
msgid "Change my password"
msgstr "Modifica la mia parola chiave"
msgstr "Modifica la mia password"
#: contrib/admin/templates/registration/password_change_done.html:6
#: contrib/admin/templates/registration/password_change_done.html:10
msgid "Password change successful"
msgstr "Cambio di parola chiave avvenuto correttamente"
msgstr "Cambio di password avvenuto correttamente"
#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "La parola chiave è stata cambiata."
msgstr "La password è stata cambiata."
#: contrib/sites/models.py:10
msgid "domain name"
@ -1905,7 +1905,7 @@ msgstr "Il modulo di commento non fornisce né 'anteprima' né 'invia'"
#: contrib/comments/templates/comments/form.html:8
msgid "Forgotten your password?"
msgstr "Hai dimenticato la parola chiave?"
msgstr "Hai dimenticato la password?"
#: contrib/comments/templates/comments/form.html:12
msgid "Ratings"

Binary file not shown.

View File

@ -0,0 +1,112 @@
# translation of djangojs.po to Polish
# Copyright (C) 2007 Michal Chruszcz
# This file is distributed under the same license as the django package.
#
# Michal Chruszcz <troll@pld-linux.org>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
"PO-Revision-Date: 2007-03-12 11:42+0100\n"
"Last-Translator: Michal Chruszcz <troll@pld-linux.org>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
msgstr "Dostępne %s"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
msgstr "Wybierz wszystko"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
msgstr "Dodaj"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
msgstr "Usuń"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
msgid "Chosen %s"
msgstr "Wybrano %s"
#: contrib/admin/media/js/SelectFilter2.js:54
#, fuzzy
msgid "Select your choice(s) and click "
msgstr "Zaznacz swój wybór i kliknij "
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
msgstr "Wyczyść wszystko"
#: 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 "Styczeń Luty Marzec Kwiecień Maj Czerwiec Lipiec Sierpień Wrzesień Październik Listopad Grudzień"
#: contrib/admin/media/js/dateparse.js:27
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "Niedziela Poniedziałek Wtorek Środa Czwartek Piątek Sobota"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "N Pn Wt Śr Cz Pt So"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
msgid "Now"
msgstr "Teraz"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
msgid "Clock"
msgstr "Zegar"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
msgid "Choose a time"
msgstr "Wybierz czas"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Midnight"
msgstr "Północ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "6 a.m."
msgstr "6 rano"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "Noon"
msgstr "Południe"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
msgid "Cancel"
msgstr "Anuluj"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
msgid "Today"
msgstr "Dzisiaj"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
msgid "Calendar"
msgstr "Kalendarz"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
msgid "Yesterday"
msgstr "Wczoraj"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
msgid "Tomorrow"
msgstr "Jutro"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,108 @@
# Portuguese translation of Django.
# Copyright (C) 2007 the Lawrence Journal-World
# This file is distributed under the same license as the PACKAGE package.
# Nuno Mariz <nmariz@gmail.com>, 2007.
#
msgid ""
msgstr ""
"Project-Id-Version: Django 0.96pre\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-03-15 11:51+0100\n"
"PO-Revision-Date: 2007-03-16 10:01+0000\n"
"Last-Translator: Nuno Mariz <nmariz@gmail.com>\n"
"Language-Team: pt_PT <nmariz@gmail.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
msgstr "Disponível %s"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
msgstr "Escolher todos"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
msgstr "Adicionar"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
msgstr "Remover"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
msgid "Chosen %s"
msgstr "Escolhido %s"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
msgstr "Seleccione a(s) sua(s) escolha(s) e clique "
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
msgstr "Limpar tudo"
#: 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 "Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Outubro Novembro Dezembro"
#: contrib/admin/media/js/dateparse.js:27
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "Domingo Segunda Terça Quarta Quinta Sexta Sábado"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "D S T Q Q S S"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
msgid "Now"
msgstr "Agora"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
msgid "Clock"
msgstr "Relógio"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
msgid "Choose a time"
msgstr "Escolha a hora"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Midnight"
msgstr "Meia-noite"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "6 a.m."
msgstr "6 a.m."
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "Noon"
msgstr "Meio-dia"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
msgid "Cancel"
msgstr "Cancelar"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
msgid "Today"
msgstr "Hoje"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
msgid "Calendar"
msgstr "Calendário"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
msgid "Yesterday"
msgstr "Ontem"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
msgid "Tomorrow"
msgstr "Amanhã"

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,112 @@
# translation of djangojs.po to tamil
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# PONNUSAMY.A <ponnusamy.simpleman@gmail.com>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: djangojs\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-12-09 11:51+0100\n"
"PO-Revision-Date: 2007-03-14 16:40+0530\n"
"Last-Translator: PONNUSAMY <ponnusamy.simpleman@gmail.com>\n"
"Language-Team: tamil <tamilinix@yahoogroups.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
msgstr "%s இருக்கிறதா "
#: 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 "காலை 6 மணி "
#: 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 "நாளை"

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
{{ form }}
</table>
<input type="hidden" name="{{ stage_field }}" value="1" />
<p><input type="submit" value="Submit" /></p>
<p><input type="submit" value="Preview" /></p>
</form>
{% endblock %}

View File

@ -7,7 +7,7 @@
<table>
{% for field in form %}
<tr>
<th>{{ field.verbose_name }}:</th>
<th>{{ field.label }}:</th>
<td>{{ field.data|escape }}</td>
</tr>
{% endfor %}
@ -30,7 +30,7 @@
{{ form }}
</table>
<input type="hidden" name="{{ stage_field }}" value="1" />
<p><input type="submit" value="Submit changes" /></p>
<p><input type="submit" value="Preview" /></p>
</form>
{% endblock %}

View File

@ -83,7 +83,12 @@ class SessionMiddleware(object):
if accessed:
patch_vary_headers(response, ('Cookie',))
if modified or settings.SESSION_SAVE_EVERY_REQUEST:
session_key = request.session.session_key or Session.objects.get_new_session_key()
if request.session.session_key:
session_key = request.session.session_key
else:
obj = Session.objects.get_new_session_object()
session_key = obj.session_key
if settings.SESSION_EXPIRE_AT_BROWSER_CLOSE:
max_age = None
expires = None

View File

@ -1,4 +1,4 @@
import base64, md5, random, sys
import base64, md5, random, sys, datetime
import cPickle as pickle
from django.db import models
from django.utils.translation import gettext_lazy as _
@ -23,6 +23,23 @@ class SessionManager(models.Manager):
break
return session_key
def get_new_session_object(self):
"""
Returns a new session object.
"""
# FIXME: There is a *small* chance of collision here, meaning we will
# return an existing object. That can be fixed when we add a way to
# validate (and guarantee) that non-auto primary keys are unique. For
# now, we save immediately in order to reduce the "window of
# misfortune" as much as possible.
created = False
while not created:
obj, created = self.get_or_create(session_key=self.get_new_session_key(),
expire_date = datetime.datetime.now())
# Collision in key generation, so re-seed the generator
random.seed()
return obj
def save(self, session_key, session_dict, expire_date):
s = self.model(session_key, self.encode(session_dict), expire_date)
if session_dict:

View File

@ -280,7 +280,7 @@ def get_sql_delete(app):
from django.db import backend, connection, models, get_introspection_module
introspection = get_introspection_module()
# This should work even if a connecton isn't available
# This should work even if a connection isn't available
try:
cursor = connection.cursor()
except:
@ -512,6 +512,7 @@ def syncdb(verbosity=1, interactive=True):
created_models = set()
pending_references = {}
# Create the tables for each model
for app in models.get_apps():
app_name = app.__name__.split('.')[-2]
model_list = models.get_models(app)
@ -533,6 +534,11 @@ def syncdb(verbosity=1, interactive=True):
cursor.execute(statement)
table_list.append(model._meta.db_table)
# Create the m2m tables. This must be done after all tables have been created
# to ensure that all referred tables will exist.
for app in models.get_apps():
app_name = app.__name__.split('.')[-2]
model_list = models.get_models(app)
for model in model_list:
if model in created_models:
sql = _get_many_to_many_sql_for_model(model)
@ -542,7 +548,7 @@ def syncdb(verbosity=1, interactive=True):
for statement in sql:
cursor.execute(statement)
transaction.commit_unless_managed()
transaction.commit_unless_managed()
# Send the post_syncdb signal, so individual apps can do whatever they need
# to do at this point.

View File

@ -34,17 +34,17 @@ class Serializer(object):
for obj in queryset:
self.start_object(obj)
for field in obj._meta.fields:
if field is obj._meta.pk:
continue
elif field.rel is None:
if self.selected_fields is None or field.attname in self.selected_fields:
self.handle_field(obj, field)
else:
if self.selected_fields is None or field.attname[:-3] in self.selected_fields:
self.handle_fk_field(obj, field)
if field.serialize:
if field.rel is None:
if self.selected_fields is None or field.attname in self.selected_fields:
self.handle_field(obj, field)
else:
if self.selected_fields is None or field.attname[:-3] in self.selected_fields:
self.handle_fk_field(obj, field)
for field in obj._meta.many_to_many:
if self.selected_fields is None or field.attname in self.selected_fields:
self.handle_m2m_field(obj, field)
if field.serialize:
if self.selected_fields is None or field.attname in self.selected_fields:
self.handle_m2m_field(obj, field)
self.end_object(obj)
self.end_serialization()
return self.getvalue()

View File

@ -15,7 +15,7 @@ import yaml
class Serializer(PythonSerializer):
"""
Convert a queryset to JSON.
Convert a queryset to YAML.
"""
def end_serialization(self):
yaml.dump(self.objects, self.stream, **self.options)
@ -25,7 +25,7 @@ class Serializer(PythonSerializer):
def Deserializer(stream_or_string, **options):
"""
Deserialize a stream or string of JSON data.
Deserialize a stream or string of YAML data.
"""
if isinstance(stream_or_string, basestring):
stream = StringIO(stream_or_string)

View File

@ -13,6 +13,10 @@ class Serializer(base.Serializer):
Serializes a QuerySet to XML.
"""
def indent(self, level):
if self.options.get('indent', None) is not None:
self.xml.ignorableWhitespace('\n' + ' ' * self.options.get('indent', None) * level)
def start_serialization(self):
"""
Start serialization -- open the XML document and the root element.
@ -25,6 +29,7 @@ class Serializer(base.Serializer):
"""
End serialization -- end the document.
"""
self.indent(0)
self.xml.endElement("django-objects")
self.xml.endDocument()
@ -35,6 +40,7 @@ class Serializer(base.Serializer):
if not hasattr(obj, "_meta"):
raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj))
self.indent(1)
self.xml.startElement("object", {
"pk" : str(obj._get_pk_val()),
"model" : str(obj._meta),
@ -44,6 +50,7 @@ class Serializer(base.Serializer):
"""
Called after handling all fields for an object.
"""
self.indent(1)
self.xml.endElement("object")
def handle_field(self, obj, field):
@ -51,6 +58,7 @@ class Serializer(base.Serializer):
Called to handle each field on an object (except for ForeignKeys and
ManyToManyFields)
"""
self.indent(2)
self.xml.startElement("field", {
"name" : field.name,
"type" : field.get_internal_type()
@ -94,6 +102,7 @@ class Serializer(base.Serializer):
"""
Helper to output the <field> element for relational fields
"""
self.indent(2)
self.xml.startElement("field", {
"name" : field.name,
"rel" : field.rel.__class__.__name__,

View File

@ -10,8 +10,14 @@ try:
except ImportError, e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured, "Error loading MySQLdb module: %s" % e
if Database.version_info < (1,2,1,'final',2):
raise ImportError, "MySQLdb-1.2.1p2 or newer is required; you have %s" % MySQLdb.__version__
# We want version (1, 2, 1, 'final', 2) or later. We can't just use
# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
# inadvertently passes the version test.
version = Database.version_info
if (version < (1,2,1) or (version[:3] == (1, 2, 1) and
(len(version) < 5 or version[3] != 'final' or version[4] < 2))):
raise ImportError, "MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__
from MySQLdb.converters import conversions
from MySQLdb.constants import FIELD_TYPE
@ -74,6 +80,8 @@ class DatabaseWrapper(local):
if not self._valid_connection():
kwargs = {
'conv': django_conversions,
'charset': 'utf8',
'use_unicode': False,
}
if settings.DATABASE_USER:
kwargs['user'] = settings.DATABASE_USER

View File

View File

@ -0,0 +1,233 @@
"""
MySQL database backend for Django.
Requires MySQLdb: http://sourceforge.net/projects/mysql-python
"""
from django.db.backends import util
try:
import MySQLdb as Database
except ImportError, e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured, "Error loading MySQLdb module: %s" % e
from MySQLdb.converters import conversions
from MySQLdb.constants import FIELD_TYPE
import types
import re
DatabaseError = Database.DatabaseError
django_conversions = conversions.copy()
django_conversions.update({
types.BooleanType: util.rev_typecast_boolean,
FIELD_TYPE.DATETIME: util.typecast_timestamp,
FIELD_TYPE.DATE: util.typecast_date,
FIELD_TYPE.TIME: util.typecast_time,
})
# This should match the numerical portion of the version numbers (we can treat
# versions like 5.0.24 and 5.0.24a as the same). Based on the list of version
# at http://dev.mysql.com/doc/refman/4.1/en/news.html and
# http://dev.mysql.com/doc/refman/5.0/en/news.html .
server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
# This is an extra debug layer over MySQL queries, to display warnings.
# It's only used when DEBUG=True.
class MysqlDebugWrapper:
def __init__(self, cursor):
self.cursor = cursor
def execute(self, sql, params=()):
try:
return self.cursor.execute(sql, params)
except Database.Warning, w:
self.cursor.execute("SHOW WARNINGS")
raise Database.Warning, "%s: %s" % (w, self.cursor.fetchall())
def executemany(self, sql, param_list):
try:
return self.cursor.executemany(sql, param_list)
except Database.Warning, w:
self.cursor.execute("SHOW WARNINGS")
raise Database.Warning, "%s: %s" % (w, self.cursor.fetchall())
def __getattr__(self, attr):
if self.__dict__.has_key(attr):
return self.__dict__[attr]
else:
return getattr(self.cursor, attr)
try:
# Only exists in Python 2.4+
from threading import local
except ImportError:
# Import copy of _thread_local.py from Python 2.4
from django.utils._threading_local import local
class DatabaseWrapper(local):
def __init__(self, **kwargs):
self.connection = None
self.queries = []
self.server_version = None
self.options = kwargs
def _valid_connection(self):
if self.connection is not None:
try:
self.connection.ping()
return True
except DatabaseError:
self.connection.close()
self.connection = None
return False
def cursor(self):
from django.conf import settings
if not self._valid_connection():
kwargs = {
'user': settings.DATABASE_USER,
'db': settings.DATABASE_NAME,
'passwd': settings.DATABASE_PASSWORD,
'conv': django_conversions,
}
if settings.DATABASE_HOST.startswith('/'):
kwargs['unix_socket'] = settings.DATABASE_HOST
else:
kwargs['host'] = settings.DATABASE_HOST
if settings.DATABASE_PORT:
kwargs['port'] = int(settings.DATABASE_PORT)
kwargs.update(self.options)
self.connection = Database.connect(**kwargs)
cursor = self.connection.cursor()
if self.connection.get_server_info() >= '4.1':
cursor.execute("SET NAMES 'utf8'")
else:
cursor = self.connection.cursor()
if settings.DEBUG:
return util.CursorDebugWrapper(MysqlDebugWrapper(cursor), self)
return cursor
def _commit(self):
if self.connection is not None:
self.connection.commit()
def _rollback(self):
if self.connection is not None:
try:
self.connection.rollback()
except Database.NotSupportedError:
pass
def close(self):
if self.connection is not None:
self.connection.close()
self.connection = None
def get_server_version(self):
if not self.server_version:
if not self._valid_connection():
self.cursor()
m = server_version_re.match(self.connection.get_server_info())
if not m:
raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info())
self.server_version = tuple([int(x) for x in m.groups()])
return self.server_version
supports_constraints = True
def quote_name(name):
if name.startswith("`") and name.endswith("`"):
return name # Quoting once is enough.
return "`%s`" % name
dictfetchone = util.dictfetchone
dictfetchmany = util.dictfetchmany
dictfetchall = util.dictfetchall
def get_last_insert_id(cursor, table_name, pk_name):
return cursor.lastrowid
def get_date_extract_sql(lookup_type, table_name):
# lookup_type is 'year', 'month', 'day'
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), table_name)
def get_date_trunc_sql(lookup_type, field_name):
# lookup_type is 'year', 'month', 'day'
fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
try:
i = fields.index(lookup_type) + 1
except ValueError:
sql = field_name
else:
format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
return sql
def get_limit_offset_sql(limit, offset=None):
sql = "LIMIT "
if offset and offset != 0:
sql += "%s," % offset
return sql + str(limit)
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
def get_drop_foreignkey_sql():
return "DROP FOREIGN KEY"
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',
'contains': 'LIKE BINARY %s',
'icontains': 'LIKE %s',
'gt': '> %s',
'gte': '>= %s',
'lt': '< %s',
'lte': '<= %s',
'startswith': 'LIKE BINARY %s',
'endswith': 'LIKE BINARY %s',
'istartswith': 'LIKE %s',
'iendswith': 'LIKE %s',
}

View File

@ -0,0 +1,14 @@
from django.conf import settings
import os
def runshell():
args = ['']
args += ["--user=%s" % settings.DATABASE_USER]
if settings.DATABASE_PASSWORD:
args += ["--password=%s" % settings.DATABASE_PASSWORD]
if settings.DATABASE_HOST:
args += ["--host=%s" % settings.DATABASE_HOST]
if settings.DATABASE_PORT:
args += ["--port=%s" % settings.DATABASE_PORT]
args += [settings.DATABASE_NAME]
os.execvp('mysql', args)

View File

@ -0,0 +1,29 @@
# This dictionary maps Field objects to their associated MySQL column
# types, as strings. Column-type strings can contain format strings; they'll
# be interpolated against the values of Field.__dict__ before being output.
# If a column type is set to None, it won't be included in the output.
DATA_TYPES = {
'AutoField': 'integer AUTO_INCREMENT',
'BooleanField': 'bool',
'CharField': 'varchar(%(maxlength)s)',
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'FileField': 'varchar(100)',
'FilePathField': 'varchar(100)',
'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'ImageField': 'varchar(100)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
'ManyToManyField': None,
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PhoneNumberField': 'varchar(20)',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(maxlength)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'USStateField': 'varchar(2)',
}

View File

@ -0,0 +1,95 @@
from django.db.backends.mysql_old.base import quote_name
from MySQLdb import ProgrammingError, OperationalError
from MySQLdb.constants import FIELD_TYPE
import re
foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
def get_table_list(cursor):
"Returns a list of table names in the current database."
cursor.execute("SHOW TABLES")
return [row[0] for row in cursor.fetchall()]
def get_table_description(cursor, table_name):
"Returns a description of the table, with the DB-API cursor.description interface."
cursor.execute("SELECT * FROM %s LIMIT 1" % quote_name(table_name))
return cursor.description
def _name_to_index(cursor, table_name):
"""
Returns a dictionary of {field_name: field_index} for the given table.
Indexes are 0-based.
"""
return dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name))])
def get_relations(cursor, table_name):
"""
Returns a dictionary of {field_index: (field_index_other_table, other_table)}
representing all relationships to the given table. Indexes are 0-based.
"""
my_field_dict = _name_to_index(cursor, table_name)
constraints = []
relations = {}
try:
# This should work for MySQL 5.0.
cursor.execute("""
SELECT column_name, referenced_table_name, referenced_column_name
FROM information_schema.key_column_usage
WHERE table_name = %s
AND table_schema = DATABASE()
AND referenced_table_name IS NOT NULL
AND referenced_column_name IS NOT NULL""", [table_name])
constraints.extend(cursor.fetchall())
except (ProgrammingError, OperationalError):
# Fall back to "SHOW CREATE TABLE", for previous MySQL versions.
# Go through all constraints and save the equal matches.
cursor.execute("SHOW CREATE TABLE %s" % quote_name(table_name))
for row in cursor.fetchall():
pos = 0
while True:
match = foreign_key_re.search(row[1], pos)
if match == None:
break
pos = match.end()
constraints.append(match.groups())
for my_fieldname, other_table, other_field in constraints:
other_field_index = _name_to_index(cursor, other_table)[other_field]
my_field_index = my_field_dict[my_fieldname]
relations[my_field_index] = (other_field_index, other_table)
return relations
def get_indexes(cursor, table_name):
"""
Returns a dictionary of fieldname -> infodict for the given table,
where each infodict is in the format:
{'primary_key': boolean representing whether it's the primary key,
'unique': boolean representing whether it's a unique index}
"""
cursor.execute("SHOW INDEX FROM %s" % quote_name(table_name))
indexes = {}
for row in cursor.fetchall():
indexes[row[4]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1])}
return indexes
DATA_TYPES_REVERSE = {
FIELD_TYPE.BLOB: 'TextField',
FIELD_TYPE.CHAR: 'CharField',
FIELD_TYPE.DECIMAL: 'FloatField',
FIELD_TYPE.DATE: 'DateField',
FIELD_TYPE.DATETIME: 'DateTimeField',
FIELD_TYPE.DOUBLE: 'FloatField',
FIELD_TYPE.FLOAT: 'FloatField',
FIELD_TYPE.INT24: 'IntegerField',
FIELD_TYPE.LONG: 'IntegerField',
FIELD_TYPE.LONGLONG: 'IntegerField',
FIELD_TYPE.SHORT: 'IntegerField',
FIELD_TYPE.STRING: 'TextField',
FIELD_TYPE.TIMESTAMP: 'DateTimeField',
FIELD_TYPE.TINY: 'IntegerField',
FIELD_TYPE.TINY_BLOB: 'TextField',
FIELD_TYPE.MEDIUM_BLOB: 'TextField',
FIELD_TYPE.LONG_BLOB: 'TextField',
FIELD_TYPE.VAR_STRING: 'CharField',
}

View File

@ -67,7 +67,7 @@ class Field(object):
def __init__(self, verbose_name=None, name=None, primary_key=False,
maxlength=None, unique=False, blank=False, null=False, db_index=False,
core=False, rel=None, default=NOT_PROVIDED, editable=True,
core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True,
prepopulate_from=None, unique_for_date=None, unique_for_month=None,
unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
help_text='', db_column=None):
@ -78,6 +78,7 @@ class Field(object):
self.blank, self.null = blank, null
self.core, self.rel, self.default = core, rel, default
self.editable = editable
self.serialize = serialize
self.validator_list = validator_list or []
self.prepopulate_from = prepopulate_from
self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month

View File

@ -94,6 +94,7 @@ class GenericRelation(RelatedField, Field):
kwargs['blank'] = True
kwargs['editable'] = False
kwargs['serialize'] = False
Field.__init__(self, **kwargs)
def get_manipulator_field_objs(self):

View File

@ -84,6 +84,7 @@ class Options(object):
self.fields.insert(bisect(self.fields, field), field)
if not self.pk and field.primary_key:
self.pk = field
field.serialize = False
def __repr__(self):
return '<Options for %s>' % self.object_name

View File

@ -109,6 +109,8 @@ class QuerySet(object):
def __getitem__(self, k):
"Retrieve an item or slice from the set of results."
if not isinstance(k, (slice, int)):
raise TypeError
assert (not isinstance(k, slice) and (k >= 0)) \
or (isinstance(k, slice) and (k.start is None or k.start >= 0) and (k.stop is None or k.stop >= 0)), \
"Negative indexing is not supported."
@ -780,7 +782,7 @@ def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen,
def parse_lookup(kwarg_items, opts):
# Helper function that handles converting API kwargs
# (e.g. "name__exact": "tom") to SQL.
# Returns a tuple of (tables, joins, where, params).
# Returns a tuple of (joins, where, params).
# 'joins' is a sorted dictionary describing the tables that must be joined
# to complete the query. The dictionary is sorted because creation order

View File

@ -19,7 +19,7 @@ def get_object_or_404(klass, *args, **kwargs):
try:
return manager.get(*args, **kwargs)
except klass.DoesNotExist:
raise Http404
raise Http404('No %s matches the given query.' % klass._meta.object_name)
def get_list_or_404(klass, *args, **kwargs):
if isinstance(klass, Manager):
@ -28,5 +28,5 @@ def get_list_or_404(klass, *args, **kwargs):
manager = klass._default_manager
obj_list = list(manager.filter(*args, **kwargs))
if not obj_list:
raise Http404
raise Http404('No %s matches the given query.' % manager.model._meta.object_name)
return obj_list

View File

@ -582,7 +582,7 @@ ifequal = register.tag(ifequal)
#@register.tag
def ifnotequal(parser, token):
"""Output the contents of the block if the two arguments are not equal. See ifequal"""
"""Output the contents of the block if the two arguments are not equal. See ifequal."""
return do_ifequal(parser, token, True)
ifnotequal = register.tag(ifnotequal)
@ -901,7 +901,7 @@ def url(parser, token):
"""
Returns an absolute URL matching given view with its parameters.
This is a way to define links that aren't tied to a particular url configuration::
This is a way to define links that aren't tied to a particular URL configuration::
{% url path.to.some_view arg1,arg2,name1=value1 %}
@ -912,11 +912,11 @@ def url(parser, token):
URL. All arguments for the URL should be present.
For example if you have a view ``app_name.client`` taking client's id and
the corresponding line in a urlconf looks like this::
the corresponding line in a URLconf looks like this::
('^client/(\d+)/$', 'app_name.client')
and this app's urlconf is included into the project's urlconf under some
and this app's URLconf is included into the project's URLconf under some
path::
('^clients/', include('project_name.app_name.urls'))

View File

@ -69,6 +69,14 @@ def encode_multipart(boundary, data):
'',
value.read()
])
elif hasattr(value, '__iter__'):
for item in value:
lines.extend([
'--' + boundary,
'Content-Disposition: form-data; name="%s"' % key,
'',
str(item)
])
else:
lines.extend([
'--' + boundary,

View File

@ -94,7 +94,7 @@ class SortedDict(dict):
def copy(self):
"Returns a copy of this object."
# This way of initialising the copy means it works for subclasses, too.
# This way of initializing the copy means it works for subclasses, too.
obj = self.__class__(self)
obj.keyOrder = self.keyOrder
return obj

View File

@ -17,7 +17,7 @@ def wrap(text, width):
pos = len(word) - word.rfind('\n') - 1
for word in it:
if "\n" in word:
lines = word.splitlines()
lines = word.split('\n')
else:
lines = (word,)
pos += len(lines[0]) + 1

View File

@ -1,6 +1,6 @@
=====================
The "contrib" add-ons
=====================
============================
The "django.contrib" add-ons
============================
Django aims to follow Python's `"batteries included" philosophy`_. It ships
with a variety of extra, optional tools that solve common Web-development
@ -51,8 +51,6 @@ See the `csrf documentation`_.
formtools
=========
**New in Django development version**
A set of high-level abstractions for Django forms (django.newforms).
django.contrib.formtools.preview
@ -142,8 +140,6 @@ See the `flatpages documentation`_.
localflavor
===========
**New in Django development version**
A collection of various Django snippets that are useful only for a particular
country or culture. For example, ``django.contrib.localflavor.usa.forms``
contains a ``USZipCodeField`` that you can use to validate U.S. zip codes.
@ -153,12 +149,16 @@ markup
A collection of template filters that implement these common markup languages:
* Textile
* Markdown
* ReST (ReStructured Text)
* `Textile`_
* `Markdown`_
* `ReST (ReStructured Text)`_
For documentation, read the source code in django/contrib/markup/templatetags/markup.py.
.. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29
.. _Markdown: http://en.wikipedia.org/wiki/Markdown
.. _ReST (ReStructured Text): http://en.wikipedia.org/wiki/ReStructuredText
redirects
=========

View File

@ -303,11 +303,11 @@ Please follow these coding standards when writing code for inclusion in Django:
def my_view(req, foo):
# ...
* Our policy is to keep the names of developers and contributors
in the ``AUTHORS`` file distributed with Django, so please don't include
your name in the actual code. Feel free to include a change to the
``AUTHORS`` file in your patch if you make more than a single trivial
change.
* Please don't put your name in the code you contribute. Our policy is to
keep contributors' names in the ``AUTHORS`` file distributed with Django
-- not scattered throughout the codebase itself. Feel free to include a
change to the ``AUTHORS`` file in your patch if you make more than a
single trivial change.
Committing code
===============
@ -527,12 +527,12 @@ sure all other lines are commented::
# http://code.djangoproject.com/svn/django/trunk/
#
/path/to/trunk
# <branch> is a svn checkout of:
# http://code.djangoproject.com/svn/django/branches/<branch>/
#
#/path/to/<branch>
# On windows a path may look like this:
# C:/path/to/<branch>

View File

@ -1,56 +1,59 @@
===============================
Notes About Supported Databases
Notes about supported databases
===============================
Django attempts to support as many features as possible on all databases.
However, since not all database servers are identical, there is obviously
going to be some variations. This file describes some of the
features that might relevant to Django usage. It is not intended as a
replacement for server-specific documentation or reference manuals.
Django attempts to support as many features as possible on all database
backends. However, not all database backends are alike, and we've had to make
design decisions on which features to support and which assumptions we can make
safely.
MySQL Notes
This file describes some of the features that might be relevant to Django
usage. Of course, it is not intended as a replacement for server-specific
documentation or reference manuals.
MySQL notes
===========
Django expects the database to support transactions, referential integrity,
and Unicode support (UTF-8 encoding). Fortunately MySQL_ has all these
and Unicode support (UTF-8 encoding). Fortunately, MySQL_ has all these
features as available as far back as 3.23. While it may be possible to use
3.23 or 4.0, you will probably have less trouble if you use 4.1 or 5.0.
3.23 or 4.0, you'll probably have less trouble if you use 4.1 or 5.0.
MySQL-4.1
MySQL 4.1
---------
MySQL-4.1_ has greatly improved support for character sets. It is possible to
`MySQL 4.1`_ has greatly improved support for character sets. It is possible to
set different default character sets on the database, table, and column.
Previous versions have only a server-wide character set setting. It's also the
first version where the character set can be changed on the fly. 4.1 also has
support for views, but these are not currently used by Django.
support for views, but Django currently doesn't use views.
MySQL-5.0
MySQL 5.0
---------
MySQL-5.0_ adds the ``information_schema`` database, which contains detailed
data on all database schema. This is used for Django's ``inspectdb`` feature,
when it is available. 5.0 also has support for stored procedures, but these
are not currently used by Django.
`MySQL 5.0`_ adds the ``information_schema`` database, which contains detailed
data on all database schema. Django's ``inspectdb`` feature uses this
``information_schema`` if it's available. 5.0 also has support for stored
procedures, but Django currently doesn't use stored procedures.
.. _MySQL: http://www.mysql.com/
.. _MySQL-4.1: http://dev.mysql.com/doc/refman/4.1/en/index.html
.. _MySQL-5.0: http://dev.mysql.com/doc/refman/5.0/en/index.html
.. _MySQL 4.1: http://dev.mysql.com/doc/refman/4.1/en/index.html
.. _MySQL 5.0: http://dev.mysql.com/doc/refman/5.0/en/index.html
Storage Engines
Storage engines
---------------
MySQL has several `storage engines`_ (previously called table types). You can
change the default storage engine in the server configuration.
The default one is MyISAM_. The main drawback of MyISAM is that it does not
currently have support for transactions or foreign keys. On the plus side, it
is currently the only engine that supports full-text indexing and searching.
The default engine is MyISAM_. The main drawback of MyISAM is that it doesn't
currently support transactions or foreign keys. On the plus side, it's
currently the only engine that supports full-text indexing and searching.
The InnoDB_ engine is fully transactional and supports foreign key references.
The BDB_ engine, like InnoDB, is also fully transactional and supports foreign
key references. However, it's use seems to be somewhat deprecated.
key references. However, its use seems to be deprecated.
`Other storage engines`_, including SolidDB_ and Falcon_, are on the horizon.
For now, InnoDB is probably your best choice.
@ -66,25 +69,25 @@ For now, InnoDB is probably your best choice.
MySQLdb
-------
`MySQLdb`_ is the Python interface to MySQL. 1.2.1 is the first version which
has support for MySQL-4.1 and newer. If you are trying to use an older version
of MySQL, then 1.2.0 *may* work for you.
`MySQLdb`_ is the Python interface to MySQL. 1.2.1 is the first version that
has support for MySQL 4.1 and newer. If you are trying to use an older version
of MySQL, then 1.2.0 *might* work for you.
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
Creating your database
~~~~~~~~~~~~~~~~~~~~~~
----------------------
You can `create your database`_ using the command-line tools and this SQL::
CREATE DATABASE <dbname> CHARACTER SET utf8;
This ensures all tables and columns will use utf8 by default.
This ensures all tables and columns will use UTF-8 by default.
.. _create your database: http://dev.mysql.com/doc/refman/5.0/en/create-database.html
Connecting to the database
~~~~~~~~~~~~~~~~~~~~~~~~~~
--------------------------
Refer to the `settings documentation`_.
@ -106,7 +109,7 @@ Here's a sample configuration which uses a MySQL option file::
DATABASE_OPTIONS = {
'read_default_file': '/path/to/my.cnf',
}
# my.cnf
[client]
database = DATABASE_NAME
@ -114,49 +117,46 @@ Here's a sample configuration which uses a MySQL option file::
passwd = DATABASE_PASSWORD
default-character-set = utf8
There are several other MySQLdb connection options which may be useful, such
as ``ssl``, ``use_unicode``, ``init_command``, and ``sql_mode``; consult the
Several other MySQLdb connection options may be useful, such as ``ssl``,
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
`MySQLdb documentation`_ for more details.
.. _settings documentation: http://www.djangoproject.com/documentation/settings/#database-engine
.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/
Creating your tables
~~~~~~~~~~~~~~~~~~~~
--------------------
When Django generates the schema, it doesn't specify a storage engine, so they
will be created with whatever default `storage engine`__ your database server
is configured for. The easiest solution is to set your database server's default
storage engine to the desired engine.
When Django generates the schema, it doesn't specify a storage engine, so
tables will be created with whatever default storage engine your database
server is configured for. The easiest solution is to set your database server's
default storage engine to the desired engine.
__ `storage engines`_
If you are using a hosting service and can't change your server's default
If you're using a hosting service and can't change your server's default
storage engine, you have a couple of options.
After the tables is created, all that is needed to convert it to a new storage
engine (such as InnoDB) is::
ALTER TABLE <tablename> ENGINE=INNODB;
* After the tables are created, execute an ``ALTER TABLE`` statement to
convert a table to a new storage engine (such as InnoDB)::
With a lot of tables, this can be tedious.
ALTER TABLE <tablename> ENGINE=INNODB;
Another option is to use the ``init_command`` option for MySQLdb prior to
creating your tables::
This can be tedious if you have a lot of tables.
DATABASE_OPTIONS = {
...
"init_command": "SET storage_engine=INNODB",
...
}
* Another option is to use the ``init_command`` option for MySQLdb prior to
creating your tables::
This sets the default storage engine upon connecting to the database. After
your tables are set up and running in production, you should remove this
option.
DATABASE_OPTIONS = {
# ...
"init_command": "SET storage_engine=INNODB",
# ...
}
Another method for changing the storage engine is described in
AlterModelOnSyncDB_.
This sets the default storage engine upon connecting to the database.
After your tables have been created, you should remove this option.
* Another method for changing the storage engine is described in
AlterModelOnSyncDB_.
.. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB

View File

@ -57,7 +57,7 @@ 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``.
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

View File

@ -100,8 +100,6 @@ 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).
@ -117,8 +115,6 @@ 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``
@ -165,18 +161,9 @@ needed.
``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection
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
@ -216,7 +203,7 @@ 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::
directories will be included in the search path. For example::
django-admin.py loaddata foo/bar/mydata.json
@ -350,8 +337,6 @@ Prints the DROP TABLE SQL statements for the given appnames.
sqlcustom [appname appname ...]
-------------------------------
**New in Django development version**
Prints the custom SQL statements for the given appnames.
For each model in each specified app, this command looks for the file
@ -373,13 +358,6 @@ 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 ...]
--------------------------------------
@ -426,8 +404,6 @@ fixture data files.
test
----
**New in Django development version**
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
.. _testing django applications: ../testing/
@ -475,8 +451,6 @@ setting the Python path for you.
--format
--------
**New in Django development version**
Example usage::
django-admin.py dumpdata --format=xml
@ -493,8 +467,6 @@ options.
--indent
--------
**New in Django development version**
Example usage::
django-admin.py dumpdata --indent=4
@ -506,8 +478,6 @@ Pretty-printing will only be enabled if the indent option is provided.
--noinput
---------
**New in Django development version**
Inform django-admin that the user should NOT be prompted for any input. Useful
if the django-admin script will be executed as an unattended, automated
script.
@ -530,8 +500,6 @@ Example output::
--verbosity
-----------
**New in Django development version**
Example usage::
django-admin.py syncdb --verbosity=2
@ -543,8 +511,6 @@ and `2` is verbose output.
--adminmedia
------------
**New in Django development version**
Example usage::
django-admin.py manage.py --adminmedia=/tmp/new-admin-style/

View File

@ -97,8 +97,7 @@ which is a dictionary of the parameters captured in the URL.
* ``extra_context``: A dictionary of values to add to the template
context. By default, this is an empty dictionary. If a value in the
dictionary is callable, the generic view will call it
just before rendering the template. (**This is new in the
Django development version.**)
just before rendering the template.
**Example:**
@ -752,10 +751,10 @@ 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_on_page`: 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_on_page`: The number of the
first result on the current page. This is 1-based.
* ``pages``: The total number of pages, as an integer.

View File

@ -284,13 +284,13 @@ obtain) the language translations themselves. Here's how that works.
.. admonition:: Locale restrictions
Django does not support localising your application into a locale for
which Django itself has not been translated -- it will ignore your
translation files. If you were to try this and Django supported it, you
would inevitably see a mixture of translated strings (from your
application) and English strings (from Django itself). If you are wanting
to support a locale for your application that is not already part of
Django, you will need to make at least a minimal translation of the Django
Django does not support localizing your application into a locale for
which Django itself has not been translated. In this case, it will ignore
your translation files. If you were to try this and Django supported it,
you would inevitably see a mixture of translated strings (from your
application) and English strings (from Django itself). If you want to
support a locale for your application that is not already part of
Django, you'll need to make at least a minimal translation of the Django
core.
Message files

View File

@ -86,25 +86,17 @@ Installing the official version
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`_.
2. Download the latest release from our `download page`_.
3. ``tar xzvf Django-0.95.tar.gz``
3. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``).
4. ``cd Django-0.95``
4. Change into the downloaded directory (e.g. ``cd Django-NNN``).
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
connection and may cause problems on Python 2.5. If you run into problems,
try using our development version by following the instructions below. The
development version no longer uses setuptools nor requires an Internet
connection.
5. Run ``sudo python setup.py install``.
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

View File

@ -104,8 +104,6 @@ Also removes the content from any response to a HEAD request and sets the
django.middleware.http.SetRemoteAddrFromForwardedFor
----------------------------------------------------
**New in Django development version**
Sets ``request.META['REMOTE_ADDR']`` based on
``request.META['HTTP_X_FORWARDED_FOR']``, if the latter is set. This is useful
if you're sitting behind a reverse proxy that causes each request's

View File

@ -362,9 +362,8 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
containing only letters, numbers, underscores or hyphens. They're generally
used in URLs.
In the Django development version, you can specify ``maxlength``. If
``maxlength`` is not specified, Django will use a default length of 50. In
previous Django versions, there's no way to override the length of 50.
Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
not specified, Django will use a default length of 50.
Implies ``db_index=True``.
@ -1216,8 +1215,9 @@ screen via ``<script src="">`` tags. This can be used to tweak a given type of
admin page in JavaScript or to provide "quick links" to fill in default values
for certain fields.
If relative URLs are used, Django admin will automatically prepend these links
with ``settings.ADMIN_MEDIA_PREFIX``.
If you use relative URLs -- URLs that don't start with ``http://`` or ``/`` --
then the admin site will automatically prefix these links with
``settings.ADMIN_MEDIA_PREFIX``.
``list_display``
----------------
@ -1456,8 +1456,8 @@ user searches for ``john lennon``, Django will do the equivalent of this SQL
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
**New in Django development version:** For faster and/or more restrictive
searches, prefix the field name with an operator:
For faster and/or more restrictive searches, prefix the field name
with an operator:
``^``
Matches the beginning of the field. For example, if ``search_fields`` is
@ -1753,8 +1753,6 @@ But this template code is good::
The ``permalink`` decorator
~~~~~~~~~~~~~~~~~~~~~~~~~~~
**New in Django development version.**
The problem with the way we wrote ``get_absolute_url()`` above is that it
slightly violates the DRY principle: the URL for this object is defined both
in the URLConf file and in the model.

View File

@ -9,9 +9,10 @@ framework. This document explains how to use this new library.
Migration plan
==============
``django.newforms`` currently is only available in the Django development version
-- i.e., it's not available in the Django 0.95 release. For the next Django
release, our plan is to do the following:
``django.newforms`` currently is only available in Django beginning
with the 0.96 release. the Django development version -- i.e., it's
not available in the Django 0.95 release. For the next Django release,
our plan is to do the following:
* As of revision [4208], we've copied the current ``django.forms`` to
``django.oldforms``. This allows you to upgrade your code *now* rather

264
docs/release_notes_0.96.txt Normal file
View File

@ -0,0 +1,264 @@
=================================
Django version 0.96 release notes
=================================
Welcome to Django 0.96!
The primary goal for 0.96 is a cleanup and stabilization of the features
introduced in 0.95. There have been a few small `backwards-incompatible
changes`_ since 0.95, but the upgrade process should be fairly simple
and should not require major changes to existing applications.
However, we're also releasing 0.96 now because we have a set of
backwards-incompatible changes scheduled for the near future. Once
completed, they will involve some code changes for application
developers, so we recommend that you stick with Django 0.96 until the
next official release; then you'll be able to upgrade in one step
instead of needing to make incremental changes to keep up with the
development version of Django.
Backwards-incompatible changes
==============================
The following changes may require you to update your code when you switch from
0.95 to 0.96:
``MySQLdb`` version requirement
-------------------------------
Due to a bug in older versions of the ``MySQLdb`` Python module (which
Django uses to connect to MySQL databases), Django's MySQL backend now
requires version 1.2.1p2 or higher of `MySQLdb`, and will raise
exceptions if you attempt to use an older version.
If you're currently unable to upgrade your copy of ``MySQLdb`` to meet
this requirement, a separate, backwards-compatible backend, called
"mysql_old", has been added to Django. To use this backend, change
the ``DATABASE_ENGINE`` setting in your Django settings file from
this::
DATABASE_ENGINE = "mysql"
to this::
DATABASE_ENGINE = "mysql_old"
However, we strongly encourage MySQL users to upgrade to a more recent
version of `MySQLdb` as soon as possible, The "mysql_old" backend is
provided only to ease this transition, and is considered deprecated;
aside from any necessary security fixes, it will not be actively
maintained, and it will be removed in a future release of Django.
Also, note that some features, like the new ``DATABASE_OPTIONS``
setting (see the `databases documentation`_ for details), are only
available on the "mysql" backend, and will not be made available for
"mysql_old".
.. _databases documentation: ../databases/
Database constraint names changed
---------------------------------
The format of the constraint names Django generates for foreign key
references have changed slightly. These names are generally only used
when it is not possible to put the reference directly on the affected
column, so they is not always visible.
The effect of this change is that running ``manage.py reset`` and
similar commands against an existing database may generate SQL with
the new form of constraint name, while the database itself contains
constraints named in the old form; this will cause the database server
to raise an error message about modifying non-existent constraints.
If you need to work around this, there are two methods available:
1. Redirect the output of ``manage.py`` to a file, and edit the
generated SQL to use the correct constraint names before
executing it.
2. Examine the output of ``manage.py sqlall`` to see the new-style
constraint names, and use that as a guide to rename existing
constraints in your database.
Name changes in ``manage.py``
-----------------------------
A few of the options to ``manage.py`` have changed with the addition of fixture
support:
* There are new ``dumpdata`` and ``loaddata`` commands which, as
you might expect, will dump and load data to/from the
database. These commands can operate against any of Django's
supported serialization formats.
* The ``sqlinitialdata`` command has been renamed to ``sqlcustom`` to
emphasize that ``loaddata`` should be used for data (and ``sqlcustom`` for
other custom SQL -- views, stored procedures, etc.).
* The vestigial ``install`` command has been removed. Use ``syncdb``.
Backslash escaping changed
--------------------------
The Django database API now escapes backslashes given as query parameters. If
you have any database API code that matches backslashes, and it was working before
(despite the lack of escaping), you'll have to change your code to "unescape" the
slashes one level.
For example, this used to work::
# Find text containing a single backslash
MyModel.objects.filter(text__contains='\\\\')
The above is now incorrect, and should be rewritten as::
# Find text containing a single backslash
MyModel.objects.filter(text__contains='\\')
Removed ENABLE_PSYCO setting
----------------------------
The ``ENABLE_PSYCO`` setting no longer exists. If your settings file includes
``ENABLE_PSYCO`` it will have no effect; to use Psyco_, we recommend
writing a middleware class to activate it.
.. _psyco: http://psyco.sourceforge.net/
What's new in 0.96?
===================
This revision represents over a thousand source commits and over four hundred
bug fixes, so we can't possibly catalog all the changes. Here, we describe the
most notable changes in this release.
New forms library
-----------------
``django.newforms`` is Django's new form-handling library. It's a
replacement for ``django.forms``, the old form/manipulator/validation
framework. Both APIs are available in 0.96, but over the next two
releases we plan to switch completely to the new forms system, and
deprecate and remove the old system.
There are three elements to this transition:
* We've copied the current ``django.forms`` to
``django.oldforms``. This allows you to upgrade your code *now*
rather than waiting for the backwards-incompatible change and
rushing to fix your code after the fact. Just change your
import statements like this::
from django import forms # 0.95-style
from django import oldforms as forms # 0.96-style
* The next official release of Django will move the current
``django.newforms`` to ``django.forms``. This will be a
backwards-incompatible change, and anyone still using the old
version of ``django.forms`` at that time will need to change
their import statements as described above.
* The next release after that will completely remove
``django.oldforms``.
Although the ``newforms`` library will continue to evolve, it's ready for use
for most common cases. We recommend that anyone new to form handling skip the
old forms system and start with the new.
For more information about ``django.newforms``, read the `newforms
documentation`_.
.. _newforms documentation: ../newforms/
URLconf improvements
--------------------
You can now use any callable as the callback in URLconfs (previously, only
strings that referred to callables were allowed). This allows a much more
natural use of URLconfs. For example, this URLconf::
from django.conf.urls.defaults import *
urlpatterns = patterns('',
('^myview/$', 'mysite.myapp.views.myview')
)
can now be rewritten as::
from django.conf.urls.defaults import *
from mysite.myapp.views import myview
urlpatterns = patterns('',
('^myview/$', myview)
)
One useful application of this can be seen when using decorators; this
change allows you to apply decorators to views *in your
URLconf*. Thus, you can make a generic view require login very
easily::
from django.conf.urls.defaults import *
from django.contrib.auth.decorators import login_required
from django.views.generic.list_detail import object_list
from mysite.myapp.models import MyModel
info = {
"queryset" : MyModel.objects.all(),
}
urlpatterns = patterns('',
('^myview/$', login_required(object_list), info)
)
Note that both syntaxes (strings and callables) are valid, and will continue to
be valid for the foreseeable future.
The test framework
------------------
Django now includes a test framework so you can start transmuting fear into
boredom (with apologies to Kent Beck). You can write tests based on doctest_
or unittest_ and test your views with a simple test client.
There is also new support for "fixtures" -- initial data, stored in any of the
supported `serialization formats`_, that will be loaded into your database at the
start of your tests. This makes testing with real data much easier.
See `the testing documentation`_ for the full details.
.. _doctest: http://docs.python.org/lib/module-doctest.html
.. _unittest: http://docs.python.org/lib/module-unittest.html
.. _the testing documentation: ../testing/
.. _serialization formats: ../serialization/
Improvements to the admin interface
-----------------------------------
A small change, but a very nice one: dedicated views for adding and
updating users have been added to the admin interface, so you no
longer need to worry about working with hashed passwords in the admin.
Thanks
======
Since 0.95, a number of people have stepped forward and taken a major
new role in Django's development. We'd like to thank these people for
all their hard work:
* Russell Keith-Magee and Malcolm Tredinnick for their major code
contributions. This release wouldn't have been possible without them.
* Our new release manager, James Bennett, for his work in getting out
0.95.1, 0.96, and (hopefully) future release.
* Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill,
Michael Radziej, and Gary Wilson. They agreed to take on the monumental
task of wrangling our tickets into nicely cataloged submission. Figuring
out what to work on is now about a million times easier; thanks again,
guys.
* Everyone who submitted a bug report, patch or ticket comment. We can't
possibly thank everyone by name -- over 200 developers submitted patches
that went into 0.96 -- but everyone who's contributed to Django is listed
in AUTHORS_.
.. _AUTHORS: http://code.djangoproject.com/browser/django/trunk/AUTHORS

View File

@ -384,7 +384,6 @@ Methods
Deletes the cookie with the given key. Fails silently if the key doesn't
exist.
The ``path`` and ``domain`` arguments are new in the Django development version.
Due to the way cookies work, ``path`` and ``domain`` should be the same
values you used in ``set_cookie()`` -- otherwise the cookie may not be deleted.

View File

@ -31,7 +31,8 @@ but it'll almost always be a QuerySet).
You can also use a serializer object directly::
xml_serializer = serializers.get_serializer("xml")
XMLSerializer = serializers.get_serializer("xml")
xml_serializer = XMLSerializer()
xml_serializer.serialize(queryset)
data = xml_serializer.getvalue()

View File

@ -265,8 +265,6 @@ The name of the cookie to use for sessions. This can be whatever you want.
SESSION_COOKIE_SECURE
---------------------
**New in Django development version**
Default: ``False``
Whether to use a secure cookie for the session cookie. If this is set to

View File

@ -245,7 +245,8 @@ DATABASE_ENGINE
Default: ``''`` (Empty string)
Which database backend to use. Either ``'postgresql_psycopg2'``,
``'postgresql'``, ``'mysql'``, ``'sqlite3'`` or ``'ado_mssql'``.
``'postgresql'``, ``'mysql'``, ``'mysql_old'``, ``'sqlite3'`` or
``'ado_mssql'``.
DATABASE_HOST
-------------
@ -428,8 +429,6 @@ 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
@ -715,8 +714,6 @@ See the `session docs`_.
SESSION_COOKIE_SECURE
---------------------
**New in Django development version**
Default: ``False``
Whether to use a secure cookie for the session cookie. If this is set to
@ -811,8 +808,6 @@ misspelled) variables. See `How invalid variables are handled`_.
TEST_RUNNER
-----------
**New in Django development version**
Default: ``'django.test.simple.run_tests'``
The name of the method to use for starting the test suite. See
@ -823,8 +818,6 @@ The name of the method to use for starting the test suite. See
TEST_DATABASE_NAME
------------------
**New in Django development version**
Default: ``None``
The name of database to use when running the test suite. If a value of

View File

@ -112,8 +112,6 @@ know how to write Python code.
Comments
========
**New in Django development version**
To comment-out part of a template, use the comment syntax: ``{# #}``.
For example, this template would render as ``'hello'``::
@ -253,8 +251,8 @@ Here are some tips for working with inheritance:
if you want to add to the contents of a parent block instead of
completely overriding it.
* **New in Django development version:** For extra readability, you can
optionally give a *name* to your ``{% endblock %}`` tag. For example::
* For extra readability, you can optionally give a *name* to your
``{% endblock %}`` tag. For example::
{% block content %}
...
@ -548,9 +546,9 @@ The 'ifchanged' block tag is used within a loop. It has two possible uses.
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
{% endfor %}
2. **New in Django development version.** If given a variable, check whether that
variable has changed. For example, the following shows the date every time it
changes, but only shows the hour if both the hour and the date has changed::
2. If given a variable, check whether that variable has changed. For
example, the following shows the date every time it changes, but
only shows the hour if both the hour and the date has changed::
{% for date in days %}
{% ifchanged date.date %} {{ date.date }} {% endifchanged %}
@ -828,13 +826,9 @@ The argument tells which template bit to output:
``closecomment`` ``#}``
================== =======
Note: ``opencomment`` and ``closecomment`` are new in the Django development version.
url
~~~
**New in Django development version**
**Note that the syntax for this tag may change in the future, as we make it more robust.**
Returns an absolute URL (i.e., a URL without the domain name) matching a given
@ -976,8 +970,6 @@ place -- but only if there's a decimal part to be displayed. For example:
* ``36.15`` gets converted to ``36.2``
* ``36`` gets converted to ``36``
**New in Django development version**
If used with a numeric integer argument, ``floatformat`` rounds a number to that
many decimal places. For example:

View File

@ -2,8 +2,6 @@
Testing Django applications
===========================
**New in Django development version**.
Automated testing is an extremely useful weapon in the bug-killing arsenal
of the modern developer. When initially writing code, a test suite can be
used to validate that code behaves as expected. When refactoring or
@ -227,6 +225,12 @@ can be invoked on the ``Client`` instance.
The key-value pairs in the data dictionary will be encoded as a multipart
message and used to create the POST data payload.
To submit multiple values for a given key (for example, to specify
the selections for a multiple selection list), provide the values as a
list or tuple for the required key. For example, a data dictionary of
``{'choices': ('a','b','d')}`` would submit three selected rows for the
field named ``choices``.
Submitting files is a special case. To POST a file, you need only
provide the file field name as a key, and a file handle to the file you wish to
upload as a value. The Test Client will populate the two POST fields (i.e.,

View File

@ -400,8 +400,6 @@ to pass metadata and options to views.
Passing extra options to ``include()``
--------------------------------------
**New in Django development version.**
Similarly, you can pass extra options to ``include()``. When you pass extra
options to ``include()``, *each* line in the included URLconf will be passed
the extra options.
@ -442,8 +440,6 @@ every view in the the included URLconf accepts the extra options you're passing.
Passing callable objects instead of strings
===========================================
**New in Django development version.**
Some developers find it more natural to pass the actual Python function object
rather than a string containing the path to its module. This alternative is
supported -- you can pass any callable object as the view.

View File

@ -1,5 +1,5 @@
"""
Empty model tests
39. Empty model tests
These test that things behave sensibly for the rare corner-case of a model with
no fields.

View File

@ -1,5 +1,5 @@
"""
31. Callable defaults
32. Callable defaults
You can pass callable objects as the ``default`` parameter to a field. When
the object is created without an explicit value passed in, Django will call

View File

@ -1,5 +1,5 @@
"""
39. Fixtures.
37. 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

View File

@ -1,5 +1,5 @@
"""
33. Generic relations
34. Generic relations
Generic relations let an object have a foreign key to any object through a
content-type/object-id field. A generic foreign key can point to any object,

View File

@ -1,5 +1,5 @@
"""
34. DB-API Shortcuts
35. DB-API Shortcuts
get_object_or_404 is a shortcut function to be used in view functions for
performing a get() lookup and raising a Http404 exception if a DoesNotExist
@ -44,7 +44,7 @@ __test__ = {'API_TESTS':"""
>>> get_object_or_404(Article, title="Foo")
Traceback (most recent call last):
...
Http404
Http404: No Article matches the given query.
# Create an Article.
>>> article = Article.objects.create(title="Run away!")
@ -63,7 +63,7 @@ Http404
>>> get_object_or_404(a.article_set, title__contains="Camelot")
Traceback (most recent call last):
...
Http404
Http404: No Article matches the given query.
# Custom managers can be used too.
>>> get_object_or_404(Article.by_a_sir, title="Run away!")
@ -77,7 +77,7 @@ Http404
>>> get_list_or_404(a.article_set, title__icontains='Shrubbery')
Traceback (most recent call last):
...
Http404
Http404: No Article matches the given query.
# Custom managers can be used too.
>>> get_list_or_404(Article.by_a_sir, title__icontains="Run")

View File

@ -1,5 +1,5 @@
"""
32. get_or_create()
33. get_or_create()
get_or_create() does what it says: it tries to look up an object with the given
parameters. If an object isn't found, it creates one with the given parameters.

View File

@ -1,5 +1,5 @@
"""
28. Many-to-many and many-to-one relationships to the same table
29. Many-to-many and many-to-one relationships to the same table
Make sure to set ``related_name`` if you use relationships to the same table.
"""

View File

@ -1,5 +1,5 @@
"""
27. Many-to-many relationships between the same two tables
28. Many-to-many relationships between the same two tables
In this example, A Person can have many friends, who are also people. Friendship is a
symmetrical relationship - if I am your friend, you are my friend.

View File

@ -1,5 +1,5 @@
"""
26. Default manipulators
27. Default manipulators
Each model gets an AddManipulator and ChangeManipulator by default.
"""

View File

@ -1,5 +1,5 @@
"""
34. Generating HTML forms from models
36. Generating HTML forms from models
Django provides shortcuts for creating Form objects from a model class and a
model instance.

View File

@ -1,5 +1,5 @@
"""
29. Object pagination
30. Object pagination
Django provides a framework for paginating a list of objects in a few lines
of code. This is often useful for dividing search results or long lists of

View File

@ -1,5 +1,5 @@
"""
XXX. Tests for ``select_related()``
40. 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

View File

@ -1,5 +1,5 @@
"""
XXX. Serialization
41. Serialization
``django.core.serializers`` provides interfaces to converting Django querysets
to and from "flat" data (i.e. strings).

View File

@ -1,5 +1,5 @@
"""
39. Testing using the Test Client
38. Testing using the Test Client
The test client is a class that can act like a simple
browser for testing purposes.
@ -81,7 +81,43 @@ class ClientTest(TestCase):
# Check that the response was a 302 (redirect)
self.assertEqual(response.status_code, 302)
def test_valid_form(self):
"POST valid data to a form"
post_data = {
'text': 'Hello World',
'email': 'foo@example.com',
'value': 37,
'single': 'b',
'multi': ('b','c','e')
}
response = self.client.post('/test_client/form_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template.name, "Valid POST Template")
def test_incomplete_data_form(self):
"POST incomplete data to a form"
post_data = {
'text': 'Hello World',
'value': 37
}
response = self.client.post('/test_client/form_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template.name, "Invalid POST Template")
def test_form_error(self):
"POST erroneous data to a form"
post_data = {
'text': 'Hello World',
'email': 'not an email address',
'value': 37,
'single': 'b',
'multi': ('b','c','e')
}
response = self.client.post('/test_client/form_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template.name, "Invalid POST Template")
def test_unknown_page(self):
"GET an invalid URL"
response = self.client.get('/test_client/unknown_view/')

View File

@ -6,6 +6,7 @@ urlpatterns = patterns('',
(r'^post_view/$', views.post_view),
(r'^raw_post_view/$', views.raw_post_view),
(r'^redirect_view/$', views.redirect_view),
(r'^form_view/$', views.form_view),
(r'^login_protected_view/$', views.login_protected_view),
(r'^session_view/$', views.session_view),
(r'^broken_view/$', views.broken_view)

View File

@ -2,6 +2,8 @@ from xml.dom.minidom import parseString
from django.template import Context, Template
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.newforms.forms import Form
from django.newforms import fields
def get_view(request):
"A simple view that expects a GET request, and returns a rendered template"
@ -45,7 +47,39 @@ def raw_post_view(request):
def redirect_view(request):
"A view that redirects all requests to the GET view"
return HttpResponseRedirect('/test_client/get_view/')
TestChoices = (
('a', 'First Choice'),
('b', 'Second Choice'),
('c', 'Third Choice'),
('d', 'Fourth Choice'),
('e', 'Fifth Choice')
)
class TestForm(Form):
text = fields.CharField()
email = fields.EmailField()
value = fields.IntegerField()
single = fields.ChoiceField(choices=TestChoices)
multi = fields.MultipleChoiceField(choices=TestChoices)
def form_view(request):
"A view that tests a simple form"
if request.method == 'POST':
form = TestForm(request.POST)
if form.is_valid():
t = Template('Valid POST data.', name='Valid POST Template')
c = Context()
else:
t = Template('Invalid POST data. {{ form.errors }}', name='Invalid POST Template')
c = Context({'form': form})
else:
form = TestForm()
t = Template('Viewing base form. {{ form }}.', name='Form GET Template')
c = Context({'form': form})
return HttpResponse(t.render(c))
def login_protected_view(request):
"A simple view that is login protected."
t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template')

View File

@ -1,5 +1,5 @@
"""
30. Validation
31. Validation
This is an experimental feature!

View File

@ -133,6 +133,12 @@ u'\xcb'
>>> wordwrap('this is a long paragraph of text that really needs to be wrapped I\'m afraid', 14)
"this is a long\nparagraph of\ntext that\nreally needs\nto be wrapped\nI'm afraid"
>>> wordwrap('this is a short paragraph of text.\n But this line should be indented',14)
'this is a\nshort\nparagraph of\ntext.\n But this\nline should be\nindented'
>>> wordwrap('this is a short paragraph of text.\n But this line should be indented',15)
'this is a short\nparagraph of\ntext.\n But this line\nshould be\nindented'
>>> ljust('test', 10)
'test '

View File

@ -6,7 +6,8 @@ This class sets up a model for each model field type
"""
from django.db import models
from django.contrib.contenttypes.models import ContentType
# The following classes are for testing basic data
# marshalling, including NULL values.
@ -73,6 +74,22 @@ class USStateData(models.Model):
class XMLData(models.Model):
data = models.XMLField(null=True)
class Tag(models.Model):
"""A tag on an item."""
data = models.SlugField()
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = models.GenericForeignKey()
class Meta:
ordering = ["data"]
class GenericData(models.Model):
data = models.CharField(maxlength=30)
tags = models.GenericRelation(Tag)
# The following test classes are all for validation
# of related objects; in particular, forward, backward,
# and self references.

View File

@ -24,6 +24,14 @@ def data_create(pk, klass, data):
instance.data = data
instance.save()
return instance
def generic_create(pk, klass, data):
instance = klass(id=pk)
instance.data = data[0]
instance.save()
for tag in data[1:]:
instance.tags.create(data=tag)
return instance
def fk_create(pk, klass, data):
instance = klass(id=pk)
@ -56,6 +64,11 @@ def data_compare(testcase, pk, klass, data):
testcase.assertEqual(data, instance.data,
"Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % (pk,data, type(data), instance.data, type(instance.data)))
def generic_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk)
testcase.assertEqual(data[0], instance.data)
testcase.assertEqual(data[1:], [t.data for t in instance.tags.all()])
def fk_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk)
testcase.assertEqual(data, instance.data_id)
@ -76,6 +89,7 @@ def pk_compare(testcase, pk, klass, data):
# actually a pair of functions; one to create
# and one to compare objects of that type
data_obj = (data_create, data_compare)
generic_obj = (generic_create, generic_compare)
fk_obj = (fk_create, fk_compare)
m2m_obj = (m2m_create, m2m_compare)
o2o_obj = (o2o_create, o2o_compare)
@ -140,6 +154,9 @@ The end."""),
(data_obj, 190, XMLData, "<foo></foo>"),
(data_obj, 191, XMLData, None),
(generic_obj, 200, GenericData, ['Generic Object 1', 'tag1', 'tag2']),
(generic_obj, 201, GenericData, ['Generic Object 2', 'tag2', 'tag3']),
(data_obj, 300, Anchor, "Anchor 1"),
(data_obj, 301, Anchor, "Anchor 2"),
@ -222,6 +239,9 @@ def serializerTest(format, self):
transaction.commit()
transaction.leave_transaction_management()
# Add the generic tagged objects to the object list
objects.extend(Tag.objects.all())
# Serialize the test database
serialized_data = serializers.serialize(format, objects, indent=2)