mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
[soc2009/multidb] Merged up to trunk r11810. There are many conflicts in this merge, these will be resolved in a subsequent commit.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11812 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
353e079792
commit
c88113683d
@ -131,9 +131,12 @@ DATABASE_HOST = '' # Set to empty string for localhost. Not used wit
|
||||
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
||||
DATABASE_OPTIONS = {} # Set to empty dictionary for default.
|
||||
|
||||
<<<<<<< HEAD:django/conf/global_settings.py
|
||||
DATABASES = {
|
||||
}
|
||||
|
||||
=======
|
||||
>>>>>>> master:django/conf/global_settings.py
|
||||
# The email backend to use. For possible shortcuts see django.core.mail.
|
||||
# The default is to use the SMTP backend.
|
||||
# Third-party backends can be specified by providing a Python path
|
||||
|
@ -5,7 +5,11 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
"POT-Creation-Date: 2009-10-25 20:56+0100\n"
|
||||
=======
|
||||
"POT-Creation-Date: 2009-12-11 10:11+0100\n"
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
"PO-Revision-Date: 2008-02-25 15:53+0100\n"
|
||||
"Last-Translator: Jarek Zgoda <jarek.zgoda@gmail.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -223,7 +227,11 @@ msgstr "chiński tradycyjny"
|
||||
msgid "Successfully deleted %(count)d %(items)s."
|
||||
msgstr "Usunięto %(count)d %(items)s."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/actions.py:67 contrib/admin/options.py:1027
|
||||
=======
|
||||
#: contrib/admin/actions.py:67 contrib/admin/options.py:1034
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
msgid "Are you sure?"
|
||||
msgstr "Jesteś pewien?"
|
||||
|
||||
@ -310,87 +318,132 @@ msgstr "log"
|
||||
msgid "log entries"
|
||||
msgstr "logi"
|
||||
|
||||
#: contrib/admin/options.py:133 contrib/admin/options.py:147
|
||||
#: contrib/admin/options.py:135 contrib/admin/options.py:149
|
||||
msgid "None"
|
||||
msgstr "brak"
|
||||
|
||||
#: contrib/admin/options.py:519
|
||||
#: contrib/admin/options.py:522
|
||||
#, python-format
|
||||
msgid "Changed %s."
|
||||
msgstr "Zmieniono %s"
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:519 contrib/admin/options.py:529
|
||||
=======
|
||||
#: contrib/admin/options.py:522 contrib/admin/options.py:532
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/comments/templates/comments/preview.html:16 forms/models.py:384
|
||||
#: forms/models.py:596
|
||||
msgid "and"
|
||||
msgstr "i"
|
||||
|
||||
#: contrib/admin/options.py:524
|
||||
#: contrib/admin/options.py:527
|
||||
#, python-format
|
||||
msgid "Added %(name)s \"%(object)s\"."
|
||||
msgstr "Dodano %(name)s \"%(object)s\"."
|
||||
|
||||
#: contrib/admin/options.py:528
|
||||
#: contrib/admin/options.py:531
|
||||
#, python-format
|
||||
msgid "Changed %(list)s for %(name)s \"%(object)s\"."
|
||||
msgstr "Zmieniono %(list)s w %(name)s \"%(object)s\"."
|
||||
|
||||
#: contrib/admin/options.py:533
|
||||
#: contrib/admin/options.py:536
|
||||
#, python-format
|
||||
msgid "Deleted %(name)s \"%(object)s\"."
|
||||
msgstr "Usunięto %(name)s \"%(object)s\"."
|
||||
|
||||
#: contrib/admin/options.py:537
|
||||
#: contrib/admin/options.py:540
|
||||
msgid "No fields changed."
|
||||
msgstr "Żadne pole nie zmienione."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:599 contrib/auth/admin.py:67
|
||||
=======
|
||||
#: contrib/admin/options.py:602 contrib/auth/admin.py:68
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" dodany pomyślnie."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:603 contrib/admin/options.py:636
|
||||
#: contrib/auth/admin.py:75
|
||||
msgid "You may edit it again below."
|
||||
msgstr "Możesz ponownie edytować wpis poniżej."
|
||||
|
||||
#: contrib/admin/options.py:613 contrib/admin/options.py:646
|
||||
=======
|
||||
#: contrib/admin/options.py:606 contrib/admin/options.py:639
|
||||
#: contrib/auth/admin.py:77
|
||||
msgid "You may edit it again below."
|
||||
msgstr "Możesz ponownie edytować wpis poniżej."
|
||||
|
||||
#: contrib/admin/options.py:616 contrib/admin/options.py:649
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "You may add another %s below."
|
||||
msgstr "Możesz dodać nowy wpis %s poniżej."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:634
|
||||
=======
|
||||
#: contrib/admin/options.py:637
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was changed successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" zostało pomyślnie zmienione."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:642
|
||||
=======
|
||||
#: contrib/admin/options.py:645
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr ""
|
||||
"%(name)s \"%(obj)s\" dodane pomyślnie. Możesz edytować ponownie wpis poniżej."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:773
|
||||
=======
|
||||
#: contrib/admin/options.py:778
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "Add %s"
|
||||
msgstr "Dodaj %s"
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:804 contrib/admin/options.py:1005
|
||||
=======
|
||||
#: contrib/admin/options.py:810 contrib/admin/options.py:1012
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "%(name)s object with primary key %(key)r does not exist."
|
||||
msgstr "Obiekt %(name)s o kluczu głównym %(key)r nie istnieje."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:861
|
||||
=======
|
||||
#: contrib/admin/options.py:867
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "Change %s"
|
||||
msgstr "Zmień %s"
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:905
|
||||
msgid "Database error"
|
||||
msgstr "Błąd bazy danych"
|
||||
|
||||
#: contrib/admin/options.py:941
|
||||
=======
|
||||
#: contrib/admin/options.py:911
|
||||
msgid "Database error"
|
||||
msgstr "Błąd bazy danych"
|
||||
|
||||
#: contrib/admin/options.py:947
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "%(count)s %(name)s was changed successfully."
|
||||
msgid_plural "%(count)s %(name)s were changed successfully."
|
||||
@ -398,17 +451,29 @@ msgstr[0] "%(count)s %(name)s został pomyślnie zmieniony."
|
||||
msgstr[1] "%(count)s %(name)s zostały pomyślnie zmienione."
|
||||
msgstr[2] "%(count)s %(name)s zostało pomyślnie zmienionych."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:1020
|
||||
=======
|
||||
#: contrib/admin/options.py:1027
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was deleted successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" usunięty pomyślnie."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/options.py:1057
|
||||
=======
|
||||
#: contrib/admin/options.py:1064
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "Change history: %s"
|
||||
msgstr "Historia zmian: %s"
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/sites.py:21 contrib/admin/views/decorators.py:14
|
||||
=======
|
||||
#: contrib/admin/sites.py:22 contrib/admin/views/decorators.py:14
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/auth/forms.py:80
|
||||
msgid ""
|
||||
"Please enter a correct username and password. Note that both fields are case-"
|
||||
@ -417,11 +482,19 @@ msgstr ""
|
||||
"Proszę wpisać poprawną nazwę użytkownika i hasło. Uwaga: wielkość liter ma "
|
||||
"znaczenie."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/sites.py:288 contrib/admin/views/decorators.py:40
|
||||
msgid "Please log in again, because your session has expired."
|
||||
msgstr "Twoja sesja wygasła, zaloguj się ponownie."
|
||||
|
||||
#: contrib/admin/sites.py:295 contrib/admin/views/decorators.py:47
|
||||
=======
|
||||
#: contrib/admin/sites.py:292 contrib/admin/views/decorators.py:40
|
||||
msgid "Please log in again, because your session has expired."
|
||||
msgstr "Twoja sesja wygasła, zaloguj się ponownie."
|
||||
|
||||
#: contrib/admin/sites.py:299 contrib/admin/views/decorators.py:47
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
msgid ""
|
||||
"Looks like your browser isn't configured to accept cookies. Please enable "
|
||||
"cookies, reload this page, and try again."
|
||||
@ -429,27 +502,47 @@ msgstr ""
|
||||
"Twoja przeglądarka nie chce akceptować ciasteczek. Zmień jej ustawienia i "
|
||||
"spróbuj ponownie."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/sites.py:311 contrib/admin/sites.py:317
|
||||
=======
|
||||
#: contrib/admin/sites.py:315 contrib/admin/sites.py:321
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/views/decorators.py:66
|
||||
msgid "Usernames cannot contain the '@' character."
|
||||
msgstr "Nazwy użytkowników nie mogą zawierać znaku '@'."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/sites.py:314 contrib/admin/views/decorators.py:62
|
||||
=======
|
||||
#: contrib/admin/sites.py:318 contrib/admin/views/decorators.py:62
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "Your e-mail address is not your username. Try '%s' instead."
|
||||
msgstr "Podany adres e-mail nie jest Twoją nazwą użytkownika. Spróbuj '%s'."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/sites.py:370
|
||||
msgid "Site administration"
|
||||
msgstr "Administracja stroną"
|
||||
|
||||
#: contrib/admin/sites.py:384 contrib/admin/templates/admin/login.html:26
|
||||
=======
|
||||
#: contrib/admin/sites.py:374
|
||||
msgid "Site administration"
|
||||
msgstr "Administracja stroną"
|
||||
|
||||
#: contrib/admin/sites.py:388 contrib/admin/templates/admin/login.html:26
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/templates/registration/password_reset_complete.html:14
|
||||
#: contrib/admin/views/decorators.py:20
|
||||
msgid "Log in"
|
||||
msgstr "Zaloguj się"
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/admin/sites.py:429
|
||||
=======
|
||||
#: contrib/admin/sites.py:433
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "%s administration"
|
||||
msgstr "%s - administracja"
|
||||
@ -670,8 +763,13 @@ msgid ""
|
||||
"Are you sure you want to delete the selected %(object_name)s objects? All of "
|
||||
"the following objects and their related items will be deleted:"
|
||||
msgstr ""
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
"Czy chcesz skasować wybrane %(object_name)s? Następujące obiekty i zależne od "
|
||||
"nich zostaną skasowane:"
|
||||
=======
|
||||
"Czy chcesz skasować wybrane %(object_name)s? Następujące obiekty i zależne "
|
||||
"od nich zostaną skasowane:"
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
|
||||
#: contrib/admin/templates/admin/filter.html:2
|
||||
#, python-format
|
||||
@ -977,7 +1075,7 @@ msgstr "Adres e-mail:"
|
||||
msgid "Reset my password"
|
||||
msgstr "Zresetuj moje hasło"
|
||||
|
||||
#: contrib/admin/templatetags/admin_list.py:299
|
||||
#: contrib/admin/templatetags/admin_list.py:304
|
||||
msgid "All dates"
|
||||
msgstr "Wszystkie daty"
|
||||
|
||||
@ -991,11 +1089,11 @@ msgstr "Zaznacz %s"
|
||||
msgid "Select %s to change"
|
||||
msgstr "Zaznacz %s aby zmienić"
|
||||
|
||||
#: contrib/admin/views/template.py:37 contrib/sites/models.py:38
|
||||
#: contrib/admin/views/template.py:38 contrib/sites/models.py:38
|
||||
msgid "site"
|
||||
msgstr "strona"
|
||||
|
||||
#: contrib/admin/views/template.py:39
|
||||
#: contrib/admin/views/template.py:40
|
||||
msgid "template"
|
||||
msgstr "szablon"
|
||||
|
||||
@ -1209,37 +1307,37 @@ msgstr "Edytuj ten obiekt (nowe okno)"
|
||||
msgid "As above, but opens the admin page in a new window."
|
||||
msgstr "Jak wyżej, tyle że otwiera nowe okno."
|
||||
|
||||
#: contrib/auth/admin.py:21
|
||||
#: contrib/auth/admin.py:22
|
||||
msgid "Personal info"
|
||||
msgstr "Dane osobowe"
|
||||
|
||||
#: contrib/auth/admin.py:22
|
||||
#: contrib/auth/admin.py:23
|
||||
msgid "Permissions"
|
||||
msgstr "Uprawnienia"
|
||||
|
||||
#: contrib/auth/admin.py:23
|
||||
#: contrib/auth/admin.py:24
|
||||
msgid "Important dates"
|
||||
msgstr "Ważne daty"
|
||||
|
||||
#: contrib/auth/admin.py:24
|
||||
#: contrib/auth/admin.py:25
|
||||
msgid "Groups"
|
||||
msgstr "Grupy"
|
||||
|
||||
#: contrib/auth/admin.py:80
|
||||
#: contrib/auth/admin.py:82
|
||||
msgid "Add user"
|
||||
msgstr "Dodaj użytkownika"
|
||||
|
||||
#: contrib/auth/admin.py:106
|
||||
#: contrib/auth/admin.py:108
|
||||
msgid "Password changed successfully."
|
||||
msgstr "Hasło zostało zmienione pomyślnie."
|
||||
|
||||
#: contrib/auth/admin.py:112
|
||||
#: contrib/auth/admin.py:114
|
||||
#, python-format
|
||||
msgid "Change password: %s"
|
||||
msgstr "Zmień hasło: %s"
|
||||
|
||||
#: contrib/auth/forms.py:15 contrib/auth/forms.py:48
|
||||
#: contrib/auth/models.py:128
|
||||
#: contrib/auth/models.py:129
|
||||
msgid ""
|
||||
"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
|
||||
"digits and underscores)."
|
||||
@ -1329,31 +1427,31 @@ msgstr "uprawnienia"
|
||||
msgid "group"
|
||||
msgstr "grupa"
|
||||
|
||||
#: contrib/auth/models.py:91 contrib/auth/models.py:138
|
||||
#: contrib/auth/models.py:91 contrib/auth/models.py:139
|
||||
msgid "groups"
|
||||
msgstr "grupy"
|
||||
|
||||
#: contrib/auth/models.py:128
|
||||
#: contrib/auth/models.py:129
|
||||
msgid "username"
|
||||
msgstr "użytkownik"
|
||||
|
||||
#: contrib/auth/models.py:129
|
||||
#: contrib/auth/models.py:130
|
||||
msgid "first name"
|
||||
msgstr "imię"
|
||||
|
||||
#: contrib/auth/models.py:130
|
||||
#: contrib/auth/models.py:131
|
||||
msgid "last name"
|
||||
msgstr "nazwisko"
|
||||
|
||||
#: contrib/auth/models.py:131
|
||||
#: contrib/auth/models.py:132
|
||||
msgid "e-mail address"
|
||||
msgstr "adres e-mail"
|
||||
|
||||
#: contrib/auth/models.py:132
|
||||
#: contrib/auth/models.py:133
|
||||
msgid "password"
|
||||
msgstr "hasło"
|
||||
|
||||
#: contrib/auth/models.py:132
|
||||
#: contrib/auth/models.py:133
|
||||
msgid ""
|
||||
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
|
||||
"password form</a>."
|
||||
@ -1361,19 +1459,19 @@ msgstr ""
|
||||
"Użyj '[algo]$[salt]$[hexdigest]' lub <a href=\"password/\">formularza zmiany "
|
||||
"hasła</a>."
|
||||
|
||||
#: contrib/auth/models.py:133
|
||||
#: contrib/auth/models.py:134
|
||||
msgid "staff status"
|
||||
msgstr "w zespole"
|
||||
|
||||
#: contrib/auth/models.py:133
|
||||
#: contrib/auth/models.py:134
|
||||
msgid "Designates whether the user can log into this admin site."
|
||||
msgstr "Oznacza czy użytkownik może zalogować się do panelu admina."
|
||||
|
||||
#: contrib/auth/models.py:134
|
||||
#: contrib/auth/models.py:135
|
||||
msgid "active"
|
||||
msgstr "aktywny"
|
||||
|
||||
#: contrib/auth/models.py:134
|
||||
#: contrib/auth/models.py:135
|
||||
msgid ""
|
||||
"Designates whether this user should be treated as active. Unselect this "
|
||||
"instead of deleting accounts."
|
||||
@ -1381,11 +1479,11 @@ msgstr ""
|
||||
"Oznacza czy użytkownika należy uważać za aktywnego. Odznacz to, zamiast "
|
||||
"usuwać konta."
|
||||
|
||||
#: contrib/auth/models.py:135
|
||||
#: contrib/auth/models.py:136
|
||||
msgid "superuser status"
|
||||
msgstr "status administratora"
|
||||
|
||||
#: contrib/auth/models.py:135
|
||||
#: contrib/auth/models.py:136
|
||||
msgid ""
|
||||
"Designates that this user has all permissions without explicitly assigning "
|
||||
"them."
|
||||
@ -1393,15 +1491,15 @@ msgstr ""
|
||||
"Oznacza, że ten użytkownik ma wszystkie uprawnienia bez jawnego "
|
||||
"przypisywania ich."
|
||||
|
||||
#: contrib/auth/models.py:136
|
||||
#: contrib/auth/models.py:137
|
||||
msgid "last login"
|
||||
msgstr "ostatnio zalogowany"
|
||||
|
||||
#: contrib/auth/models.py:137
|
||||
#: contrib/auth/models.py:138
|
||||
msgid "date joined"
|
||||
msgstr "data przyłączenia"
|
||||
|
||||
#: contrib/auth/models.py:139
|
||||
#: contrib/auth/models.py:140
|
||||
msgid ""
|
||||
"In addition to the permissions manually assigned, this user will also get "
|
||||
"all permissions granted to each group he/she is in."
|
||||
@ -1409,24 +1507,28 @@ msgstr ""
|
||||
"Oprócz uprawnień przypisanych bezpośrednio użytkownikowi otrzyma on "
|
||||
"uprawnienia grup, do których należy."
|
||||
|
||||
#: contrib/auth/models.py:140
|
||||
#: contrib/auth/models.py:141
|
||||
msgid "user permissions"
|
||||
msgstr "uprawnienia użytkownika"
|
||||
|
||||
#: contrib/auth/models.py:144 contrib/comments/models.py:50
|
||||
#: contrib/auth/models.py:145 contrib/comments/models.py:50
|
||||
#: contrib/comments/models.py:168
|
||||
msgid "user"
|
||||
msgstr "użytkownik"
|
||||
|
||||
#: contrib/auth/models.py:145
|
||||
#: contrib/auth/models.py:146
|
||||
msgid "users"
|
||||
msgstr "użytkownicy"
|
||||
|
||||
#: contrib/auth/models.py:301
|
||||
#: contrib/auth/models.py:334
|
||||
msgid "message"
|
||||
msgstr "wiadomość"
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: contrib/auth/views.py:58
|
||||
=======
|
||||
#: contrib/auth/views.py:60
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
msgid "Logged out"
|
||||
msgstr "Wylogowany"
|
||||
|
||||
@ -1774,7 +1876,7 @@ msgstr "strona statyczna"
|
||||
msgid "flat pages"
|
||||
msgstr "strony statyczne"
|
||||
|
||||
#: contrib/formtools/wizard.py:130
|
||||
#: contrib/formtools/wizard.py:132
|
||||
msgid ""
|
||||
"We apologize, but your form has expired. Please continue filling out the "
|
||||
"form from this page."
|
||||
@ -3811,6 +3913,10 @@ msgstr "Prowincja Północno-Zachodnia"
|
||||
msgid "Western Cape"
|
||||
msgstr "Prowincja Przylądkowa Zachodnia"
|
||||
|
||||
#: contrib/messages/tests/base.py:97
|
||||
msgid "lazy message"
|
||||
msgstr "testowa wiadomość z opóźnioną ewaluacją"
|
||||
|
||||
#: contrib/redirects/models.py:7
|
||||
msgid "redirect from"
|
||||
msgstr "przekieruj z"
|
||||
@ -3919,14 +4025,22 @@ msgstr ""
|
||||
msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
|
||||
msgstr "Proszę wpisać poprawną godzinę w formacie HH:MM[:ss[.uuuuuu]]."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: db/models/fields/related.py:816
|
||||
=======
|
||||
#: db/models/fields/related.py:869
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
"Przytrzymaj wciśnięty klawisz \"Ctrl\" lub \"Command\" na Mac'u aby "
|
||||
"zaznaczyć więcej niż jeden wybór."
|
||||
|
||||
<<<<<<< HEAD:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#: db/models/fields/related.py:894
|
||||
=======
|
||||
#: db/models/fields/related.py:930
|
||||
>>>>>>> master:django/conf/locale/pl/LC_MESSAGES/django.po
|
||||
#, python-format
|
||||
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
|
||||
msgid_plural ""
|
||||
@ -4427,17 +4541,17 @@ msgstr "Y-m"
|
||||
msgid "MONTH_DAY_FORMAT"
|
||||
msgstr "m-d"
|
||||
|
||||
#: views/generic/create_update.py:114
|
||||
#: views/generic/create_update.py:115
|
||||
#, python-format
|
||||
msgid "The %(verbose_name)s was created successfully."
|
||||
msgstr "%(verbose_name)s zostało pomyślnie utworzone."
|
||||
|
||||
#: views/generic/create_update.py:156
|
||||
#: views/generic/create_update.py:158
|
||||
#, python-format
|
||||
msgid "The %(verbose_name)s was updated successfully."
|
||||
msgstr "%(verbose_name)s zostało pomyślnie zmienione."
|
||||
|
||||
#: views/generic/create_update.py:198
|
||||
#: views/generic/create_update.py:201
|
||||
#, python-format
|
||||
msgid "The %(verbose_name)s was deleted."
|
||||
msgstr "%(verbose_name)s zostało usunięte."
|
||||
|
@ -1059,7 +1059,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||
content_type__id__exact = ContentType.objects.get_for_model(model).id
|
||||
).select_related().order_by('action_time')
|
||||
# If no history was found, see whether this object even exists.
|
||||
obj = get_object_or_404(model, pk=object_id)
|
||||
obj = get_object_or_404(model, pk=unquote(object_id))
|
||||
context = {
|
||||
'title': _('Change history: %s') % force_unicode(obj),
|
||||
'action_list': action_list,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import datetime
|
||||
from warnings import warn
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.utils.importlib import import_module
|
||||
|
||||
@ -19,6 +20,12 @@ def load_backend(path):
|
||||
cls = getattr(mod, attr)
|
||||
except AttributeError:
|
||||
raise ImproperlyConfigured, 'Module "%s" does not define a "%s" authentication backend' % (module, attr)
|
||||
try:
|
||||
getattr(cls, 'supports_object_permissions')
|
||||
except AttributeError:
|
||||
warn("Authentication backends without a `supports_object_permissions` attribute are deprecated. Please define it in %s." % cls,
|
||||
PendingDeprecationWarning)
|
||||
cls.supports_object_permissions = False
|
||||
return cls()
|
||||
|
||||
def get_backends():
|
||||
|
@ -11,6 +11,8 @@ class ModelBackend(object):
|
||||
"""
|
||||
Authenticates against django.contrib.auth.models.User.
|
||||
"""
|
||||
supports_object_permissions = False
|
||||
|
||||
# TODO: Model, login attribute name and password attribute name should be
|
||||
# configurable.
|
||||
def authenticate(self, username=None, password=None):
|
||||
|
@ -121,7 +121,8 @@ class UserManager(models.Manager):
|
||||
return ''.join([choice(allowed_chars) for i in range(length)])
|
||||
|
||||
class User(models.Model):
|
||||
"""Users within the Django authentication system are represented by this model.
|
||||
"""
|
||||
Users within the Django authentication system are represented by this model.
|
||||
|
||||
Username and password are required. Other fields are optional.
|
||||
"""
|
||||
@ -151,11 +152,16 @@ class User(models.Model):
|
||||
return "/users/%s/" % urllib.quote(smart_str(self.username))
|
||||
|
||||
def is_anonymous(self):
|
||||
"Always returns False. This is a way of comparing User objects to anonymous users."
|
||||
"""
|
||||
Always returns False. This is a way of comparing User objects to
|
||||
anonymous users.
|
||||
"""
|
||||
return False
|
||||
|
||||
def is_authenticated(self):
|
||||
"""Always return True. This is a way to tell if the user has been authenticated in templates.
|
||||
"""
|
||||
Always return True. This is a way to tell if the user has been
|
||||
authenticated in templates.
|
||||
"""
|
||||
return True
|
||||
|
||||
@ -194,30 +200,41 @@ class User(models.Model):
|
||||
def has_usable_password(self):
|
||||
return self.password != UNUSABLE_PASSWORD
|
||||
|
||||
def get_group_permissions(self):
|
||||
def get_group_permissions(self, obj=None):
|
||||
"""
|
||||
Returns a list of permission strings that this user has through
|
||||
his/her groups. This method queries all available auth backends.
|
||||
If an object is passed in, only permissions matching this object
|
||||
are returned.
|
||||
"""
|
||||
permissions = set()
|
||||
for backend in auth.get_backends():
|
||||
if hasattr(backend, "get_group_permissions"):
|
||||
permissions.update(backend.get_group_permissions(self))
|
||||
if obj is not None and backend.supports_object_permissions:
|
||||
group_permissions = backend.get_group_permissions(self, obj)
|
||||
else:
|
||||
group_permissions = backend.get_group_permissions(self)
|
||||
permissions.update(group_permissions)
|
||||
return permissions
|
||||
|
||||
def get_all_permissions(self):
|
||||
def get_all_permissions(self, obj=None):
|
||||
permissions = set()
|
||||
for backend in auth.get_backends():
|
||||
if hasattr(backend, "get_all_permissions"):
|
||||
permissions.update(backend.get_all_permissions(self))
|
||||
if obj is not None and backend.supports_object_permissions:
|
||||
all_permissions = backend.get_all_permissions(self, obj)
|
||||
else:
|
||||
all_permissions = backend.get_all_permissions(self)
|
||||
permissions.update(all_permissions)
|
||||
return permissions
|
||||
|
||||
def has_perm(self, perm):
|
||||
def has_perm(self, perm, obj=None):
|
||||
"""
|
||||
Returns True if the user has the specified permission. This method
|
||||
queries all available auth backends, but returns immediately if any
|
||||
backend returns True. Thus, a user who has permission from a single
|
||||
auth backend is assumed to have permission in general.
|
||||
auth backend is assumed to have permission in general. If an object
|
||||
is provided, permissions for this specific object are checked.
|
||||
"""
|
||||
# Inactive users have no permissions.
|
||||
if not self.is_active:
|
||||
@ -230,14 +247,22 @@ class User(models.Model):
|
||||
# Otherwise we need to check the backends.
|
||||
for backend in auth.get_backends():
|
||||
if hasattr(backend, "has_perm"):
|
||||
if backend.has_perm(self, perm):
|
||||
return True
|
||||
if obj is not None and backend.supports_object_permissions:
|
||||
if backend.has_perm(self, perm, obj):
|
||||
return True
|
||||
else:
|
||||
if backend.has_perm(self, perm):
|
||||
return True
|
||||
return False
|
||||
|
||||
def has_perms(self, perm_list):
|
||||
"""Returns True if the user has each of the specified permissions."""
|
||||
def has_perms(self, perm_list, obj=None):
|
||||
"""
|
||||
Returns True if the user has each of the specified permissions.
|
||||
If object is passed, it checks if the user has all required perms
|
||||
for this object.
|
||||
"""
|
||||
for perm in perm_list:
|
||||
if not self.has_perm(perm):
|
||||
if not self.has_perm(perm, obj):
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -358,10 +383,10 @@ class AnonymousUser(object):
|
||||
return self._user_permissions
|
||||
user_permissions = property(_get_user_permissions)
|
||||
|
||||
def has_perm(self, perm):
|
||||
def has_perm(self, perm, obj=None):
|
||||
return False
|
||||
|
||||
def has_perms(self, perm_list):
|
||||
def has_perms(self, perm_list, obj=None):
|
||||
return False
|
||||
|
||||
def has_module_perms(self, module):
|
||||
|
@ -4,6 +4,7 @@ from django.contrib.auth.tests.views \
|
||||
from django.contrib.auth.tests.forms import FORM_TESTS
|
||||
from django.contrib.auth.tests.remote_user \
|
||||
import RemoteUserTest, RemoteUserNoCreateTest, RemoteUserCustomTest
|
||||
from django.contrib.auth.tests.auth_backends import BackendTest, RowlevelBackendTest
|
||||
from django.contrib.auth.tests.tokens import TOKEN_GENERATOR_TESTS
|
||||
|
||||
# The password for the fixture data users is 'password'
|
||||
|
149
django/contrib/auth/tests/auth_backends.py
Normal file
149
django/contrib/auth/tests/auth_backends.py
Normal file
@ -0,0 +1,149 @@
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User, Group, Permission, AnonymousUser
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class BackendTest(TestCase):
|
||||
|
||||
backend = 'django.contrib.auth.backends.ModelBackend'
|
||||
|
||||
def setUp(self):
|
||||
self.curr_auth = settings.AUTHENTICATION_BACKENDS
|
||||
settings.AUTHENTICATION_BACKENDS = (self.backend,)
|
||||
User.objects.create_user('test', 'test@example.com', 'test')
|
||||
|
||||
def tearDown(self):
|
||||
settings.AUTHENTICATION_BACKENDS = self.curr_auth
|
||||
|
||||
def test_has_perm(self):
|
||||
user = User.objects.get(username='test')
|
||||
self.assertEqual(user.has_perm('auth.test'), False)
|
||||
user.is_staff = True
|
||||
user.save()
|
||||
self.assertEqual(user.has_perm('auth.test'), False)
|
||||
user.is_superuser = True
|
||||
user.save()
|
||||
self.assertEqual(user.has_perm('auth.test'), True)
|
||||
user.is_staff = False
|
||||
user.is_superuser = False
|
||||
user.save()
|
||||
self.assertEqual(user.has_perm('auth.test'), False)
|
||||
|
||||
def test_custom_perms(self):
|
||||
user = User.objects.get(username='test')
|
||||
content_type=ContentType.objects.get_for_model(Group)
|
||||
perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
|
||||
user.user_permissions.add(perm)
|
||||
user.save()
|
||||
|
||||
# reloading user to purge the _perm_cache
|
||||
user = User.objects.get(username='test')
|
||||
self.assertEqual(user.get_all_permissions() == set([u'auth.test']), True)
|
||||
self.assertEqual(user.get_group_permissions(), set([]))
|
||||
self.assertEqual(user.has_module_perms('Group'), False)
|
||||
self.assertEqual(user.has_module_perms('auth'), True)
|
||||
perm = Permission.objects.create(name='test2', content_type=content_type, codename='test2')
|
||||
user.user_permissions.add(perm)
|
||||
user.save()
|
||||
perm = Permission.objects.create(name='test3', content_type=content_type, codename='test3')
|
||||
user.user_permissions.add(perm)
|
||||
user.save()
|
||||
user = User.objects.get(username='test')
|
||||
self.assertEqual(user.get_all_permissions(), set([u'auth.test2', u'auth.test', u'auth.test3']))
|
||||
self.assertEqual(user.has_perm('test'), False)
|
||||
self.assertEqual(user.has_perm('auth.test'), True)
|
||||
self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), True)
|
||||
perm = Permission.objects.create(name='test_group', content_type=content_type, codename='test_group')
|
||||
group = Group.objects.create(name='test_group')
|
||||
group.permissions.add(perm)
|
||||
group.save()
|
||||
user.groups.add(group)
|
||||
user = User.objects.get(username='test')
|
||||
exp = set([u'auth.test2', u'auth.test', u'auth.test3', u'auth.test_group'])
|
||||
self.assertEqual(user.get_all_permissions(), exp)
|
||||
self.assertEqual(user.get_group_permissions(), set([u'auth.test_group']))
|
||||
self.assertEqual(user.has_perms(['auth.test3', 'auth.test_group']), True)
|
||||
|
||||
user = AnonymousUser()
|
||||
self.assertEqual(user.has_perm('test'), False)
|
||||
self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), False)
|
||||
|
||||
|
||||
class TestObj(object):
|
||||
pass
|
||||
|
||||
|
||||
class SimpleRowlevelBackend(object):
|
||||
supports_object_permissions = True
|
||||
|
||||
def has_perm(self, user, perm, obj=None):
|
||||
if not obj:
|
||||
return # We only support row level perms
|
||||
|
||||
if isinstance(obj, TestObj):
|
||||
if user.username == 'test2':
|
||||
return True
|
||||
elif isinstance(user, AnonymousUser) and perm == 'anon':
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_all_permissions(self, user, obj=None):
|
||||
if not obj:
|
||||
return [] # We only support row level perms
|
||||
|
||||
if not isinstance(obj, TestObj):
|
||||
return ['none']
|
||||
|
||||
if user.username == 'test2':
|
||||
return ['simple', 'advanced']
|
||||
else:
|
||||
return ['simple']
|
||||
|
||||
def get_group_permissions(self, user, obj=None):
|
||||
if not obj:
|
||||
return # We only support row level perms
|
||||
|
||||
if not isinstance(obj, TestObj):
|
||||
return ['none']
|
||||
|
||||
if 'test_group' in [group.name for group in user.groups.all()]:
|
||||
return ['group_perm']
|
||||
else:
|
||||
return ['none']
|
||||
|
||||
|
||||
class RowlevelBackendTest(TestCase):
|
||||
|
||||
backend = 'django.contrib.auth.tests.auth_backends.SimpleRowlevelBackend'
|
||||
|
||||
def setUp(self):
|
||||
self.curr_auth = settings.AUTHENTICATION_BACKENDS
|
||||
settings.AUTHENTICATION_BACKENDS = self.curr_auth + (self.backend,)
|
||||
self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
|
||||
self.user2 = User.objects.create_user('test2', 'test2@example.com', 'test')
|
||||
self.user3 = AnonymousUser()
|
||||
self.user4 = User.objects.create_user('test4', 'test4@example.com', 'test')
|
||||
|
||||
def tearDown(self):
|
||||
settings.AUTHENTICATION_BACKENDS = self.curr_auth
|
||||
|
||||
def test_has_perm(self):
|
||||
self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
|
||||
self.assertEqual(self.user2.has_perm('perm', TestObj()), True)
|
||||
self.assertEqual(self.user2.has_perm('perm'), False)
|
||||
self.assertEqual(self.user2.has_perms(['simple', 'advanced'], TestObj()), True)
|
||||
self.assertEqual(self.user3.has_perm('perm', TestObj()), False)
|
||||
self.assertEqual(self.user3.has_perm('anon', TestObj()), False)
|
||||
self.assertEqual(self.user3.has_perms(['simple', 'advanced'], TestObj()), False)
|
||||
|
||||
def test_get_all_permissions(self):
|
||||
self.assertEqual(self.user1.get_all_permissions(TestObj()), set(['simple']))
|
||||
self.assertEqual(self.user2.get_all_permissions(TestObj()), set(['simple', 'advanced']))
|
||||
self.assertEqual(self.user2.get_all_permissions(), set([]))
|
||||
|
||||
def test_get_group_permissions(self):
|
||||
content_type=ContentType.objects.get_for_model(Group)
|
||||
group = Group.objects.create(name='test_group')
|
||||
self.user4.groups.add(group)
|
||||
self.assertEqual(self.user4.get_group_permissions(TestObj()), set(['group_perm']))
|
@ -279,11 +279,19 @@ class RelatedGeoModelTest(unittest.TestCase):
|
||||
def test14_collect(self):
|
||||
"Testing the `collect` GeoQuerySet method and `Collect` aggregate."
|
||||
# Reference query:
|
||||
<<<<<<< HEAD:django/contrib/gis/tests/relatedapp/tests.py
|
||||
# SELECT AsText(ST_Collect("relatedapp_location"."point")) FROM "relatedapp_city" LEFT OUTER JOIN
|
||||
# "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id")
|
||||
# WHERE "relatedapp_city"."state" = 'TX';
|
||||
ref_geom = fromstr('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)')
|
||||
|
||||
=======
|
||||
# SELECT AsText(ST_Collect("relatedapp_location"."point")) FROM "relatedapp_city" LEFT OUTER JOIN
|
||||
# "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id")
|
||||
# WHERE "relatedapp_city"."state" = 'TX';
|
||||
ref_geom = fromstr('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)')
|
||||
|
||||
>>>>>>> master:django/contrib/gis/tests/relatedapp/tests.py
|
||||
c1 = City.objects.filter(state='TX').collect(field_name='location__point')
|
||||
c2 = City.objects.filter(state='TX').aggregate(Collect('location__point'))['location__point__collect']
|
||||
|
||||
@ -292,7 +300,10 @@ class RelatedGeoModelTest(unittest.TestCase):
|
||||
# consolidate -- that's why 4 points in MultiPoint.
|
||||
self.assertEqual(4, len(coll))
|
||||
self.assertEqual(ref_geom, coll)
|
||||
<<<<<<< HEAD:django/contrib/gis/tests/relatedapp/tests.py
|
||||
|
||||
=======
|
||||
>>>>>>> master:django/contrib/gis/tests/relatedapp/tests.py
|
||||
|
||||
# TODO: Related tests for KML, GML, and distance lookups.
|
||||
|
||||
|
@ -82,9 +82,14 @@ class Command(BaseCommand):
|
||||
model_list = get_models(app)
|
||||
|
||||
for model in model_list:
|
||||
<<<<<<< HEAD:django/core/management/commands/dumpdata.py
|
||||
# Don't serialize proxy models, or models that haven't been synchronized
|
||||
if not model._meta.proxy and model._meta.db_table in tables:
|
||||
objects.extend(model._default_manager.using(using).all())
|
||||
=======
|
||||
if not model._meta.proxy:
|
||||
objects.extend(model._default_manager.all())
|
||||
>>>>>>> master:django/core/management/commands/dumpdata.py
|
||||
|
||||
try:
|
||||
return serializers.serialize(format, objects, indent=indent)
|
||||
|
@ -357,7 +357,11 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
cursor = None
|
||||
if not self._valid_connection():
|
||||
conn_string = convert_unicode(self._connect_string())
|
||||
<<<<<<< HEAD:django/db/backends/oracle/base.py
|
||||
self.connection = Database.connect(conn_string, **self.settings_dict['OPTIONS'])
|
||||
=======
|
||||
self.connection = Database.connect(conn_string, **self.settings_dict['DATABASE_OPTIONS'])
|
||||
>>>>>>> master:django/db/backends/oracle/base.py
|
||||
cursor = FormatStylePlaceholderCursor(self.connection)
|
||||
# Set oracle date to ansi date format. This only needs to execute
|
||||
# once when we create a new connection. We also set the Territory
|
||||
|
@ -230,6 +230,7 @@ class ModelBase(type):
|
||||
|
||||
signals.class_prepared.send(sender=cls)
|
||||
|
||||
<<<<<<< HEAD:django/db/models/base.py
|
||||
class ModelState(object):
|
||||
"""
|
||||
A class for storing instance state
|
||||
@ -237,6 +238,8 @@ class ModelState(object):
|
||||
def __init__(self, db=None):
|
||||
self.db = db
|
||||
|
||||
=======
|
||||
>>>>>>> master:django/db/models/base.py
|
||||
class Model(object):
|
||||
__metaclass__ = ModelBase
|
||||
_deferred = False
|
||||
@ -488,7 +491,11 @@ class Model(object):
|
||||
if pk_set:
|
||||
# Determine whether a record with the primary key already exists.
|
||||
if (force_update or (not force_insert and
|
||||
<<<<<<< HEAD:django/db/models/base.py
|
||||
manager.using(using).filter(pk=pk_val).exists())):
|
||||
=======
|
||||
manager.filter(pk=pk_val).exists())):
|
||||
>>>>>>> master:django/db/models/base.py
|
||||
# It does already exist, so do an UPDATE.
|
||||
if force_update or non_pks:
|
||||
values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks]
|
||||
@ -527,7 +534,10 @@ class Model(object):
|
||||
# Store the database on which the object was saved
|
||||
self._state.db = using
|
||||
|
||||
<<<<<<< HEAD:django/db/models/base.py
|
||||
# Signal that the save is complete
|
||||
=======
|
||||
>>>>>>> master:django/db/models/base.py
|
||||
if origin and not meta.auto_created:
|
||||
signals.post_save.send(sender=origin, instance=self,
|
||||
created=(not record_exists), raw=raw)
|
||||
|
@ -474,7 +474,11 @@ def create_many_related_manager(superclass, rel=False):
|
||||
if not rel.through._meta.auto_created:
|
||||
opts = through._meta
|
||||
raise AttributeError, "Cannot use create() on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name)
|
||||
<<<<<<< HEAD:django/db/models/fields/related.py
|
||||
new_obj = super(ManyRelatedManager, self).using(self.instance._state.db).create(**kwargs)
|
||||
=======
|
||||
new_obj = super(ManyRelatedManager, self).create(**kwargs)
|
||||
>>>>>>> master:django/db/models/fields/related.py
|
||||
self.add(new_obj)
|
||||
return new_obj
|
||||
create.alters_data = True
|
||||
@ -501,15 +505,22 @@ def create_many_related_manager(superclass, rel=False):
|
||||
new_ids = set()
|
||||
for obj in objs:
|
||||
if isinstance(obj, self.model):
|
||||
<<<<<<< HEAD:django/db/models/fields/related.py
|
||||
if obj._state.db != self.instance._state.db:
|
||||
raise ValueError('Cannot add "%r": instance is on database "%s", value is is on database "%s"' %
|
||||
(obj, self.instance._state.db, obj._state.db))
|
||||
=======
|
||||
>>>>>>> master:django/db/models/fields/related.py
|
||||
new_ids.add(obj.pk)
|
||||
elif isinstance(obj, Model):
|
||||
raise TypeError, "'%s' instance expected" % self.model._meta.object_name
|
||||
else:
|
||||
new_ids.add(obj)
|
||||
<<<<<<< HEAD:django/db/models/fields/related.py
|
||||
vals = self.through._default_manager.using(self.instance._state.db).values_list(target_field_name, flat=True)
|
||||
=======
|
||||
vals = self.through._default_manager.values_list(target_field_name, flat=True)
|
||||
>>>>>>> master:django/db/models/fields/related.py
|
||||
vals = vals.filter(**{
|
||||
source_field_name: self._pk_val,
|
||||
'%s__in' % target_field_name: new_ids,
|
||||
@ -518,7 +529,11 @@ def create_many_related_manager(superclass, rel=False):
|
||||
|
||||
# Add the ones that aren't there already
|
||||
for obj_id in (new_ids - vals):
|
||||
<<<<<<< HEAD:django/db/models/fields/related.py
|
||||
self.through._default_manager.using(self.instance._state.db).create(**{
|
||||
=======
|
||||
self.through._default_manager.create(**{
|
||||
>>>>>>> master:django/db/models/fields/related.py
|
||||
'%s_id' % source_field_name: self._pk_val,
|
||||
'%s_id' % target_field_name: obj_id,
|
||||
})
|
||||
@ -538,14 +553,22 @@ def create_many_related_manager(superclass, rel=False):
|
||||
else:
|
||||
old_ids.add(obj)
|
||||
# Remove the specified objects from the join table
|
||||
<<<<<<< HEAD:django/db/models/fields/related.py
|
||||
self.through._default_manager.using(self.instance._state.db).filter(**{
|
||||
=======
|
||||
self.through._default_manager.filter(**{
|
||||
>>>>>>> master:django/db/models/fields/related.py
|
||||
source_field_name: self._pk_val,
|
||||
'%s__in' % target_field_name: old_ids
|
||||
}).delete()
|
||||
|
||||
def _clear_items(self, source_field_name):
|
||||
# source_col_name: the PK colname in join_table for the source object
|
||||
<<<<<<< HEAD:django/db/models/fields/related.py
|
||||
self.through._default_manager.using(self.instance._state.db).filter(**{
|
||||
=======
|
||||
self.through._default_manager.filter(**{
|
||||
>>>>>>> master:django/db/models/fields/related.py
|
||||
source_field_name: self._pk_val
|
||||
}).delete()
|
||||
|
||||
|
@ -172,9 +172,12 @@ class Manager(object):
|
||||
def only(self, *args, **kwargs):
|
||||
return self.get_query_set().only(*args, **kwargs)
|
||||
|
||||
<<<<<<< HEAD:django/db/models/manager.py
|
||||
def using(self, *args, **kwargs):
|
||||
return self.get_query_set().using(*args, **kwargs)
|
||||
|
||||
=======
|
||||
>>>>>>> master:django/db/models/manager.py
|
||||
def exists(self, *args, **kwargs):
|
||||
return self.get_query_set().exists(*args, **kwargs)
|
||||
|
||||
|
@ -3,8 +3,12 @@ The main QuerySet implementation. This provides the public API for the ORM.
|
||||
"""
|
||||
|
||||
from copy import deepcopy
|
||||
<<<<<<< HEAD:django/db/models/query.py
|
||||
|
||||
from django.db import connections, transaction, IntegrityError, DEFAULT_DB_ALIAS
|
||||
=======
|
||||
from django.db import connection, transaction, IntegrityError
|
||||
>>>>>>> master:django/db/models/query.py
|
||||
from django.db.models.aggregates import Aggregate
|
||||
from django.db.models.fields import DateField
|
||||
from django.db.models.query_utils import Q, select_related_descend, CollectedObjects, CyclicDependency, deferred_class_factory
|
||||
@ -476,7 +480,11 @@ class QuerySet(object):
|
||||
|
||||
def exists(self):
|
||||
if self._result_cache is None:
|
||||
<<<<<<< HEAD:django/db/models/query.py
|
||||
return self.query.has_results(using=self.db)
|
||||
=======
|
||||
return self.query.has_results()
|
||||
>>>>>>> master:django/db/models/query.py
|
||||
return bool(self._result_cache)
|
||||
|
||||
##################################################
|
||||
|
@ -22,8 +22,12 @@ from django.db.models.sql.expressions import SQLEvaluator
|
||||
from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, AND, OR
|
||||
from django.core.exceptions import FieldError
|
||||
|
||||
<<<<<<< HEAD:django/db/models/sql/query.py
|
||||
|
||||
__all__ = ['Query']
|
||||
=======
|
||||
__all__ = ['Query', 'BaseQuery']
|
||||
>>>>>>> master:django/db/models/sql/query.py
|
||||
|
||||
class Query(object):
|
||||
"""
|
||||
@ -337,7 +341,11 @@ class Query(object):
|
||||
|
||||
return number
|
||||
|
||||
<<<<<<< HEAD:django/db/models/sql/query.py
|
||||
def has_results(self, using):
|
||||
=======
|
||||
def has_results(self):
|
||||
>>>>>>> master:django/db/models/sql/query.py
|
||||
q = self.clone()
|
||||
q.add_extra({'a': 1}, None, None, None, None, None)
|
||||
q.add_fields(())
|
||||
@ -345,8 +353,104 @@ class Query(object):
|
||||
q.set_aggregate_mask(())
|
||||
q.clear_ordering()
|
||||
q.set_limits(high=1)
|
||||
<<<<<<< HEAD:django/db/models/sql/query.py
|
||||
compiler = q.get_compiler(using=using)
|
||||
return bool(compiler.execute_sql(SINGLE))
|
||||
=======
|
||||
return bool(q.execute_sql(SINGLE))
|
||||
|
||||
def as_sql(self, with_limits=True, with_col_aliases=False):
|
||||
"""
|
||||
Creates the SQL for this query. Returns the SQL string and list of
|
||||
parameters.
|
||||
|
||||
If 'with_limits' is False, any limit/offset information is not included
|
||||
in the query.
|
||||
"""
|
||||
self.pre_sql_setup()
|
||||
out_cols = self.get_columns(with_col_aliases)
|
||||
ordering, ordering_group_by = self.get_ordering()
|
||||
|
||||
# This must come after 'select' and 'ordering' -- see docstring of
|
||||
# get_from_clause() for details.
|
||||
from_, f_params = self.get_from_clause()
|
||||
|
||||
qn = self.quote_name_unless_alias
|
||||
where, w_params = self.where.as_sql(qn=qn)
|
||||
having, h_params = self.having.as_sql(qn=qn)
|
||||
params = []
|
||||
for val in self.extra_select.itervalues():
|
||||
params.extend(val[1])
|
||||
|
||||
result = ['SELECT']
|
||||
if self.distinct:
|
||||
result.append('DISTINCT')
|
||||
result.append(', '.join(out_cols + self.ordering_aliases))
|
||||
|
||||
result.append('FROM')
|
||||
result.extend(from_)
|
||||
params.extend(f_params)
|
||||
|
||||
if where:
|
||||
result.append('WHERE %s' % where)
|
||||
params.extend(w_params)
|
||||
if self.extra_where:
|
||||
if not where:
|
||||
result.append('WHERE')
|
||||
else:
|
||||
result.append('AND')
|
||||
result.append(' AND '.join(self.extra_where))
|
||||
|
||||
grouping, gb_params = self.get_grouping()
|
||||
if grouping:
|
||||
if ordering:
|
||||
# If the backend can't group by PK (i.e., any database
|
||||
# other than MySQL), then any fields mentioned in the
|
||||
# ordering clause needs to be in the group by clause.
|
||||
if not self.connection.features.allows_group_by_pk:
|
||||
for col, col_params in ordering_group_by:
|
||||
if col not in grouping:
|
||||
grouping.append(str(col))
|
||||
gb_params.extend(col_params)
|
||||
else:
|
||||
ordering = self.connection.ops.force_no_ordering()
|
||||
result.append('GROUP BY %s' % ', '.join(grouping))
|
||||
params.extend(gb_params)
|
||||
|
||||
if having:
|
||||
result.append('HAVING %s' % having)
|
||||
params.extend(h_params)
|
||||
|
||||
if ordering:
|
||||
result.append('ORDER BY %s' % ', '.join(ordering))
|
||||
|
||||
if with_limits:
|
||||
if self.high_mark is not None:
|
||||
result.append('LIMIT %d' % (self.high_mark - self.low_mark))
|
||||
if self.low_mark:
|
||||
if self.high_mark is None:
|
||||
val = self.connection.ops.no_limit_value()
|
||||
if val:
|
||||
result.append('LIMIT %d' % val)
|
||||
result.append('OFFSET %d' % self.low_mark)
|
||||
|
||||
params.extend(self.extra_params)
|
||||
return ' '.join(result), tuple(params)
|
||||
|
||||
def as_nested_sql(self):
|
||||
"""
|
||||
Perform the same functionality as the as_sql() method, returning an
|
||||
SQL string and parameters. However, the alias prefixes are bumped
|
||||
beforehand (in a copy -- the current query isn't changed) and any
|
||||
ordering is removed.
|
||||
|
||||
Used when nesting this query inside another.
|
||||
"""
|
||||
obj = self.clone()
|
||||
obj.clear_ordering(True)
|
||||
obj.bump_prefix()
|
||||
return obj.as_sql()
|
||||
>>>>>>> master:django/db/models/sql/query.py
|
||||
|
||||
def combine(self, rhs, connector):
|
||||
"""
|
||||
|
@ -471,8 +471,12 @@ class BaseModelFormSet(BaseFormSet):
|
||||
pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)
|
||||
pk = self.data[pk_key]
|
||||
pk_field = self.model._meta.pk
|
||||
<<<<<<< HEAD:django/forms/models.py
|
||||
pk = pk_field.get_db_prep_lookup('exact', pk,
|
||||
connection=connections[self.get_queryset().db])
|
||||
=======
|
||||
pk = pk_field.get_db_prep_lookup('exact', pk)
|
||||
>>>>>>> master:django/forms/models.py
|
||||
if isinstance(pk, list):
|
||||
pk = pk[0]
|
||||
kwargs['instance'] = self._existing_object(pk)
|
||||
|
@ -11,6 +11,7 @@ except NameError:
|
||||
from django.template import Node, NodeList, Template, Context, Variable
|
||||
from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END
|
||||
from django.template import get_library, Library, InvalidTemplateLibrary
|
||||
from django.template.smartif import IfParser, Literal
|
||||
from django.conf import settings
|
||||
from django.utils.encoding import smart_str, smart_unicode
|
||||
from django.utils.itercompat import groupby
|
||||
@ -227,10 +228,9 @@ class IfEqualNode(Node):
|
||||
return self.nodelist_false.render(context)
|
||||
|
||||
class IfNode(Node):
|
||||
def __init__(self, bool_exprs, nodelist_true, nodelist_false, link_type):
|
||||
self.bool_exprs = bool_exprs
|
||||
def __init__(self, var, nodelist_true, nodelist_false=None):
|
||||
self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
|
||||
self.link_type = link_type
|
||||
self.var = var
|
||||
|
||||
def __repr__(self):
|
||||
return "<If node>"
|
||||
@ -250,28 +250,10 @@ class IfNode(Node):
|
||||
return nodes
|
||||
|
||||
def render(self, context):
|
||||
if self.link_type == IfNode.LinkTypes.or_:
|
||||
for ifnot, bool_expr in self.bool_exprs:
|
||||
try:
|
||||
value = bool_expr.resolve(context, True)
|
||||
except VariableDoesNotExist:
|
||||
value = None
|
||||
if (value and not ifnot) or (ifnot and not value):
|
||||
return self.nodelist_true.render(context)
|
||||
return self.nodelist_false.render(context)
|
||||
else:
|
||||
for ifnot, bool_expr in self.bool_exprs:
|
||||
try:
|
||||
value = bool_expr.resolve(context, True)
|
||||
except VariableDoesNotExist:
|
||||
value = None
|
||||
if not ((value and not ifnot) or (ifnot and not value)):
|
||||
return self.nodelist_false.render(context)
|
||||
if self.var.eval(context):
|
||||
return self.nodelist_true.render(context)
|
||||
|
||||
class LinkTypes:
|
||||
and_ = 0,
|
||||
or_ = 1
|
||||
else:
|
||||
return self.nodelist_false.render(context)
|
||||
|
||||
class RegroupNode(Node):
|
||||
def __init__(self, target, expression, var_name):
|
||||
@ -761,6 +743,27 @@ def ifnotequal(parser, token):
|
||||
return do_ifequal(parser, token, True)
|
||||
ifnotequal = register.tag(ifnotequal)
|
||||
|
||||
class TemplateLiteral(Literal):
|
||||
def __init__(self, value, text):
|
||||
self.value = value
|
||||
self.text = text # for better error messages
|
||||
|
||||
def display(self):
|
||||
return self.text
|
||||
|
||||
def eval(self, context):
|
||||
return self.value.resolve(context, ignore_failures=True)
|
||||
|
||||
class TemplateIfParser(IfParser):
|
||||
error_class = TemplateSyntaxError
|
||||
|
||||
def __init__(self, parser, *args, **kwargs):
|
||||
self.template_parser = parser
|
||||
return super(TemplateIfParser, self).__init__(*args, **kwargs)
|
||||
|
||||
def create_var(self, value):
|
||||
return TemplateLiteral(self.template_parser.compile_filter(value), value)
|
||||
|
||||
#@register.tag(name="if")
|
||||
def do_if(parser, token):
|
||||
"""
|
||||
@ -805,47 +808,21 @@ def do_if(parser, token):
|
||||
There are some athletes and absolutely no coaches.
|
||||
{% endif %}
|
||||
|
||||
``if`` tags do not allow ``and`` and ``or`` clauses with the same tag,
|
||||
because the order of logic would be ambigous. For example, this is
|
||||
invalid::
|
||||
Comparison operators are also available, and the use of filters is also
|
||||
allowed, for example:
|
||||
|
||||
{% if athlete_list and coach_list or cheerleader_list %}
|
||||
{% if articles|length >= 5 %}...{% endif %}
|
||||
|
||||
If you need to combine ``and`` and ``or`` to do advanced logic, just use
|
||||
nested if tags. For example::
|
||||
Arguments and operators _must_ have a space between them, so
|
||||
``{% if 1>2 %}`` is not a valid if tag.
|
||||
|
||||
{% if athlete_list %}
|
||||
{% if coach_list or cheerleader_list %}
|
||||
We have athletes, and either coaches or cheerleaders!
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
All supported operators are: ``or``, ``and``, ``in``, ``==`` (or ``=``),
|
||||
``!=``, ``>``, ``>=``, ``<`` and ``<=``.
|
||||
|
||||
Operator precedence follows Python.
|
||||
"""
|
||||
bits = token.contents.split()
|
||||
del bits[0]
|
||||
if not bits:
|
||||
raise TemplateSyntaxError("'if' statement requires at least one argument")
|
||||
# Bits now looks something like this: ['a', 'or', 'not', 'b', 'or', 'c.d']
|
||||
bitstr = ' '.join(bits)
|
||||
boolpairs = bitstr.split(' and ')
|
||||
boolvars = []
|
||||
if len(boolpairs) == 1:
|
||||
link_type = IfNode.LinkTypes.or_
|
||||
boolpairs = bitstr.split(' or ')
|
||||
else:
|
||||
link_type = IfNode.LinkTypes.and_
|
||||
if ' or ' in bitstr:
|
||||
raise TemplateSyntaxError, "'if' tags can't mix 'and' and 'or'"
|
||||
for boolpair in boolpairs:
|
||||
if ' ' in boolpair:
|
||||
try:
|
||||
not_, boolvar = boolpair.split()
|
||||
except ValueError:
|
||||
raise TemplateSyntaxError, "'if' statement improperly formatted"
|
||||
if not_ != 'not':
|
||||
raise TemplateSyntaxError, "Expected 'not' in if statement"
|
||||
boolvars.append((True, parser.compile_filter(boolvar)))
|
||||
else:
|
||||
boolvars.append((False, parser.compile_filter(boolpair)))
|
||||
bits = token.split_contents()[1:]
|
||||
var = TemplateIfParser(parser, bits).parse()
|
||||
nodelist_true = parser.parse(('else', 'endif'))
|
||||
token = parser.next_token()
|
||||
if token.contents == 'else':
|
||||
@ -853,7 +830,7 @@ def do_if(parser, token):
|
||||
parser.delete_first_token()
|
||||
else:
|
||||
nodelist_false = NodeList()
|
||||
return IfNode(boolvars, nodelist_true, nodelist_false, link_type)
|
||||
return IfNode(var, nodelist_true, nodelist_false)
|
||||
do_if = register.tag("if", do_if)
|
||||
|
||||
#@register.tag
|
||||
|
192
django/template/smartif.py
Normal file
192
django/template/smartif.py
Normal file
@ -0,0 +1,192 @@
|
||||
"""
|
||||
Parser and utilities for the smart 'if' tag
|
||||
"""
|
||||
import operator
|
||||
|
||||
# Using a simple top down parser, as described here:
|
||||
# http://effbot.org/zone/simple-top-down-parsing.htm.
|
||||
# 'led' = left denotation
|
||||
# 'nud' = null denotation
|
||||
# 'bp' = binding power (left = lbp, right = rbp)
|
||||
|
||||
class TokenBase(object):
|
||||
"""
|
||||
Base class for operators and literals, mainly for debugging and for throwing
|
||||
syntax errors.
|
||||
"""
|
||||
id = None # node/token type name
|
||||
value = None # used by literals
|
||||
first = second = None # used by tree nodes
|
||||
|
||||
def nud(self, parser):
|
||||
# Null denotation - called in prefix context
|
||||
raise parser.error_class(
|
||||
"Not expecting '%s' in this position in if tag." % self.id
|
||||
)
|
||||
|
||||
def led(self, left, parser):
|
||||
# Left denotation - called in infix context
|
||||
raise parser.error_class(
|
||||
"Not expecting '%s' as infix operator in if tag." % self.id
|
||||
)
|
||||
|
||||
def display(self):
|
||||
"""
|
||||
Returns what to display in error messages for this node
|
||||
"""
|
||||
return self.id
|
||||
|
||||
def __repr__(self):
|
||||
out = [str(x) for x in [self.id, self.first, self.second] if x is not None]
|
||||
return "(" + " ".join(out) + ")"
|
||||
|
||||
|
||||
def infix(bp, func):
|
||||
"""
|
||||
Creates an infix operator, given a binding power and a function that
|
||||
evaluates the node
|
||||
"""
|
||||
class Operator(TokenBase):
|
||||
lbp = bp
|
||||
|
||||
def led(self, left, parser):
|
||||
self.first = left
|
||||
self.second = parser.expression(bp)
|
||||
return self
|
||||
|
||||
def eval(self, context):
|
||||
try:
|
||||
return func(self.first.eval(context), self.second.eval(context))
|
||||
except Exception:
|
||||
# Templates shouldn't throw exceptions when rendering. We are
|
||||
# most likely to get exceptions for things like {% if foo in bar
|
||||
# %} where 'bar' does not support 'in', so default to False
|
||||
return False
|
||||
|
||||
return Operator
|
||||
|
||||
|
||||
def prefix(bp, func):
|
||||
"""
|
||||
Creates a prefix operator, given a binding power and a function that
|
||||
evaluates the node.
|
||||
"""
|
||||
class Operator(TokenBase):
|
||||
lbp = bp
|
||||
|
||||
def nud(self, parser):
|
||||
self.first = parser.expression(bp)
|
||||
self.second = None
|
||||
return self
|
||||
|
||||
def eval(self, context):
|
||||
try:
|
||||
return func(self.first.eval(context))
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
return Operator
|
||||
|
||||
|
||||
# Operator precedence follows Python.
|
||||
# NB - we can get slightly more accurate syntax error messages by not using the
|
||||
# same object for '==' and '='.
|
||||
|
||||
OPERATORS = {
|
||||
'or': infix(6, lambda x, y: x or y),
|
||||
'and': infix(7, lambda x, y: x and y),
|
||||
'not': prefix(8, operator.not_),
|
||||
'in': infix(9, lambda x, y: x in y),
|
||||
'=': infix(10, operator.eq),
|
||||
'==': infix(10, operator.eq),
|
||||
'!=': infix(10, operator.ne),
|
||||
'>': infix(10, operator.gt),
|
||||
'>=': infix(10, operator.ge),
|
||||
'<': infix(10, operator.lt),
|
||||
'<=': infix(10, operator.le),
|
||||
}
|
||||
|
||||
# Assign 'id' to each:
|
||||
for key, op in OPERATORS.items():
|
||||
op.id = key
|
||||
|
||||
|
||||
class Literal(TokenBase):
|
||||
"""
|
||||
A basic self-resolvable object similar to a Django template variable.
|
||||
"""
|
||||
# IfParser uses Literal in create_var, but TemplateIfParser overrides
|
||||
# create_var so that a proper implementation that actually resolves
|
||||
# variables, filters etc is used.
|
||||
id = "literal"
|
||||
lbp = 0
|
||||
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def display(self):
|
||||
return repr(self.value)
|
||||
|
||||
def nud(self, parser):
|
||||
return self
|
||||
|
||||
def eval(self, context):
|
||||
return self.value
|
||||
|
||||
def __repr__(self):
|
||||
return "(%s %r)" % (self.id, self.value)
|
||||
|
||||
|
||||
class EndToken(TokenBase):
|
||||
lbp = 0
|
||||
|
||||
def nud(self, parser):
|
||||
raise parser.error_class("Unexpected end of expression in if tag.")
|
||||
|
||||
EndToken = EndToken()
|
||||
|
||||
|
||||
class IfParser(object):
|
||||
error_class = ValueError
|
||||
|
||||
def __init__(self, tokens):
|
||||
self.tokens = map(self.translate_tokens, tokens)
|
||||
self.pos = 0
|
||||
self.current_token = self.next()
|
||||
|
||||
def translate_tokens(self, token):
|
||||
try:
|
||||
op = OPERATORS[token]
|
||||
except (KeyError, TypeError):
|
||||
return self.create_var(token)
|
||||
else:
|
||||
return op()
|
||||
|
||||
def next(self):
|
||||
if self.pos >= len(self.tokens):
|
||||
return EndToken
|
||||
else:
|
||||
retval = self.tokens[self.pos]
|
||||
self.pos += 1
|
||||
return retval
|
||||
|
||||
def parse(self):
|
||||
retval = self.expression()
|
||||
# Check that we have exhausted all the tokens
|
||||
if self.current_token is not EndToken:
|
||||
raise self.error_class("Unused '%s' at end of if expression." %
|
||||
self.current_token.display())
|
||||
return retval
|
||||
|
||||
def expression(self, rbp=0):
|
||||
t = self.current_token
|
||||
self.current_token = self.next()
|
||||
left = t.nud(self)
|
||||
while rbp < self.current_token.lbp:
|
||||
t = self.current_token
|
||||
self.current_token = self.next()
|
||||
left = t.led(left, self)
|
||||
return left
|
||||
|
||||
def create_var(self, value):
|
||||
return Literal(value)
|
@ -13,6 +13,13 @@ their deprecation, as per the :ref:`Django deprecation policy
|
||||
hooking up admin URLs. This has been deprecated since the 1.1
|
||||
release.
|
||||
|
||||
<<<<<<< HEAD:docs/internals/deprecation.txt
|
||||
=======
|
||||
* Authentication backends need to define the boolean attribute
|
||||
``supports_object_permissions``. The old backend style is deprecated
|
||||
since the 1.2 release.
|
||||
|
||||
>>>>>>> master:docs/internals/deprecation.txt
|
||||
* 1.4
|
||||
* ``CsrfResponseMiddleware``. This has been deprecated since the 1.2
|
||||
release, in favour of the template tag method for inserting the CSRF
|
||||
@ -26,6 +33,7 @@ their deprecation, as per the :ref:`Django deprecation policy
|
||||
class in favor of a generic E-mail backend API.
|
||||
|
||||
* The many to many SQL generation functions on the database backends
|
||||
<<<<<<< HEAD:docs/internals/deprecation.txt
|
||||
will be removed.
|
||||
|
||||
* The ability to use the ``DATABASE_*`` family of top-level settings to
|
||||
@ -39,6 +47,9 @@ their deprecation, as per the :ref:`Django deprecation policy
|
||||
``get_db_prep_lookup`` methods on Field were modified in 1.2 to support
|
||||
multiple databases. In 1.4, the support functions that allow methods
|
||||
with the old prototype to continue working will be removed.
|
||||
=======
|
||||
will be removed. These have been deprecated since the 1.2 release.
|
||||
>>>>>>> master:docs/internals/deprecation.txt
|
||||
|
||||
* The ``Message`` model (in ``django.contrib.auth``), its related
|
||||
manager in the ``User`` model (``user.message_set``), and the
|
||||
@ -48,6 +59,13 @@ their deprecation, as per the :ref:`Django deprecation policy
|
||||
:ref:`messages framework <ref-contrib-messages>` should be used
|
||||
instead.
|
||||
|
||||
<<<<<<< HEAD:docs/internals/deprecation.txt
|
||||
=======
|
||||
* Authentication backends need to support the ``obj`` parameter for
|
||||
permission checking. The ``supports_object_permissions`` variable
|
||||
is not checked any longer and can be removed.
|
||||
|
||||
>>>>>>> master:docs/internals/deprecation.txt
|
||||
* 2.0
|
||||
* ``django.views.defaults.shortcut()``. This function has been moved
|
||||
to ``django.contrib.contenttypes.views.shortcut()`` as part of the
|
||||
|
@ -257,7 +257,10 @@ Here's a sample configuration which uses a MySQL option file::
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD:docs/ref/databases.txt
|
||||
|
||||
=======
|
||||
>>>>>>> master:docs/ref/databases.txt
|
||||
# my.cnf
|
||||
[client]
|
||||
database = NAME
|
||||
|
@ -210,6 +210,24 @@ records to dump. If you're using a :ref:`custom manager <custom-managers>` as
|
||||
the default manager and it filters some of the available records, not all of the
|
||||
objects will be dumped.
|
||||
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
=======
|
||||
.. django-admin-option:: --exclude
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
Exclude a specific application from the applications whose contents is
|
||||
output. For example, to specifically exclude the `auth` application from
|
||||
the output, you would call::
|
||||
|
||||
django-admin.py dumpdata --exclude=auth
|
||||
|
||||
If you want to exclude multiple applications, use multiple ``--exclude``
|
||||
directives::
|
||||
|
||||
django-admin.py dumpdata --exclude=auth --exclude=contenttypes
|
||||
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
.. django-admin-option:: --format <fmt>
|
||||
|
||||
By default, ``dumpdata`` will format its output in JSON, but you can use the
|
||||
@ -221,11 +239,14 @@ are listed in :ref:`serialization-formats`.
|
||||
By default, ``dumpdata`` will output all data on a single line. This isn't
|
||||
easy for humans to read, so you can use the ``--indent`` option to
|
||||
pretty-print the output with a number of indentation spaces.
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
The :djadminopt:`--exclude` option may be provided to prevent specific
|
||||
applications from being dumped.
|
||||
=======
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
@ -252,12 +273,15 @@ fixture will be re-installed.
|
||||
|
||||
The :djadminopt:`--noinput` option may be provided to suppress all user
|
||||
prompts.
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
The :djadminopt:`--database` option may be used to specify the database
|
||||
to flush.
|
||||
|
||||
=======
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
|
||||
inspectdb
|
||||
---------
|
||||
@ -487,6 +511,7 @@ reset <appname appname ...>
|
||||
---------------------------
|
||||
|
||||
.. django-admin:: reset
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
|
||||
Executes the equivalent of ``sqlreset`` for the given app name(s).
|
||||
|
||||
@ -497,6 +522,13 @@ prompts.
|
||||
|
||||
The :djadminopt:`--database` option can be used to specify the alias
|
||||
of the database to reset.
|
||||
=======
|
||||
|
||||
Executes the equivalent of ``sqlreset`` for the given app name(s).
|
||||
|
||||
The :djadminopt:`--noinput` option may be provided to suppress all user
|
||||
prompts.
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
|
||||
runfcgi [options]
|
||||
-----------------
|
||||
@ -680,11 +712,14 @@ sqlflush
|
||||
|
||||
Prints the SQL statements that would be executed for the :djadmin:`flush`
|
||||
command.
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
The :djadminopt:`--database` option can be used to specify the database for
|
||||
which to print the SQL.
|
||||
=======
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
|
||||
sqlindexes <appname appname ...>
|
||||
--------------------------------
|
||||
@ -784,6 +819,7 @@ with an appropriate extension (e.g. ``json`` or ``xml``). See the
|
||||
documentation for ``loaddata`` for details on the specification of fixture
|
||||
data files.
|
||||
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
--noinput
|
||||
~~~~~~~~~
|
||||
The :djadminopt:`--noinput` option may be provided to suppress all user
|
||||
@ -793,15 +829,27 @@ prompts.
|
||||
|
||||
The :djadminopt:`--database` option can be used to specify the database to
|
||||
synchronize.
|
||||
=======
|
||||
The :djadminopt:`--noinput` option may be provided to suppress all user
|
||||
prompts.
|
||||
|
||||
test <app or test identifier>
|
||||
-----------------------------
|
||||
|
||||
.. django-admin:: test
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
|
||||
test <app or test identifier>
|
||||
-----------------------------
|
||||
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
.. django-admin:: test
|
||||
|
||||
Runs tests for all installed models. See :ref:`topics-testing` for more
|
||||
information.
|
||||
|
||||
=======
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
testserver <fixture fixture ...>
|
||||
--------------------------------
|
||||
|
||||
@ -935,6 +983,7 @@ Common options
|
||||
The following options are not available on every commands, but they are
|
||||
common to a number of commands.
|
||||
|
||||
<<<<<<< HEAD:docs/ref/django-admin.txt
|
||||
.. django-admin-option:: --database
|
||||
|
||||
.. versionadded:: 1.2
|
||||
@ -959,6 +1008,8 @@ directives::
|
||||
|
||||
django-admin.py dumpdata --exclude=auth --exclude=contenttypes
|
||||
|
||||
=======
|
||||
>>>>>>> master:docs/ref/django-admin.txt
|
||||
.. django-admin-option:: --locale
|
||||
|
||||
Use the ``--locale`` or ``-l`` option to specify the locale to process.
|
||||
|
@ -145,6 +145,54 @@ The default number of seconds to cache a page when the caching middleware or
|
||||
``cache_page()`` decorator is used.
|
||||
|
||||
.. setting:: CSRF_COOKIE_NAME
|
||||
<<<<<<< HEAD:docs/ref/settings.txt
|
||||
=======
|
||||
|
||||
CSRF_COOKIE_NAME
|
||||
----------------
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
Default: ``'csrftoken'``
|
||||
|
||||
The name of the cookie to use for the CSRF authentication token. This can be whatever you
|
||||
want. See :ref:`ref-contrib-csrf`.
|
||||
|
||||
.. setting:: CSRF_COOKIE_DOMAIN
|
||||
|
||||
CSRF_COOKIE_DOMAIN
|
||||
------------------
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
Default: ``None``
|
||||
|
||||
The domain to be used when setting the CSRF cookie. This can be useful for
|
||||
allowing cross-subdomain requests to be exluded from the normal cross site
|
||||
request forgery protection. It should be set to a string such as
|
||||
``".lawrence.com"`` to allow a POST request from a form on one subdomain to be
|
||||
accepted by accepted by a view served from another subdomain.
|
||||
|
||||
.. setting:: CSRF_FAILURE_VIEW
|
||||
|
||||
CSRF_FAILURE_VIEW
|
||||
-----------------
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
Default: ``'django.views.csrf.csrf_failure'``
|
||||
|
||||
A dotted path to the view function to be used when an incoming request
|
||||
is rejected by the CSRF protection. The function should have this signature::
|
||||
|
||||
def csrf_failure(request, reason="")
|
||||
|
||||
where ``reason`` is a short message (intended for developers or logging, not for
|
||||
end users) indicating the reason the request was rejected. See
|
||||
:ref:`ref-contrib-csrf`.
|
||||
|
||||
.. setting:: DATABASE_ENGINE
|
||||
>>>>>>> master:docs/ref/settings.txt
|
||||
|
||||
CSRF_COOKIE_NAME
|
||||
----------------
|
||||
|
@ -313,6 +313,9 @@ displayed by the ``{{ athlete_list|length }}`` variable.
|
||||
As you can see, the ``if`` tag can take an optional ``{% else %}`` clause that
|
||||
will be displayed if the test fails.
|
||||
|
||||
Boolean operators
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
``if`` tags may use ``and``, ``or`` or ``not`` to test a number of variables or
|
||||
to negate a given variable::
|
||||
|
||||
@ -338,24 +341,153 @@ to negate a given variable::
|
||||
There are some athletes and absolutely no coaches.
|
||||
{% endif %}
|
||||
|
||||
``if`` tags don't allow ``and`` and ``or`` clauses within the same tag, because
|
||||
the order of logic would be ambiguous. For example, this is invalid::
|
||||
.. versionchanged:: 1.2
|
||||
|
||||
Use of both ``and`` and ``or`` clauses within the same tag is allowed, with
|
||||
``and`` having higher precedence than ``or`` e.g.::
|
||||
|
||||
{% if athlete_list and coach_list or cheerleader_list %}
|
||||
|
||||
If you need to combine ``and`` and ``or`` to do advanced logic, just use nested
|
||||
``if`` tags. For example::
|
||||
will be interpreted like:
|
||||
|
||||
{% if athlete_list %}
|
||||
{% if coach_list or cheerleader_list %}
|
||||
We have athletes, and either coaches or cheerleaders!
|
||||
{% endif %}
|
||||
.. code-block:: python
|
||||
|
||||
if (athlete_list and coach_list) or cheerleader_list
|
||||
|
||||
Use of actual brackets in the ``if`` tag is invalid syntax. If you need them to
|
||||
indicate precedence, you should use nested ``if`` tags.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
|
||||
``if`` tags may also use the operators ``==``, ``!=``, ``<``, ``>``,
|
||||
``<=``, ``>=`` and ``in`` which work as follows:
|
||||
|
||||
|
||||
``==`` operator
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Equality. Example::
|
||||
|
||||
{% if somevar == "x" %}
|
||||
This appears if variable somevar equals the string "x"
|
||||
{% endif %}
|
||||
|
||||
Multiple uses of the same logical operator are fine, as long as you use the
|
||||
same operator. For example, this is valid::
|
||||
``!=`` operator
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Inequality. Example::
|
||||
|
||||
{% if somevar != "x" %}
|
||||
This appears if variable somevar does not equal the string "x",
|
||||
or if somevar is not found in the context
|
||||
{% endif %}
|
||||
|
||||
``<`` operator
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Less than. Example::
|
||||
|
||||
{% if somevar < 100 %}
|
||||
This appears if variable somevar is less than 100.
|
||||
{% endif %}
|
||||
|
||||
``>`` operator
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Greater than. Example::
|
||||
|
||||
{% if somevar > 0 %}
|
||||
This appears if variable somevar is greater than 0.
|
||||
{% endif %}
|
||||
|
||||
``<=`` operator
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Less than or equal to. Example::
|
||||
|
||||
{% if somevar <= 100 %}
|
||||
This appears if variable somevar is less than 100 or equal to 100.
|
||||
{% endif %}
|
||||
|
||||
``>=`` operator
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Greater than or equal to. Example::
|
||||
|
||||
{% if somevar >= 1 %}
|
||||
This appears if variable somevar is greater than 1 or equal to 1.
|
||||
{% endif %}
|
||||
|
||||
``in`` operator
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Contained within. This operator is supported by many Python containers to test
|
||||
whether the given value is in the container. The following are some examples of
|
||||
how ``x in y`` will be interpreted::
|
||||
|
||||
{% if "bc" in "abcdef" %}
|
||||
This appears since "bc" is a substring of "abcdef"
|
||||
{% endif %}
|
||||
|
||||
{% if "hello" in greetings %}
|
||||
If greetings is a list or set, one element of which is the string
|
||||
"hello", this will appear.
|
||||
{% endif %}
|
||||
|
||||
{% if user in users %}
|
||||
If users is a QuerySet, this will appear if user is an
|
||||
instance that belongs to the QuerySet.
|
||||
{% endif %}
|
||||
|
||||
|
||||
The comparison operators cannot be 'chained' like in Python or in mathematical
|
||||
notation. For example, instead of using::
|
||||
|
||||
{% if a > b > c %} (WRONG)
|
||||
|
||||
you should use::
|
||||
|
||||
{% if a > b and b > c %}
|
||||
|
||||
|
||||
Filters
|
||||
^^^^^^^
|
||||
|
||||
You can also use filters in the ``if`` expression. For example::
|
||||
|
||||
{% if messages|length >= 100 %}
|
||||
You have lots of messages today!
|
||||
{% endif %}
|
||||
|
||||
Complex expressions
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
All of the above can be combined to form complex expressions. For such
|
||||
expressions, it can be important to know how the operators are grouped when the
|
||||
expression is evaluated - that is, the precedence rules. The precedence of the
|
||||
operators, from lowest to highest, is as follows:
|
||||
|
||||
* ``or``
|
||||
* ``and``
|
||||
* ``not``
|
||||
* ``in``
|
||||
* ``==``, ``!=``, ``<``, ``>``,``<=``, ``>=``
|
||||
|
||||
(This follows Python exactly). So, for example, the following complex if tag:
|
||||
|
||||
{% if a == b or c == d and e %}
|
||||
|
||||
...will be interpreted as:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
(a == b) or ((c == d) and e)
|
||||
|
||||
If you need different precedence, you will need to use nested if tags. Sometimes
|
||||
that is better for clarity anyway, for the sake of those who do not know the
|
||||
precedence rules.
|
||||
|
||||
{% if athlete_list or coach_list or parent_list or teacher_list %}
|
||||
|
||||
.. templatetag:: ifchanged
|
||||
|
||||
@ -427,6 +559,9 @@ You cannot check for equality with Python objects such as ``True`` or
|
||||
``False``. If you need to test if something is true or false, use the ``if``
|
||||
tag instead.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
An alternative to the ``ifequal`` tag is to use the :ttag:`if` tag and the ``==`` operator.
|
||||
|
||||
.. templatetag:: ifnotequal
|
||||
|
||||
ifnotequal
|
||||
@ -434,6 +569,9 @@ ifnotequal
|
||||
|
||||
Just like ``ifequal``, except it tests that the two arguments are not equal.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
An alternative to the ``ifnotequal`` tag is to use the :ttag:`if` tag and the ``!=`` operator.
|
||||
|
||||
.. templatetag:: include
|
||||
|
||||
include
|
||||
|
@ -42,6 +42,18 @@ changes that developers must be aware of:
|
||||
* All of the CSRF has moved from contrib to core (with backwards compatible
|
||||
imports in the old locations, which are deprecated).
|
||||
|
||||
<<<<<<< HEAD:docs/releases/1.2.txt
|
||||
=======
|
||||
:ttag:`if` tag changes
|
||||
----------------------
|
||||
|
||||
Due to new features in the :ttag:`if` template tag, it no longer accepts 'and',
|
||||
'or' and 'not' as valid **variable** names. Previously that worked in some
|
||||
cases even though these strings were normally treated as keywords. Now, the
|
||||
keyword status is always enforced, and template code like ``{% if not %}`` or
|
||||
``{% if and %}`` will throw a TemplateSyntaxError.
|
||||
|
||||
>>>>>>> master:docs/releases/1.2.txt
|
||||
``LazyObject``
|
||||
--------------
|
||||
|
||||
@ -67,6 +79,7 @@ changes:
|
||||
|
||||
__members__ = property(lambda self: self.__dir__())
|
||||
|
||||
<<<<<<< HEAD:docs/releases/1.2.txt
|
||||
Specifying databases
|
||||
--------------------
|
||||
|
||||
@ -208,6 +221,8 @@ connection, you should be able to upgrade by renaming
|
||||
database specific conversions, then you will need to provide an
|
||||
implementation ``get_db_prep_*`` that uses the ``connection``
|
||||
argument to resolve database-specific values.
|
||||
=======
|
||||
>>>>>>> master:docs/releases/1.2.txt
|
||||
|
||||
.. _deprecated-features-1.2:
|
||||
|
||||
@ -338,6 +353,7 @@ replaces the deprecated user message API and allows you to temporarily store
|
||||
messages in one request and retrieve them for display in a subsequent request
|
||||
(usually the next one).
|
||||
|
||||
<<<<<<< HEAD:docs/releases/1.2.txt
|
||||
Support for multiple databases
|
||||
------------------------------
|
||||
|
||||
@ -346,3 +362,38 @@ Django 1.2 adds the ability to use :ref:`more than one database
|
||||
issued at a specific database with the `using()` method on
|
||||
querysets; individual objects can be saved to a specific database
|
||||
by providing a ``using`` argument when you save the instance.
|
||||
=======
|
||||
'Smart' if tag
|
||||
--------------
|
||||
|
||||
The :ttag:`if` tag has been upgraded to be much more powerful. First, support
|
||||
for comparison operators has been added. No longer will you have to type:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
{% ifnotequal a b %}
|
||||
...
|
||||
{% endifnotequal %}
|
||||
|
||||
...as you can now do:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
{% if a != b %}
|
||||
...
|
||||
{% endif %}
|
||||
|
||||
The operators supported are ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=`` and
|
||||
``in``, all of which work like the Python operators, in addition to ``and``,
|
||||
``or`` and ``not`` which were already supported.
|
||||
|
||||
Also, filters may now be used in the ``if`` expression. For example:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
<div
|
||||
{% if user.email|lower == message.recipient|lower %}
|
||||
class="highlight"
|
||||
{% endif %}
|
||||
>{{ message }}</div>
|
||||
>>>>>>> master:docs/releases/1.2.txt
|
||||
|
@ -202,28 +202,51 @@ Methods
|
||||
:meth:`~django.contrib.auth.models.User.set_unusable_password()` has
|
||||
been called for this user.
|
||||
|
||||
.. method:: models.User.get_group_permissions()
|
||||
.. method:: models.User.get_group_permissions(obj=None)
|
||||
|
||||
Returns a list of permission strings that the user has, through his/her
|
||||
groups.
|
||||
|
||||
.. method:: models.User.get_all_permissions()
|
||||
.. versionadded:: 1.2
|
||||
|
||||
If ``obj`` is passed in, only returns the group permissions for
|
||||
this specific object.
|
||||
|
||||
.. method:: models.User.get_all_permissions(obj=None)
|
||||
|
||||
Returns a list of permission strings that the user has, both through
|
||||
group and user permissions.
|
||||
|
||||
.. method:: models.User.has_perm(perm)
|
||||
.. versionadded:: 1.2
|
||||
|
||||
If ``obj`` is passed in, only returns the permissions for this
|
||||
specific object.
|
||||
|
||||
.. method:: models.User.has_perm(perm, obj=None)
|
||||
|
||||
Returns ``True`` if the user has the specified permission, where perm is
|
||||
in the format ``"<app label>.<permission codename>"``.
|
||||
If the user is inactive, this method will always return ``False``.
|
||||
|
||||
.. method:: models.User.has_perms(perm_list)
|
||||
.. versionadded:: 1.2
|
||||
|
||||
If ``obj`` is passed in, this method won't check for a permission for
|
||||
the model, but for this specific object.
|
||||
|
||||
.. method:: models.User.has_perms(perm_list, obj=None)
|
||||
|
||||
Returns ``True`` if the user has each of the specified permissions,
|
||||
where each perm is in the format
|
||||
``"<app label>.<permission codename>"``. If the user is inactive,
|
||||
this method will always return ``False``.
|
||||
<<<<<<< HEAD:docs/topics/auth.txt
|
||||
=======
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
If ``obj`` is passed in, this method won't check for permissions for
|
||||
the model, but for the specific object.
|
||||
>>>>>>> master:docs/topics/auth.txt
|
||||
|
||||
.. method:: models.User.has_module_perms(package_name)
|
||||
|
||||
@ -1521,3 +1544,24 @@ A full authorization implementation can be found in
|
||||
the ``auth_permission`` table most of the time.
|
||||
|
||||
.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py
|
||||
|
||||
Handling object permissions
|
||||
---------------------------
|
||||
|
||||
Django's permission framework has a foundation for object permissions, though
|
||||
there is no implementation for it in the core. That means that checking for
|
||||
object permissions will always return ``False`` or an empty list (depending on
|
||||
the check performed).
|
||||
|
||||
To enable object permissions in your own
|
||||
:ref:`authentication backend <ref-authentication-backends>` you'll just have
|
||||
to allow passing an ``obj`` parameter to the permission methods and set the
|
||||
``supports_objects_permissions`` class attribute to ``True``.
|
||||
|
||||
A nonexistent ``supports_objects_permissions`` will raise a hidden
|
||||
``PendingDeprecationWarning`` if used in Django 1.2. In Django 1.3, this
|
||||
warning will be upgraded to a ``DeprecationWarning``, which will be displayed
|
||||
loudly. Additionally ``supports_objects_permissions`` will be set to ``False``.
|
||||
Django 1.4 will assume that every backend supports object permissions and
|
||||
won't check for the existence of ``supports_objects_permissions``, which
|
||||
means not supporting ``obj`` as a parameter will raise a ``TypeError``.
|
||||
|
@ -187,8 +187,8 @@ tags:
|
||||
<li>{{ athlete.name }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
:ttag:`if` and :ttag:`else`
|
||||
|
||||
:ttag:`if` and ``else``
|
||||
Evaluates a variable, and if that variable is "true" the contents of the
|
||||
block are displayed::
|
||||
|
||||
@ -200,20 +200,15 @@ tags:
|
||||
|
||||
In the above, if ``athlete_list`` is not empty, the number of athletes
|
||||
will be displayed by the ``{{ athlete_list|length }}`` variable.
|
||||
|
||||
:ttag:`ifequal` and :ttag:`ifnotequal`
|
||||
Display some contents if two arguments are or are not equal. For example::
|
||||
|
||||
{% ifequal athlete.name coach.name %}
|
||||
...
|
||||
{% endifequal %}
|
||||
You can also use filters and various operators in the ``if`` tag::
|
||||
|
||||
Or::
|
||||
{% if athlete_list|length > 1 %}
|
||||
Team: {% for athlete in athlete_list %} ... {% endfor %}
|
||||
{% else %}
|
||||
Athlete: {{ athlete_list.0.name }}
|
||||
{% endif %}
|
||||
|
||||
{% ifnotequal athlete.name "Joe" %}
|
||||
...
|
||||
{% endifnotequal %}
|
||||
|
||||
:ttag:`block` and :ttag:`extends`
|
||||
Set up `template inheritance`_ (see below), a powerful way
|
||||
of cutting down on "boilerplate" in templates.
|
||||
|
@ -610,6 +610,12 @@ class AdminViewStringPrimaryKeyTest(TestCase):
|
||||
def tearDown(self):
|
||||
self.client.logout()
|
||||
|
||||
def test_get_history_view(self):
|
||||
"Retrieving the history for the object using urlencoded form of primary key should work"
|
||||
response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/history/' % quote(self.pk))
|
||||
self.assertContains(response, escape(self.pk))
|
||||
self.failUnlessEqual(response.status_code, 200)
|
||||
|
||||
def test_get_change_view(self):
|
||||
"Retrieving the object using urlencoded form of primary key should work"
|
||||
response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(self.pk))
|
||||
|
@ -1,78 +0,0 @@
|
||||
try:
|
||||
set
|
||||
except NameError:
|
||||
from sets import Set as set # Python 2.3 fallback
|
||||
|
||||
__test__ = {'API_TESTS': """
|
||||
>>> from django.contrib.auth.models import User, Group, Permission, AnonymousUser
|
||||
>>> from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
# No Permissions assigned yet, should return False except for superuser
|
||||
|
||||
>>> user = User.objects.create_user('test', 'test@example.com', 'test')
|
||||
>>> user.has_perm("auth.test")
|
||||
False
|
||||
>>> user.is_staff=True
|
||||
>>> user.save()
|
||||
>>> user.has_perm("auth.test")
|
||||
False
|
||||
>>> user.is_superuser=True
|
||||
>>> user.save()
|
||||
>>> user.has_perm("auth.test")
|
||||
True
|
||||
>>> user.is_staff = False
|
||||
>>> user.is_superuser = False
|
||||
>>> user.save()
|
||||
>>> user.has_perm("auth.test")
|
||||
False
|
||||
>>> content_type=ContentType.objects.get_for_model(Group)
|
||||
>>> perm = Permission.objects.create(name="test", content_type=content_type, codename="test")
|
||||
>>> user.user_permissions.add(perm)
|
||||
>>> user.save()
|
||||
|
||||
# reloading user to purge the _perm_cache
|
||||
|
||||
>>> user = User.objects.get(username="test")
|
||||
>>> user.get_all_permissions() == set([u'auth.test'])
|
||||
True
|
||||
>>> user.get_group_permissions() == set([])
|
||||
True
|
||||
>>> user.has_module_perms("Group")
|
||||
False
|
||||
>>> user.has_module_perms("auth")
|
||||
True
|
||||
>>> perm = Permission.objects.create(name="test2", content_type=content_type, codename="test2")
|
||||
>>> user.user_permissions.add(perm)
|
||||
>>> user.save()
|
||||
>>> perm = Permission.objects.create(name="test3", content_type=content_type, codename="test3")
|
||||
>>> user.user_permissions.add(perm)
|
||||
>>> user.save()
|
||||
>>> user = User.objects.get(username="test")
|
||||
>>> user.get_all_permissions() == set([u'auth.test2', u'auth.test', u'auth.test3'])
|
||||
True
|
||||
>>> user.has_perm('test')
|
||||
False
|
||||
>>> user.has_perm('auth.test')
|
||||
True
|
||||
>>> user.has_perms(['auth.test2', 'auth.test3'])
|
||||
True
|
||||
>>> perm = Permission.objects.create(name="test_group", content_type=content_type, codename="test_group")
|
||||
>>> group = Group.objects.create(name='test_group')
|
||||
>>> group.permissions.add(perm)
|
||||
>>> group.save()
|
||||
>>> user.groups.add(group)
|
||||
>>> user = User.objects.get(username="test")
|
||||
>>> exp = set([u'auth.test2', u'auth.test', u'auth.test3', u'auth.test_group'])
|
||||
>>> user.get_all_permissions() == exp
|
||||
True
|
||||
>>> user.get_group_permissions() == set([u'auth.test_group'])
|
||||
True
|
||||
>>> user.has_perms(['auth.test3', 'auth.test_group'])
|
||||
True
|
||||
|
||||
>>> user = AnonymousUser()
|
||||
>>> user.has_perm('test')
|
||||
False
|
||||
>>> user.has_perms(['auth.test2', 'auth.test3'])
|
||||
False
|
||||
"""}
|
@ -1,7 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Unit and doctests for specific database backends.
|
||||
import unittest
|
||||
<<<<<<< HEAD:tests/regressiontests/backends/tests.py
|
||||
from django.db import backend, connection, DEFAULT_DB_ALIAS
|
||||
=======
|
||||
from django.db import backend, connection
|
||||
>>>>>>> master:tests/regressiontests/backends/tests.py
|
||||
from django.db.backends.signals import connection_created
|
||||
from django.conf import settings
|
||||
|
||||
@ -10,7 +14,11 @@ class Callproc(unittest.TestCase):
|
||||
def test_dbms_session(self):
|
||||
# If the backend is Oracle, test that we can call a standard
|
||||
# stored procedure through our cursor wrapper.
|
||||
<<<<<<< HEAD:tests/regressiontests/backends/tests.py
|
||||
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
|
||||
=======
|
||||
if settings.DATABASE_ENGINE == 'oracle':
|
||||
>>>>>>> master:tests/regressiontests/backends/tests.py
|
||||
convert_unicode = backend.convert_unicode
|
||||
cursor = connection.cursor()
|
||||
cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'),
|
||||
@ -24,7 +32,11 @@ class LongString(unittest.TestCase):
|
||||
def test_long_string(self):
|
||||
# If the backend is Oracle, test that we can save a text longer
|
||||
# than 4000 chars and read it properly
|
||||
<<<<<<< HEAD:tests/regressiontests/backends/tests.py
|
||||
if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == 'django.db.backends.oracle':
|
||||
=======
|
||||
if settings.DATABASE_ENGINE == 'oracle':
|
||||
>>>>>>> master:tests/regressiontests/backends/tests.py
|
||||
c = connection.cursor()
|
||||
c.execute('CREATE TABLE ltext ("TEXT" NCLOB)')
|
||||
long_str = ''.join([unicode(x) for x in xrange(4000)])
|
||||
|
46
tests/regressiontests/templates/smartif.py
Normal file
46
tests/regressiontests/templates/smartif.py
Normal file
@ -0,0 +1,46 @@
|
||||
import unittest
|
||||
from django.template.smartif import IfParser, Literal
|
||||
|
||||
class SmartIfTests(unittest.TestCase):
|
||||
|
||||
def assertCalcEqual(self, expected, tokens):
|
||||
self.assertEqual(expected, IfParser(tokens).parse().eval({}))
|
||||
|
||||
# We only test things here that are difficult to test elsewhere
|
||||
# Many other tests are found in the main tests for builtin template tags
|
||||
# Test parsing via the printed parse tree
|
||||
def test_not(self):
|
||||
var = IfParser(["not", False]).parse()
|
||||
self.assertEqual("(not (literal False))", repr(var))
|
||||
self.assert_(var.eval({}))
|
||||
|
||||
self.assertFalse(IfParser(["not", True]).parse().eval({}))
|
||||
|
||||
def test_or(self):
|
||||
var = IfParser([True, "or", False]).parse()
|
||||
self.assertEqual("(or (literal True) (literal False))", repr(var))
|
||||
self.assert_(var.eval({}))
|
||||
|
||||
def test_in(self):
|
||||
list_ = [1,2,3]
|
||||
self.assertCalcEqual(True, [1, 'in', list_])
|
||||
self.assertCalcEqual(False, [1, 'in', None])
|
||||
self.assertCalcEqual(False, [None, 'in', list_])
|
||||
|
||||
def test_precedence(self):
|
||||
# (False and False) or True == True <- we want this one, like Python
|
||||
# False and (False or True) == False
|
||||
self.assertCalcEqual(True, [False, 'and', False, 'or', True])
|
||||
|
||||
# True or (False and False) == True <- we want this one, like Python
|
||||
# (True or False) and False == False
|
||||
self.assertCalcEqual(True, [True, 'or', False, 'and', False])
|
||||
|
||||
# (1 or 1) == 2 -> False
|
||||
# 1 or (1 == 2) -> True <- we want this one
|
||||
self.assertCalcEqual(True, [1, 'or', 1, '==', 2])
|
||||
|
||||
self.assertCalcEqual(True, [True, '==', True, 'or', True, '==', False])
|
||||
|
||||
self.assertEqual("(or (and (== (literal 1) (literal 2)) (literal 3)) (literal 4))",
|
||||
repr(IfParser([1, '==', 2, 'and', 3, 'or', 4]).parse()))
|
@ -24,6 +24,7 @@ from context import context_tests
|
||||
from custom import custom_filters
|
||||
from parser import filter_parsing, variable_parsing
|
||||
from unicode import unicode_tests
|
||||
from smartif import *
|
||||
|
||||
try:
|
||||
from loaders import *
|
||||
@ -534,6 +535,27 @@ class Templates(unittest.TestCase):
|
||||
'if-tag02': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": False}, "no"),
|
||||
'if-tag03': ("{% if foo %}yes{% else %}no{% endif %}", {}, "no"),
|
||||
|
||||
# Filters
|
||||
'if-tag-filter01': ("{% if foo|length == 5 %}yes{% else %}no{% endif %}", {'foo': 'abcde'}, "yes"),
|
||||
'if-tag-filter02': ("{% if foo|upper == 'ABC' %}yes{% else %}no{% endif %}", {}, "no"),
|
||||
|
||||
# Equality
|
||||
'if-tag-eq01': ("{% if foo == bar %}yes{% else %}no{% endif %}", {}, "yes"),
|
||||
'if-tag-eq02': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1}, "no"),
|
||||
'if-tag-eq03': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1, 'bar': 1}, "yes"),
|
||||
'if-tag-eq04': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1, 'bar': 2}, "no"),
|
||||
'if-tag-eq05': ("{% if foo == '' %}yes{% else %}no{% endif %}", {}, "no"),
|
||||
|
||||
# Comparison
|
||||
'if-tag-gt-01': ("{% if 2 > 1 %}yes{% else %}no{% endif %}", {}, "yes"),
|
||||
'if-tag-gt-02': ("{% if 1 > 1 %}yes{% else %}no{% endif %}", {}, "no"),
|
||||
'if-tag-gte-01': ("{% if 1 >= 1 %}yes{% else %}no{% endif %}", {}, "yes"),
|
||||
'if-tag-gte-02': ("{% if 1 >= 2 %}yes{% else %}no{% endif %}", {}, "no"),
|
||||
'if-tag-lt-01': ("{% if 1 < 2 %}yes{% else %}no{% endif %}", {}, "yes"),
|
||||
'if-tag-lt-02': ("{% if 1 < 1 %}yes{% else %}no{% endif %}", {}, "no"),
|
||||
'if-tag-lte-01': ("{% if 1 <= 1 %}yes{% else %}no{% endif %}", {}, "yes"),
|
||||
'if-tag-lte-02': ("{% if 2 <= 1 %}yes{% else %}no{% endif %}", {}, "no"),
|
||||
|
||||
# AND
|
||||
'if-tag-and01': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'),
|
||||
'if-tag-and02': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'),
|
||||
@ -554,14 +576,13 @@ class Templates(unittest.TestCase):
|
||||
'if-tag-or07': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True}, 'yes'),
|
||||
'if-tag-or08': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': True}, 'yes'),
|
||||
|
||||
# TODO: multiple ORs
|
||||
# multiple ORs
|
||||
'if-tag-or09': ("{% if foo or bar or baz %}yes{% else %}no{% endif %}", {'baz': True}, 'yes'),
|
||||
|
||||
# NOT
|
||||
'if-tag-not01': ("{% if not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'yes'),
|
||||
'if-tag-not02': ("{% if not %}yes{% else %}no{% endif %}", {'foo': True}, 'no'),
|
||||
'if-tag-not03': ("{% if not %}yes{% else %}no{% endif %}", {'not': True}, 'yes'),
|
||||
'if-tag-not04': ("{% if not not %}no{% else %}yes{% endif %}", {'not': True}, 'yes'),
|
||||
'if-tag-not05': ("{% if not not %}no{% else %}yes{% endif %}", {}, 'no'),
|
||||
'if-tag-not02': ("{% if not not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'no'),
|
||||
# not03 to not05 removed, now TemplateSyntaxErrors
|
||||
|
||||
'if-tag-not06': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {}, 'no'),
|
||||
'if-tag-not07': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'),
|
||||
@ -599,12 +620,21 @@ class Templates(unittest.TestCase):
|
||||
'if-tag-not34': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'),
|
||||
'if-tag-not35': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'),
|
||||
|
||||
# AND and OR raises a TemplateSyntaxError
|
||||
'if-tag-error01': ("{% if foo or bar and baz %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, template.TemplateSyntaxError),
|
||||
# Various syntax errors
|
||||
'if-tag-error01': ("{% if %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
'if-tag-error02': ("{% if foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
|
||||
'if-tag-error03': ("{% if foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
|
||||
'if-tag-error04': ("{% if not foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
|
||||
'if-tag-error05': ("{% if not foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
|
||||
'if-tag-error06': ("{% if abc def %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
'if-tag-error07': ("{% if not %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
'if-tag-error08': ("{% if and %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
'if-tag-error09': ("{% if or %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
'if-tag-error10': ("{% if == %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
'if-tag-error11': ("{% if 1 == %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
'if-tag-error12': ("{% if a not b %}yes{% endif %}", {}, template.TemplateSyntaxError),
|
||||
|
||||
# Additional, more precise parsing tests are in SmartIfTests
|
||||
|
||||
### IFCHANGED TAG #########################################################
|
||||
'ifchanged01': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', {'num': (1,2,3)}, '123'),
|
||||
|
Loading…
x
Reference in New Issue
Block a user