Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

gis: Merged revisions 7458,7471-7473,7476-7478,7480 via svnmerge from…

… trunk.

This includes all necessary patches for compatibility with queryset-refactor.


git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@7482 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e973fea91c4e5924f1d0d709b9c8f0d069380709 1 parent 5456919
@jbronn jbronn authored
Showing with 9,904 additions and 3,945 deletions.
  1. +2 −1  AUTHORS
  2. +6 −2 django/bin/make-messages.py
  3. BIN  django/conf/locale/ca/LC_MESSAGES/django.mo
  4. +170 −160 django/conf/locale/ca/LC_MESSAGES/django.po
  5. BIN  django/conf/locale/fr/LC_MESSAGES/django.mo
  6. +15 −5 django/conf/locale/fr/LC_MESSAGES/django.po
  7. BIN  django/conf/locale/ro/LC_MESSAGES/django.mo
  8. +3,722 −1,454 django/conf/locale/ro/LC_MESSAGES/django.po
  9. BIN  django/conf/locale/ro/LC_MESSAGES/djangojs.mo
  10. +30 −32 django/conf/locale/ro/LC_MESSAGES/djangojs.po
  11. BIN  django/conf/locale/ru/LC_MESSAGES/djangojs.mo
  12. +1 −1  django/conf/locale/ru/LC_MESSAGES/djangojs.po
  13. +7 −11 django/contrib/admin/views/main.py
  14. +5 −0 django/contrib/contenttypes/generic.py
  15. +29 −257 django/contrib/gis/db/backend/__init__.py
  16. +0 −2  django/contrib/gis/db/models/fields/__init__.py
  17. +184 −275 django/contrib/gis/db/models/query.py
  18. +2 −1  django/contrib/gis/tests/geoapp/tests.py
  19. +20 −8 django/contrib/gis/tests/geoapp/tests_mysql.py
  20. +5 −0 django/core/exceptions.py
  21. +9 −15 django/core/management/sql.py
  22. +18 −12 django/core/management/validation.py
  23. +1 −1  django/core/serializers/base.py
  24. +9 −5 django/db/__init__.py
  25. +33 −6 django/db/backends/__init__.py
  26. +5 −0 django/db/backends/mysql/base.py
  27. +5 −0 django/db/backends/mysql_old/base.py
  28. +37 −237 django/db/backends/oracle/base.py
  29. +151 −0 django/db/backends/oracle/query.py
  30. +3 −0  django/db/backends/postgresql/operations.py
  31. +3 −0  django/db/backends/sqlite3/base.py
  32. +238 −145 django/db/models/base.py
  33. +30 −13 django/db/models/fields/__init__.py
  34. +16 −0 django/db/models/fields/proxy.py
  35. +111 −144 django/db/models/fields/related.py
  36. +34 −6 django/db/models/manager.py
  37. +273 −45 django/db/models/options.py
  38. +471 −940 django/db/models/query.py
  39. +50 −0 django/db/models/query_utils.py
  40. +7 −0 django/db/models/sql/__init__.py
  41. +36 −0 django/db/models/sql/constants.py
  42. +103 −0 django/db/models/sql/datastructures.py
  43. +1,504 −0 django/db/models/sql/query.py
  44. +367 −0 django/db/models/sql/subqueries.py
  45. +171 −0 django/db/models/sql/where.py
  46. +134 −0 django/utils/tree.py
  47. +373 −65 docs/db-api.txt
  48. +271 −7 docs/model-api.txt
  49. +3 −5 tests/modeltests/basic/models.py
  50. +3 −3 tests/modeltests/custom_columns/models.py
  51. +3 −2 tests/modeltests/field_subclassing/models.py
  52. +29 −3 tests/modeltests/lookup/models.py
  53. +5 −0 tests/modeltests/many_to_many/models.py
  54. +11 −6 tests/modeltests/many_to_one/models.py
  55. +5 −0 tests/modeltests/many_to_one_null/models.py
  56. +226 −11 tests/modeltests/model_inheritance/models.py
  57. +34 −9 tests/modeltests/one_to_one/models.py
  58. +16 −5 tests/modeltests/or_lookups/models.py
  59. 0  tests/modeltests/order_with_respect_to/__init__.py
  60. +78 −0 tests/modeltests/order_with_respect_to/models.py
  61. +13 −0 tests/modeltests/ordering/models.py
  62. +0 −2  tests/modeltests/reserved_names/models.py
  63. +1 −1  tests/modeltests/reverse_lookup/models.py
  64. +42 −5 tests/modeltests/select_related/models.py
  65. +15 −14 tests/modeltests/serializers/models.py
  66. +2 −1  tests/modeltests/signals/models.py
  67. +1 −1  tests/modeltests/transactions/models.py
  68. 0  tests/modeltests/update/__init__.py
  69. +67 −0 tests/modeltests/update/models.py
  70. +10 −5 tests/regressiontests/null_queries/models.py
  71. 0  tests/regressiontests/queries/__init__.py
  72. +658 −0 tests/regressiontests/queries/models.py
  73. +13 −14 tests/regressiontests/serializers_regress/models.py
  74. +8 −8 tests/regressiontests/serializers_regress/tests.py
View
3  AUTHORS
@@ -104,6 +104,7 @@ answer newbie questions, and generally made Django that much better:
Jure Cuhalev <gandalf@owca.info>
John D'Agostino <john.dagostino@gmail.com>
dackze+django@gmail.com
+ Mihai Damian <yang_damian@yahoo.com>
David Danier <goliath.mailinglist@gmx.de>
Dirk Datzert <dummy@habmalnefrage.de>
Jonathan Daugherty (cygnus) <http://www.cprogrammer.org/>
@@ -347,7 +348,7 @@ answer newbie questions, and generally made Django that much better:
Zach Thompson <zthompson47@gmail.com>
Michael Thornhill
Deepak Thukral <deep.thukral@gmail.com>
- tibimicu@gmax.net
+ tibimicu@gmx.net
tobias@neuyork.de
Tom Tobin
Joe Topjian <http://joe.terrarum.net/geek/code/python/django/>
View
8 django/bin/make-messages.py
@@ -85,8 +85,7 @@ def make_messages():
src = pythonize_re.sub('\n#', src)
open(os.path.join(dirpath, '%s.py' % file), "wb").write(src)
thefile = '%s.py' % file
- cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
- os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
+ cmd = 'xgettext -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (domain, os.path.join(dirpath, thefile))
(stdin, stdout, stderr) = os.popen3(cmd, 't')
msgs = stdout.read()
errors = stderr.read()
@@ -97,6 +96,11 @@ def make_messages():
old = '#: '+os.path.join(dirpath, thefile)[2:]
new = '#: '+os.path.join(dirpath, file)[2:]
msgs = msgs.replace(old, new)
+ if os.path.exists(potfile):
+ # Strip the header
+ msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
+ else:
+ msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
if msgs:
open(potfile, 'ab').write(msgs)
os.unlink(os.path.join(dirpath, thefile))
View
BIN  django/conf/locale/ca/LC_MESSAGES/django.mo
Binary file not shown
View
330 django/conf/locale/ca/LC_MESSAGES/django.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-02-15 01:00+0200\n"
+"POT-Creation-Date: 2008-04-25 00:18+0200\n"
"PO-Revision-Date: 2008-03-29 01:37+0100\n"
"Last-Translator: Django Catalan Group <django-cat@googlegroups.com>\n"
"Language-Team: Catalan <ca@li.org>\n"
@@ -63,7 +63,6 @@ msgid "Argentinean Spanish"
msgstr "Castellà Argentí"
#: conf/global_settings.py:51
-#, fuzzy
msgid "Basque"
msgstr "Euskera"
@@ -152,8 +151,8 @@ msgid "Portugese"
msgstr "Portuguès"
#: conf/global_settings.py:73
-msgid "Brazilian"
-msgstr "Brasileny"
+msgid "Brazilian Portuguese"
+msgstr "Portuguès de Brasil"
#: conf/global_settings.py:74
msgid "Romanian"
@@ -401,8 +400,8 @@ msgid ""
"following types of objects:"
msgstr ""
"Eliminar el/la %(object_name)s '%(escaped_object)s' provocaria l'eliminació "
-"d'objectes relacionats, però el vostre compte no te permissos per a esborrar els "
-"tipus d'objecte següents:"
+"d'objectes relacionats, però el vostre compte no te permissos per a esborrar "
+"els tipus d'objecte següents:"
#: contrib/admin/templates/admin/delete_confirmation.html:20
#, python-format
@@ -410,7 +409,7 @@ msgid ""
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
"All of the following related items will be deleted:"
msgstr ""
-"Està segur de voler esborrar els/les %(object_name)s \"%(escaped_object)s\"? "
+"Esteu segurs de voler esborrar els/les %(object_name)s \"%(escaped_object)s\"? "
"S'esborraran els següents elements relacionats:"
#: contrib/admin/templates/admin/delete_confirmation.html:25
@@ -429,7 +428,7 @@ msgstr "Filtre"
#: contrib/admin/templates/admin/index.html:17
#, python-format
msgid "Models available in the %(name)s application."
-msgstr "Models disponibles en l'aplicació %(name)s."
+msgstr "Models disponibles a l'aplicació %(name)s."
#: contrib/admin/templates/admin/index.html:18
#, python-format
@@ -547,7 +546,7 @@ msgid ""
"First, enter a username and password. Then, you'll be able to edit more user "
"options."
msgstr ""
-"Primer, entri un usuari i una contrasenya. Després podrà editar més opcions "
+"Primer, entreu un usuari i una contrasenya. Després podreu editar més opcions "
"de l'usuari."
#: contrib/admin/templates/admin/auth/user/add_form.html:12
@@ -593,15 +592,15 @@ msgid ""
"your computer is \"internal\").</p>\n"
msgstr ""
"\n"
-"<p class=\"help\">Per a instal·lar 'bookmarklets', arrosegui l'enllaç a la "
+"<p class=\"help\">Per a instal·lar 'bookmarklets', arrosegueu l'enllaç a la "
"seva barra de\n"
-"marcadors, o faci click amb el botò dret en l'enllaç i afegeixi'l als "
+"marcadors, o feu click amb el botó dret en l'enllaç i afegeixi'l als "
"marcadors.\n"
-"Ara pot escollir el 'bookmarklet' des de qualsevol pàgina del lloc.\n"
-"Observi que alguns d'aquests 'bookmarklets' precisen que estigui veient\n"
-"el lloc des de un ordinador senyalat com a \"intern\" (parli\n"
-"amb el seu administrador de sistemes si no està segur de la condició del "
-"seu).</p>\n"
+"Ara podeu escollir el 'bookmarklet' des de qualsevol pàgina del lloc.\n"
+"Observeu que alguns d'aquests 'bookmarklets' precisen que estigui veient\n"
+"el lloc des de un ordinador senyalat com a \"intern\" (parleu\n"
+"amb el vostre administrador de sistemes si no esteu segurs de la condició del "
+"vostre).</p>\n"
#: contrib/admin/templates/admin_doc/bookmarklets.html:18
msgid "Documentation for this page"
@@ -612,7 +611,7 @@ msgid ""
"Jumps you from any page to the documentation for the view that generates "
"that page."
msgstr ""
-"El porta des de qualsevol pàgina de la documentació a la vista que la genera."
+"Us porta des de qualsevol pàgina de la documentació a la vista que la genera."
#: contrib/admin/templates/admin_doc/bookmarklets.html:21
msgid "Show object ID"
@@ -673,9 +672,9 @@ msgid ""
"Please enter your old password, for security's sake, and then enter your new "
"password twice so we can verify you typed it in correctly."
msgstr ""
-"Si us plau, introdueixi la seva contrasenya antiga, per seguretat, i tot "
-"seguit introdueixi la seva contrasenya nova dues vegades per verificar que "
-"l'ha escrit correctament."
+"Si us plau, introduïu la vostra contrasenya antiga, per seguretat, i tot "
+"seguit introduïu la vostra contrasenya nova dues vegades per verificar que "
+"l'heu escrit correctament."
#: contrib/admin/templates/registration/password_change_form.html:16
msgid "Old password:"
@@ -703,39 +702,39 @@ msgstr "Restablir contrasenya"
#: contrib/admin/templates/registration/password_reset_done.html:6
#: contrib/admin/templates/registration/password_reset_done.html:10
msgid "Password reset successful"
-msgstr "Restabliment de contrasenya exitòs"
+msgstr "Restabliment de contrasenya exitós"
#: contrib/admin/templates/registration/password_reset_done.html:12
msgid ""
"We've e-mailed a new password to the e-mail address you submitted. You "
"should be receiving it shortly."
msgstr ""
-"Li hem enviat una contrasenya nova a l'adreça de correu electrònic que ens "
-"ha indicat. L'hauria de rebre en breu."
+"Us hem enviat una contrasenya nova a l'adreça de correu electrònic que ens "
+"heu indicat. L'haurieu de rebre en breu."
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
msgstr ""
-"Està rebent aquest missatge degut a que va solicitar un restabliment de "
+"Esteu rebent aquest missatge degut a que veu solicitar un restabliment de "
"contrasenya."
#: contrib/admin/templates/registration/password_reset_email.html:3
#, python-format
msgid "for your user account at %(site_name)s"
-msgstr "del seu compte d'usuari a %(site_name)s."
+msgstr "del vostre compte d'usuari a %(site_name)s."
#: contrib/admin/templates/registration/password_reset_email.html:5
#, python-format
msgid "Your new password is: %(new_password)s"
-msgstr "La seva nova contrasenya és: %(new_password)s"
+msgstr "La vostra nova contrasenya és: %(new_password)s"
#: contrib/admin/templates/registration/password_reset_email.html:7
msgid "Feel free to change this password by going to this page:"
-msgstr "Sentis lliure de canviar-la en aquesta pàgina:"
+msgstr "Sentiu-vos lliures de canviar-la en aquesta pàgina:"
#: contrib/admin/templates/registration/password_reset_email.html:11
msgid "Your username, in case you've forgotten:"
-msgstr "El seu nom d'usuari, en cas d'haver-lo oblidat:"
+msgstr "El vostre nom d'usuari, en cas d'haver-lo oblidat:"
#: contrib/admin/templates/registration/password_reset_email.html:13
msgid "Thanks for using our site!"
@@ -751,8 +750,8 @@ msgid ""
"Forgotten your password? Enter your e-mail address below, and we'll reset "
"your password and e-mail the new one to you."
msgstr ""
-"Ha oblidat la seva contrasenya? Introdueixi la seva adreça de correu "
-"electrònic i en crearem una de nova que li enviarem per correu."
+"Heu oblidat la vostra contrasenya? Introduïu la vostra adreça de correu "
+"electrònic i en crearem una de nova que us enviarem per correu."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@@ -785,12 +784,12 @@ msgstr "Totes les dates"
#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
#, python-format
msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "El/la %(name)s \"%(obj)s\".ha estat agregat/da amb èxit."
+msgstr "El/la %(name)s \"%(obj)s\".ha estat afegit/da amb èxit."
#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:271
#: contrib/admin/views/main.py:356
msgid "You may edit it again below."
-msgstr "Pot editar-lo de nou a baix."
+msgstr "Podeu editar-lo de nou a baix."
#: contrib/admin/views/auth.py:31
msgid "Add user"
@@ -810,7 +809,7 @@ msgid ""
"Please enter a correct username and password. Note that both fields are case-"
"sensitive."
msgstr ""
-"Si us plau, introdueixi un nom d'usuari i contrasenya vàlids. Tingui en "
+"Si us plau, introduïu un nom d'usuari i contrasenya vàlids. Tingueu en "
"compte que tots dos camps son sensibles a majúscules i minúscules."
#: contrib/admin/views/decorators.py:69
@@ -818,17 +817,17 @@ msgid ""
"Please log in again, because your session has expired. Don't worry: Your "
"submission has been saved."
msgstr ""
-"Si us plau, identifiquis de nou doncs la seva sessió ha expirat. No es "
-"preocupi, el seu enviament està emmagatzemat."
+"Si us plau, identifiqueu-vos de nou doncs la vostra sessió ha expirat. No us "
+"preocupeu, el seu enviament està emmagatzemat."
#: contrib/admin/views/decorators.py:76
msgid ""
"Looks like your browser isn't configured to accept cookies. Please enable "
"cookies, reload this page, and try again."
msgstr ""
-"Sembla ser que el seu navegador no està configurat per acceptar "
-"'cookies' (galetes). Si us plau, habiliti les 'cookies', recarregui aquesta "
-"pàgina i provi-ho de nou. "
+"Sembla ser que el vostre navegador no està configurat per acceptar "
+"'cookies' (galetes). Si us plau, habiliteu les 'cookies', recarregueu aquesta "
+"pàgina i proveu-ho de nou. "
#: contrib/admin/views/decorators.py:90
msgid "Usernames cannot contain the '@' character."
@@ -838,7 +837,7 @@ msgstr "Els noms d'usuari no poden contenir el caracter '@'."
#, python-format
msgid "Your e-mail address is not your username. Try '%s' instead."
msgstr ""
-"La seva adreça de correu no és el seu nom d'usuari. Provi '%s' en tot cas."
+"La vostra adreça de correu no és el vostre nom d'usuari. Provi '%s' en tot cas."
#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
#: contrib/admin/views/doc.py:52
@@ -963,13 +962,13 @@ msgstr "Text"
msgid "Time"
msgstr "Hora"
-#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:7
+#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:8
msgid "URL"
msgstr "URL"
#: contrib/admin/views/doc.py:319
msgid "U.S. state (two uppercase letters)"
-msgstr "Estat dels E.U.A. (dos lletres majúscules)"
+msgstr "Estat dels E.U.A. (dues lletres majúscules)"
#: contrib/admin/views/doc.py:320
msgid "XML text"
@@ -987,7 +986,7 @@ msgstr "Lloc administratiu"
#: contrib/admin/views/main.py:280 contrib/admin/views/main.py:365
#, python-format
msgid "You may add another %s below."
-msgstr "Pot afegir un altre %s a baix."
+msgstr "Podeu afegir un altre %s a baix."
#: contrib/admin/views/main.py:298
#, python-format
@@ -1029,7 +1028,8 @@ msgstr "S'ha modificat amb èxit el/la %(name)s \"%(obj)s."
msgid ""
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
msgstr ""
-"S'ha agregat exitosament el/la %(name)s \"%(obj)s\". Pot editar-lo de nou abaix."
+"S'ha afegit exitosament el/la %(name)s \"%(obj)s\". Pot editar-lo de nou "
+"abaix."
#: contrib/admin/views/main.py:400
#, python-format
@@ -1063,12 +1063,12 @@ msgstr "Modificar històric: %s"
#: contrib/admin/views/main.py:583
#, python-format
msgid "Select %s"
-msgstr "Seleccioni %s"
+msgstr "Seleccioneu %s"
#: contrib/admin/views/main.py:583
#, python-format
msgid "Select %s to change"
-msgstr "Seleccioni %s per modificar"
+msgstr "Seleccioneu %s per modificar"
#: contrib/admin/views/main.py:784
msgid "Database error"
@@ -1099,7 +1099,7 @@ msgid ""
"That e-mail address doesn't have an associated user account. Are you sure "
"you've registered?"
msgstr ""
-"Aquesta adreça de correu no té associada cap compte d'usuari. Està segur de "
+"Aquesta adreça de correu no té associada cap compte d'usuari. Esteu segurs de "
"que s'ha registrat?"
#: contrib/auth/forms.py:107
@@ -1114,7 +1114,7 @@ msgstr "Els dos camps de nova contrasenya no coincideixen."
#: contrib/auth/forms.py:124
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr ""
-"La seva antiga contrasenya no és correcte. Si el plau, introdueixi-la de nou."
+"La seva antiga contrasenya no és correcte. Si el plau, introduïu-la de nou."
#: contrib/auth/models.py:73 contrib/auth/models.py:93
msgid "name"
@@ -1173,7 +1173,7 @@ msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
msgstr ""
-"Utilitzi '[algo]$[salt]$[hexdigest]' o el <a href=\"password/\">formulari de "
+"Utilitzeu '[algo]$[salt]$[hexdigest]' o el <a href=\"password/\">formulari de "
"canvi de contrasenya</a>."
#: contrib/auth/models.py:136
@@ -1189,12 +1189,13 @@ msgid "active"
msgstr "actiu"
#: contrib/auth/models.py:137
+#, fuzzy
msgid ""
-"Designates whether this user can log into the Django admin. Unselect this "
+"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
msgstr ""
-"Designa si aquest usuari pot iniciar sessió a la interfície administrativa "
-"Django. Deseleccioni-ho enlloc d'esborrar comptes d'usuari."
+"Designa si aquest usuari ha de ser tractat com a actiu. Desekeccioneu-ho "
+"enlloc d'esborrar comptes d'usuari."
#: contrib/auth/models.py:138
msgid "superuser status"
@@ -1242,7 +1243,7 @@ msgstr "Informació personal"
#: contrib/auth/models.py:155
msgid "Permissions"
-msgstr "permissos"
+msgstr "permisos"
#: contrib/auth/models.py:156
msgid "Important dates"
@@ -1326,7 +1327,7 @@ msgid ""
"Check this box if the comment is inappropriate. A \"This comment has been "
"removed\" message will be displayed instead."
msgstr ""
-"Marqui aquesta caixa si el comentari no és apropiat. En lloc seu es mostrarà "
+"Marqueu aquesta caixa si el comentari no és apropiat. En lloc seu es mostrarà "
"\"Aquest comentari ha estat eliminat\" "
#: contrib/comments/models.py:96
@@ -1477,7 +1478,7 @@ msgstr "El seu nom:"
#: contrib/comments/views/comments.py:28
msgid ""
"This rating is required because you've entered at least one other rating."
-msgstr "Es precisa aquesta puntuació perquè has introduït almenys un altre."
+msgstr "Es precisa aquesta puntuació perquè n'heu introduït almenys una altra."
#: contrib/comments/views/comments.py:112
#, python-format
@@ -1492,13 +1493,13 @@ msgid_plural ""
"\n"
"%(text)s"
msgstr[0] ""
-"Aquest comentari va ser enviat per un usuari que ha enviat menys de %"
-"(count)s comentari:\n"
+"Aquest comentari va ser enviat per un usuari que ha enviat menys de %(count)"
+"s comentari:\n"
"\n"
"%(text)s"
msgstr[1] ""
-"Aquest comentari va ser enviat per un usuari que ha enviat menys de %"
-"(count)s comentaris:\n"
+"Aquest comentari va ser enviat per un usuari que ha enviat menys de %(count)"
+"s comentaris:\n"
"\n"
"%(text)s"
@@ -1553,7 +1554,7 @@ msgstr "ID del comentari invàlid"
#: contrib/comments/views/karma.py:27
msgid "No voting for yourself"
-msgstr "No pots votar-te a tu mateix"
+msgstr "No podeu votar-vos a vosaltres mateixos"
#: contrib/contenttypes/models.py:67
msgid "python model class name"
@@ -1567,30 +1568,30 @@ msgstr "tipus de contingut"
msgid "content types"
msgstr "tipus de continguts"
-#: contrib/flatpages/models.py:8
+#: contrib/flatpages/models.py:9
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""
-"Exemple: '/about/contact/'. Asseguri's de posar les barres al principi i al "
+"Exemple: '/about/contact/'. Assegureu-vos de posar les barres al principi i al "
"final."
-#: contrib/flatpages/models.py:9
+#: contrib/flatpages/models.py:10
msgid "title"
msgstr "títol"
-#: contrib/flatpages/models.py:10
+#: contrib/flatpages/models.py:11
msgid "content"
msgstr "contingut"
-#: contrib/flatpages/models.py:11
+#: contrib/flatpages/models.py:12
msgid "enable comments"
msgstr "habilitar comentaris"
-#: contrib/flatpages/models.py:12
+#: contrib/flatpages/models.py:13
msgid "template name"
msgstr "nom de la plantilla"
-#: contrib/flatpages/models.py:13
+#: contrib/flatpages/models.py:14
msgid ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
@@ -1598,22 +1599,26 @@ msgstr ""
"Exemple: 'flatpages/contact_page.html'. Si no es proporciona, el sistema "
"utilitzarà 'flatpages/default.htmlt'."
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "registration required"
msgstr "cal estar registrat"
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "If this is checked, only logged-in users will be able to view the page."
msgstr "Si està marcat, només els usuaris registrats podran veure la pàgina."
-#: contrib/flatpages/models.py:18
+#: contrib/flatpages/models.py:20
msgid "flat page"
msgstr "pàgina estàtica"
-#: contrib/flatpages/models.py:19
+#: contrib/flatpages/models.py:21
msgid "flat pages"
msgstr "pàgines estàtiques"
+#: contrib/flatpages/models.py:27
+msgid "Advanced options"
+msgstr ""
+
#: contrib/humanize/templatetags/humanize.py:19
msgid "th"
msgstr "rt"
@@ -1701,7 +1706,7 @@ msgstr "ahir"
#: contrib/localflavor/ar/forms.py:27
msgid "Enter a postal code in the format NNNN or ANNNNAAA."
-msgstr "Introdueixi un codi postal en el format NNNN o ANNNNAAA."
+msgstr "Introduïu un codi postal en el format NNNN o ANNNNAAA."
#: contrib/localflavor/ar/forms.py:49 contrib/localflavor/br/forms.py:96
#: contrib/localflavor/br/forms.py:135 contrib/localflavor/pe/forms.py:23
@@ -1716,7 +1721,7 @@ msgstr "Aquest camp precisa 7 o 8 dígits."
#: contrib/localflavor/ar/forms.py:79
msgid "Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format."
msgstr ""
-"Introdueixi un número CUIT vàlid en el format XX-XXXXXXXX-X o XXXXXXXXXXXX."
+"Introduïu un número CUIT vàlid en el format XX-XXXXXXXX-X o XXXXXXXXXXXX."
#: contrib/localflavor/ar/forms.py:80
msgid "Invalid CUIT."
@@ -1724,11 +1729,11 @@ msgstr "Invàlid CUIT."
#: contrib/localflavor/au/forms.py:16
msgid "Enter a 4 digit post code."
-msgstr "Introdueixi un codi postal de 4 dígits."
+msgstr "Introduïu un codi postal de 4 dígits."
#: contrib/localflavor/br/forms.py:21
msgid "Enter a zip code in the format XXXXX-XXX."
-msgstr "Introdueixi un codi zip en el format XXXXX-XXX."
+msgstr "Introduïu un codi zip en el format XXXXX-XXX."
#: contrib/localflavor/br/forms.py:30
msgid "Phone numbers must be in XX-XXXX-XXXX format."
@@ -1739,7 +1744,7 @@ msgid ""
"Select a valid brazilian state. That state is not one of the available "
"states."
msgstr ""
-"Seleccioni un estat brasiler vàlid. Aquest estat no és un dels estats "
+"Seleccioneu un estat brasiler vàlid. Aquest estat no és un dels estats "
"disponibles."
#: contrib/localflavor/br/forms.py:94
@@ -1760,12 +1765,12 @@ msgstr "Aquest camp precisa almenys 14 dígits."
#: contrib/localflavor/ca/forms.py:17
msgid "Enter a postal code in the format XXX XXX."
-msgstr "Introdueixi un codi postal en el format XXX XXX."
+msgstr "Introduïu un codi postal en el format XXX XXX."
#: contrib/localflavor/ca/forms.py:88
msgid "Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format."
msgstr ""
-"Introdueixi un número vàlid de la Assegurança Social de Canadà en el format "
+"Introduïu un número vàlid de la Assegurança Social de Canadà en el format "
"XXX-XXX-XXX."
#: contrib/localflavor/ch/ch_states.py:5
@@ -1874,23 +1879,23 @@ msgstr "Zuric"
#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
msgid "Enter a zip code in the format XXXX."
-msgstr "Introdueixi un codi zip en el format XXXX."
+msgstr "Introduïu un codi zip en el format XXXX."
#: contrib/localflavor/ch/forms.py:64
msgid ""
"Enter a valid Swiss identity or passport card number in X1234567<0 or "
"1234567890 format."
msgstr ""
-"Introdueixi un número d'identificació o de passaport Suïssos en els formats "
+"Introduïu un número d'identificació o de passaport Suïssos en els formats "
"1234567890 o X1234567<0."
#: contrib/localflavor/cl/forms.py:29
msgid "Enter a valid Chilean RUT."
-msgstr "Introdueixi un RUT Xilè vàlid."
+msgstr "Introduïu un RUT Xilè vàlid."
#: contrib/localflavor/cl/forms.py:30
msgid "Enter a valid Chilean RUT. The format is XX.XXX.XXX-X."
-msgstr "Introdueixi un RUT Xilè vàlid. El format és XX.XXX.XXX-X"
+msgstr "Introduïu un RUT Xilè vàlid. El format és XX.XXX.XXX-X"
#: contrib/localflavor/cl/forms.py:31
msgid "The Chilean RUT is not valid."
@@ -1963,14 +1968,14 @@ msgstr "Turíngia"
#: contrib/localflavor/de/forms.py:14 contrib/localflavor/fi/forms.py:12
#: contrib/localflavor/fr/forms.py:15
msgid "Enter a zip code in the format XXXXX."
-msgstr "Introdueixi un codi zip en el format XXXXX."
+msgstr "Introduïu un codi zip en el format XXXXX."
#: contrib/localflavor/de/forms.py:41
msgid ""
"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
"format."
msgstr ""
-"Introdueixi un número de tarjeta d'identificació alemany vàlid en el format "
+"Introduïu un número de tarjeta d'identificació alemany vàlid en el format "
"XXXXXXXXXXX-XXXXXXX-XXXXXXX-X."
#: contrib/localflavor/es/es_provinces.py:5
@@ -2242,23 +2247,23 @@ msgstr "Comunitat Valenciana"
#: contrib/localflavor/es/forms.py:19
msgid "Enter a valid postal code in the range and format 01XXX - 52XXX."
-msgstr "Introdueixi un codi postal en rang i format 01XXX - 52XXX."
+msgstr "Introduïu un codi postal en rang i format 01XXX - 52XXX."
#: contrib/localflavor/es/forms.py:39
msgid ""
"Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or "
"9XXXXXXXX."
msgstr ""
-"Introdueixi un número de telèfon vàlid en un dels formats 6XXXXXXXX, "
+"Introduïu un número de telèfon vàlid en un dels formats 6XXXXXXXX, "
"8XXXXXXXX o 9XXXXXXXX."
#: contrib/localflavor/es/forms.py:66
msgid "Please enter a valid NIF, NIE, or CIF."
-msgstr "Si us plau, introdueixi un NIF, NIE o CIF vàlid."
+msgstr "Si us plau, introduïu un NIF, NIE o CIF vàlid."
#: contrib/localflavor/es/forms.py:67
msgid "Please enter a valid NIF or NIE."
-msgstr "Si us plau, introdueixi un NIF o NIE vàlid."
+msgstr "Si us plau, introduïu un NIF o NIE vàlid."
#: contrib/localflavor/es/forms.py:68
msgid "Invalid checksum for NIF."
@@ -2276,7 +2281,7 @@ msgstr "Validació invàlida del CIF."
msgid ""
"Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
msgstr ""
-"Introdueixi un número de compte bancari vàlid en el format XXXX-XXXX-XX-"
+"Introduïu un número de compte bancari vàlid en el format XXXX-XXXX-XX-"
"XXXXXXXXXX."
#: contrib/localflavor/es/forms.py:143
@@ -2285,17 +2290,17 @@ msgstr "Validació invàlida del número de compte bancari."
#: contrib/localflavor/fi/forms.py:28
msgid "Enter a valid Finnish social security number."
-msgstr "Introdueixi un número vàlid de la seguretat social finlandesa."
+msgstr "Introduïu un número vàlid de la seguretat social finlandesa."
#: contrib/localflavor/in_/forms.py:14
msgid "Enter a zip code in the format XXXXXXX."
-msgstr "Introdueixi un codi zip en el format XXXXXXX."
+msgstr "Introduïu un codi zip en el format XXXXXXX."
#: contrib/localflavor/is_/forms.py:17
msgid ""
"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
msgstr ""
-"Introdueixi un número de identificació d'Islàndia. El format és XXXXXX-XXXX."
+"Introduïu un número de identificació d'Islàndia. El format és XXXXXX-XXXX."
#: contrib/localflavor/is_/forms.py:18
msgid "The Icelandic identification number is not valid."
@@ -2303,19 +2308,19 @@ msgstr "El número de identificació d'Islàndia no és vàlid."
#: contrib/localflavor/it/forms.py:14
msgid "Enter a valid zip code."
-msgstr "Introdueixi un codi zip vàlid."
+msgstr "Introduïu un codi zip vàlid."
#: contrib/localflavor/it/forms.py:43
msgid "Enter a valid Social Security number."
-msgstr "Introdueixi un número valid de la Seguretat Social."
+msgstr "Introduïu un número valid de la Seguretat Social."
#: contrib/localflavor/it/forms.py:68
msgid "Enter a valid VAT number."
-msgstr "Introdueixi un número de IVA (VAT) vàlid."
+msgstr "Introduïu un número de IVA (VAT) vàlid."
#: contrib/localflavor/jp/forms.py:17
msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
-msgstr "Introdueixi un codi postal en el format XXXXXXX o XX-XXXX."
+msgstr "Introduïu un codi postal en el format XXXXXXX o XX-XXXX."
#: contrib/localflavor/jp/jp_prefectures.py:4
msgid "Hokkaido"
@@ -2716,7 +2721,7 @@ msgstr "Validació invàlida del número d'identificació nacional."
#: contrib/localflavor/pl/forms.py:72
msgid ""
"Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX."
-msgstr "Introdueixi un número NIP en el format XXX-XXX-XX-XX o XX-XX-XXX-XXX."
+msgstr "Introduïu un número NIP en el format XXX-XXX-XX-XX o XX-XX-XXX-XXX."
#: contrib/localflavor/pl/forms.py:73
msgid "Wrong checksum for the Tax Number (NIP)."
@@ -3437,21 +3442,21 @@ msgstr "Gal·les"
#: contrib/localflavor/us/forms.py:16
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
-msgstr "Introdueixi un codi zip en el format XXXXX o XXXXX-XXXX."
+msgstr "Introduïu un codi zip en el format XXXXX o XXXXX-XXXX."
#: contrib/localflavor/us/forms.py:54
msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
msgstr ""
-"Introdueixi un número vàlid de la Seguretat Social dels E.U.A. en el format "
+"Introduïu un número vàlid de la Seguretat Social dels E.U.A. en el format "
"XXX-XX-XXXX."
#: contrib/localflavor/za/forms.py:20
msgid "Enter a valid South African ID number"
-msgstr "Introdueixi un número d'Identitat Sud Africà valid"
+msgstr "Introduïu un número d'Identitat Sud Africà valid"
#: contrib/localflavor/za/forms.py:54
msgid "Enter a valid South African postal code"
-msgstr "Introdueixi un codi postal Sud Africà vàlid."
+msgstr "Introduïu un codi postal Sud Africà vàlid."
#: contrib/localflavor/za/za_provinces.py:4
msgid "Eastern Cape"
@@ -3510,8 +3515,8 @@ msgid ""
"This can be either an absolute path (as above) or a full URL starting with "
"'http://'."
msgstr ""
-"Això pot ser bé una ruta absoluta (com a dalt) o una URL completa que comenci "
-"per http:// ."
+"Això pot ser bé una ruta absoluta (com a dalt) o una URL completa que "
+"comenci per http:// ."
#: contrib/redirects/models.py:13
msgid "redirect"
@@ -3584,15 +3589,15 @@ msgstr "No es permeten minúscules aquí."
#: core/validators.py:95
msgid "Enter only digits separated by commas."
-msgstr "Introdueixi només dígits separats per comes."
+msgstr "Introduïu només dígits separats per comes."
#: core/validators.py:107
msgid "Enter valid e-mail addresses separated by commas."
-msgstr "Introdueixi adreces de correu electrònic vàlides separades per comes."
+msgstr "Introduïu adreces de correu electrònic vàlides separades per comes."
#: core/validators.py:111
msgid "Please enter a valid IP address."
-msgstr "Si el plau, introdueixi una adreça IP vàlida."
+msgstr "Si el plau, introduïu una adreça IP vàlida."
#: core/validators.py:115
msgid "Empty values are not allowed here."
@@ -3608,7 +3613,7 @@ msgstr "Aquest valor no pot contenir només dígits."
#: core/validators.py:128 newforms/fields.py:152
msgid "Enter a whole number."
-msgstr "Introdueixi un número sencer."
+msgstr "Introduïu un número sencer."
#: core/validators.py:132
msgid "Only alphabetical characters are allowed here."
@@ -3625,19 +3630,19 @@ msgstr "Data invàlida: %s"
#: core/validators.py:156 db/models/fields/__init__.py:527
msgid "Enter a valid date in YYYY-MM-DD format."
-msgstr "Introdueixi una data vàlida en el forma AAAA-MM-DD."
+msgstr "Introduïu una data vàlida en el forma AAAA-MM-DD."
#: core/validators.py:161
msgid "Enter a valid time in HH:MM format."
-msgstr "Introdueixi una hora vàlida en el format HH:MM."
+msgstr "Introduïu una hora vàlida en el format HH:MM."
#: core/validators.py:165 db/models/fields/__init__.py:604
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
-msgstr "Introdueixi un data/hora vàlida en format YYYY-MM-DD HH:MM."
+msgstr "Introduïu un data/hora vàlida en format YYYY-MM-DD HH:MM."
#: core/validators.py:170 newforms/fields.py:403
msgid "Enter a valid e-mail address."
-msgstr "Introdueixi una adreça de correu vàlida."
+msgstr "Introduïu una adreça de correu vàlida."
#: core/validators.py:182 core/validators.py:474 newforms/fields.py:433
#: oldforms/__init__.py:687
@@ -3650,20 +3655,20 @@ msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
msgstr ""
-"Envii una imatge vàlida. El fitxer que ha enviat no era una imatge o estaba "
+"Envieu una imatge vàlida. El fitxer que heu enviat no era una imatge o estava "
"corrupte."
#: core/validators.py:200
#, python-format
msgid "The URL %s does not point to a valid image."
-msgstr "La URL %s no apunta una imatge vàlida."
+msgstr "La URL %s no apunta a una imatge vàlida."
#: core/validators.py:204
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
-"Els números de telèfon han de guardar-se en el format XXX-XXX-XXXX. \"%s\" no "
-"és vàlid."
+"Els números de telèfon han de guardar-se en el format XXX-XXX-XXXX. \"%s\" "
+"no és vàlid."
#: core/validators.py:212
#, python-format
@@ -3696,7 +3701,7 @@ msgstr "URL invàlida: %s"
#: core/validators.py:259 core/validators.py:261
#, python-format
msgid "The URL %s is a broken link."
-msgstr "La URL %sés un enllaç trencat."
+msgstr "La URL %s és un enllaç trencat."
#: core/validators.py:267
msgid "Enter a valid U.S. state abbreviation."
@@ -3706,8 +3711,8 @@ msgstr "Introdueixi una abreviatura vàlida d'estat dels E.U.A.."
#, python-format
msgid "Watch your mouth! The word %s is not allowed here."
msgid_plural "Watch your mouth! The words %s are not allowed here."
-msgstr[0] "Vigili amb el llenguatge! Aquí no s'admet la paraula: %s."
-msgstr[1] "Vigili amb el llenguatge! Aquí no s'admeten les paraules: %s."
+msgstr[0] "Vigileu amb el vostre llenguatge! Aquí no s'admet la paraula: %s."
+msgstr[1] "Vigileu amb el vostre llenguatge! Aquí no s'admeten les paraules: %s."
#: core/validators.py:288
#, python-format
@@ -3716,11 +3721,11 @@ msgstr "Aquest camp ha de concordar amb el camp '%s'."
#: core/validators.py:307
msgid "Please enter something for at least one field."
-msgstr "Si us plau, introdueixi alguna cosa almenys en un camp."
+msgstr "Si us plau, introduïu alguna cosa almenys en un camp."
#: core/validators.py:316 core/validators.py:327
msgid "Please enter both fields or leave them both empty."
-msgstr "Si us plau, ompli els dos camps o deixi'ls tots dos en blanc."
+msgstr "Si us plau, ompliu els dos camps o deixeu-los tots dos en blanc."
#: core/validators.py:335
#, python-format
@@ -3758,7 +3763,7 @@ msgstr "Aquest valor ha de ser una potència de %s."
#: core/validators.py:437
msgid "Please enter a valid decimal number."
-msgstr "Si us plau, introdueixi un número decimal vàlid."
+msgstr "Si us plau, introduïu un número decimal vàlid."
#: core/validators.py:444
#, python-format
@@ -3766,9 +3771,9 @@ msgid "Please enter a valid decimal number with at most %s total digit."
msgid_plural ""
"Please enter a valid decimal number with at most %s total digits."
msgstr[0] ""
-"Si us plau, introdueixi un número decimal vàlid de com a màxim %s digit."
+"Si us plau, introduïu un número decimal vàlid de com a màxim %s digit."
msgstr[1] ""
-"Si us plau, introdueixi un número decimal vàlid de com a màxim %s digits."
+"Si us plau, introduïu un número decimal vàlid de com a màxim %s digits."
#: core/validators.py:447
#, python-format
@@ -3777,10 +3782,10 @@ msgid ""
msgid_plural ""
"Please enter a valid decimal number with a whole part of at most %s digits."
msgstr[0] ""
-"Si us plau, introdueixi un número decimal vàlid que la seva part sencera "
+"Si us plau, introduïu un número decimal vàlid que la seva part sencera "
"sigui de com a màxim %s digit."
msgstr[1] ""
-"Si us plau, introdueixi un número decimal vàlid que la seva part sencera "
+"Si us plau, introduïu un número decimal vàlid que la seva part sencera "
"sigui de com a màxim %s digits."
#: core/validators.py:450
@@ -3789,25 +3794,25 @@ msgid "Please enter a valid decimal number with at most %s decimal place."
msgid_plural ""
"Please enter a valid decimal number with at most %s decimal places."
msgstr[0] ""
-"Si us plau, introdueixi un número decimal vàlid de com a màxim %s posició "
+"Si us plau, introduïu un número decimal vàlid de com a màxim %s posició "
"decimal."
msgstr[1] ""
-"Si us plau, introdueixi un número decimal vàlid de com a màxim %s posicions "
+"Si us plau, introduïu un número decimal vàlid de com a màxim %s posicions "
"decimals."
#: core/validators.py:458
msgid "Please enter a valid floating point number."
-msgstr "Si us plau, introdueixi un número amb punt de coma flotant vàlid."
+msgstr "Si us plau, introduïu un número amb punt de coma flotant vàlid."
#: core/validators.py:467
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
-msgstr "Asseguris de que el fitxer que ha enviat té, com a mínim, %s bytes."
+msgstr "Assegureu-vos de que el fitxer que heu enviat té, com a mínim, %s bytes."
#: core/validators.py:468
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
-msgstr "Asseguris de que el fitxer que ha enviat té, com a màxim %s bytes."
+msgstr "Assegureu-vos de que el fitxer que heu enviat té, com a màxim %s bytes."
#: core/validators.py:485
msgid "The format for this field is wrong."
@@ -3836,7 +3841,7 @@ msgid ""
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
"\"%(start)s\".)"
msgstr ""
-"Si us plau, tanqui l'etiqueta %(tag)s des de la línia %(line)s. (La línia "
+"Si us plau, tanqueu l'etiqueta %(tag)s des de la línia %(line)s. (La línia "
"comença amb \"%(start)s\".)"
#: core/validators.py:576
@@ -3918,7 +3923,7 @@ msgstr "Aquest valor ha de ser un número decimal."
#: db/models/fields/__init__.py:779
msgid "Enter a valid filename."
-msgstr "Introdueixi un nom de fitxer vàlid."
+msgstr "Introduïu un nom de fitxer vàlid."
#: db/models/fields/__init__.py:960
msgid "This value must be either None, True or False."
@@ -3927,7 +3932,7 @@ msgstr "Aquest valor ha de ser None (Cap), True (Veritat) o False (Fals)"
#: db/models/fields/related.py:93
#, python-format
msgid "Please enter a valid %s."
-msgstr "Si us plau, introdueixi un %s vàlid."
+msgstr "Si us plau, introduïu un %s vàlid."
#: db/models/fields/related.py:701
msgid "Separate multiple IDs with commas."
@@ -3936,7 +3941,9 @@ msgstr "Separi múltiples IDs amb comes."
#: db/models/fields/related.py:703
msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
-msgstr "Premeu la tecla \"Control\" -o \"Command\" en un Mac- per seleccionar més d'un valor."
+msgstr ""
+"Premeu la tecla \"Control\" -o \"Command\" en un Mac- per seleccionar més "
+"d'un valor."
#: db/models/fields/related.py:750
#, python-format
@@ -3944,28 +3951,28 @@ msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural ""
"Please enter valid %(self)s IDs. The values %(value)r are invalid."
msgstr[0] ""
-"Si us plau, introdueixi els IDs de %(self)s vàlids. El valor %(value)r és "
+"Si us plau, introduïu els IDs de %(self)s vàlids. El valor %(value)r és "
"invàlid."
msgstr[1] ""
-"Si us plau, introdueixi IDs de %(self)s vàlids. Els valors %(value)r són "
+"Si us plau, introduïu IDs de %(self)s vàlids. Els valors %(value)r són "
"invàlids."
#: newforms/fields.py:47
msgid "Enter a valid value."
-msgstr "Introdueixi un valor vàlid."
+msgstr "Introduïu un valor vàlid."
#: newforms/fields.py:124
#, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
msgstr ""
-"Asseguris de que el valor té com a màxim %(max)d caràcters (en té %(length)"
+"Assegureu-vos de que el valor té com a màxim %(max)d caràcters (en té %(length)"
"d)."
#: newforms/fields.py:125
#, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
msgstr ""
-"Asseguris de que el valor té com a mínim %(min)d caràcters (en té %(length)"
+"Assegureu-vos de que el valor té com a mínim %(min)d caràcters (en té %(length)"
"d)."
#: newforms/fields.py:153 newforms/fields.py:182 newforms/fields.py:211
@@ -3976,38 +3983,38 @@ msgstr "Aquest valor ha de ser menor o igual a %s."
#: newforms/fields.py:154 newforms/fields.py:183 newforms/fields.py:212
#, python-format
msgid "Ensure this value is greater than or equal to %s."
-msgstr "Asseguris de que aquest valor sigui superior o igual a %s."
+msgstr "Assegureu-vos de que aquest valor sigui superior o igual a %s."
#: newforms/fields.py:181 newforms/fields.py:210
msgid "Enter a number."
-msgstr "Introdueixi un número."
+msgstr "Introduïu un número."
#: newforms/fields.py:213
#, python-format
msgid "Ensure that there are no more than %s digits in total."
-msgstr "Asseguris de que no hi ha més de %s dígits en total."
+msgstr "Assegureu-vos de que no hi ha més de %s dígits en total."
#: newforms/fields.py:214
#, python-format
msgid "Ensure that there are no more than %s decimal places."
-msgstr "Asseguris de que no hi ha més de %s decimals."
+msgstr "Assegureu-vos de que no hi ha més de %s decimals."
#: newforms/fields.py:215
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
-msgstr "Asseguris de que no hi ha més de %s dígits decimals."
+msgstr "Assegureu-vos de que no hi ha més de %s dígits decimals."
#: newforms/fields.py:263 newforms/fields.py:751
msgid "Enter a valid date."
-msgstr "Introdueixi una data vàlida."
+msgstr "Introduïu una data vàlida."
#: newforms/fields.py:296 newforms/fields.py:752
msgid "Enter a valid time."
-msgstr "Introdueixi una hora vàlida."
+msgstr "Introduïu una hora vàlida."
#: newforms/fields.py:335
msgid "Enter a valid date/time."
-msgstr "Introdueixi una data/hora vàlides."
+msgstr "Introduïu una data/hora vàlides."
#: newforms/fields.py:434
msgid "No file was submitted."
@@ -4019,7 +4026,7 @@ msgstr "El fitxer enviat està buit."
#: newforms/fields.py:497
msgid "Enter a valid URL."
-msgstr "Introdueixi una URL vàlida."
+msgstr "Introduïu una URL vàlida."
#: newforms/fields.py:498
msgid "This URL appears to be a broken link."
@@ -4028,32 +4035,32 @@ msgstr "Aquesta URL sembla ser un enllaç trencat."
#: newforms/fields.py:560 newforms/models.py:299
msgid "Select a valid choice. That choice is not one of the available choices."
msgstr ""
-"Esculli una opció vàlida; Aquesta opció no és una de les opcions disponibles."
+"Escolliy una opció vàlida; Aquesta opció no és una de les opcions disponibles."
#: newforms/fields.py:599
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
-msgstr "Esculli una opció vàlida. %(value)s no és una de les opcions vàlides."
+msgstr "Esculliu una opció vàlida. %(value)s no és una de les opcions vàlides."
#: newforms/fields.py:600 newforms/fields.py:662 newforms/models.py:371
msgid "Enter a list of values."
-msgstr "Introdueixi una llista de valors."
+msgstr "Introduïu una llista de valors."
#: newforms/fields.py:780
msgid "Enter a valid IPv4 address."
-msgstr "Introdueixi una adreça IPv4 vàlida."
+msgstr "Introduïu una adreça IPv4 vàlida."
#: newforms/models.py:372
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
-msgstr "Esculli una opció vàlida; %s' no és una de les opcions vàlides."
+msgstr "Escolliu una opció vàlida; %s' no és una de les opcions vàlides."
#: oldforms/__init__.py:409
#, python-format
msgid "Ensure your text is less than %s character."
msgid_plural "Ensure your text is less than %s characters."
-msgstr[0] "Asseguris de que el seu text té menys de %s caràcter."
-msgstr[1] "Asseguris de que el seu text té menys de %s caràcters."
+msgstr[0] "Assegureu-vos de que el seu text té menys de %s caràcter."
+msgstr[1] "Assegureu-vos de que el seu text té menys de %s caràcters."
#: oldforms/__init__.py:414
msgid "Line breaks are not allowed here."
@@ -4062,19 +4069,19 @@ msgstr "No es permeten salts de línia."
#: oldforms/__init__.py:512 oldforms/__init__.py:586 oldforms/__init__.py:625
#, python-format
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
-msgstr "Esculli una opció vàlida; %(data)s' no està dintre de %(choices)s."
+msgstr "Escolliu una opció vàlida; %(data)s' no està dintre de %(choices)s."
#: oldforms/__init__.py:745
msgid "Enter a whole number between -32,768 and 32,767."
-msgstr "Introdueixi un enter entre -32,768 i 32,767."
+msgstr "Introduïu un enter entre -32,768 i 32,767."
#: oldforms/__init__.py:755
msgid "Enter a positive number."
-msgstr "Introdueixi un número positiu."
+msgstr "Introduïu un número positiu."
#: oldforms/__init__.py:765
msgid "Enter a whole number between 0 and 32,767."
-msgstr "Introdueixi un número entre 0 i 32,767."
+msgstr "Introduïu un número entre 0 i 32,767."
#: template/defaultfilters.py:698
msgid "yes,no,maybe"
@@ -4383,18 +4390,21 @@ msgstr "j de/d' F del Y"
#: views/generic/create_update.py:43
#, python-format
msgid "The %(verbose_name)s was created successfully."
-msgstr "El/La %(verbose_name)s s'ha creat amb èxit."
+msgstr "El/la %(verbose_name)s s'ha creat amb èxit."
#: views/generic/create_update.py:117
#, python-format
msgid "The %(verbose_name)s was updated successfully."
-msgstr "El/La %(verbose_name)s s'ha actualtzat amb èxit."
+msgstr "El/la %(verbose_name)s s'ha actualtzat amb èxit."
#: views/generic/create_update.py:184
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "El %(verbose_name)s s'ha eliminat."
+#~ msgid "Brazilian"
+#~ msgstr "Brasileny"
+
#~ msgid "Gaeilge"
#~ msgstr "Gaeilge"
View
BIN  django/conf/locale/fr/LC_MESSAGES/django.mo
Binary file not shown
View
20 django/conf/locale/fr/LC_MESSAGES/django.po
@@ -4277,23 +4277,33 @@ msgstr "ou"
#: utils/timesince.py:21
msgid "year"
-msgstr "année"
+msgid_plural "years"
+msgstr[0] "année"
+msgstr[1] "années"
#: utils/timesince.py:22
msgid "month"
-msgstr "mois"
+msgid_plural "months"
+msgstr[0] "mois"
+msgstr[1] "mois"
#: utils/timesince.py:23
msgid "week"
-msgstr "semaine"
+msgid_plural "weeks"
+msgstr[0] "semaine"
+msgstr[1] "semaines"
#: utils/timesince.py:24
msgid "day"
-msgstr "journée"
+msgid_plural "days"
+msgstr[0] "journée"
+msgstr[1] "journées"
#: utils/timesince.py:25
msgid "hour"
-msgstr "heure"
+msgid_plural "hours"
+msgstr[0] "heure"
+msgstr[1] "heures"
#: utils/timesince.py:26
msgid "minute"
View
BIN  django/conf/locale/ro/LC_MESSAGES/django.mo
Binary file not shown
View
5,176 django/conf/locale/ro/LC_MESSAGES/django.po
3,722 additions, 1,454 deletions not shown
View
BIN  django/conf/locale/ro/LC_MESSAGES/djangojs.mo
Binary file not shown
View
62 django/conf/locale/ro/LC_MESSAGES/djangojs.po
@@ -1,118 +1,116 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
-#, fuzzy
+
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-06-28 17:36+1000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"PO-Revision-Date: 2008-04-25 21:57+0200\n"
+"Last-Translator: \n"
+"Language-Team: Romanian <ro@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: contrib/admin/media/js/SelectFilter2.js:33
-#, perl-format
+#, fuzzy, perl-format
msgid "Available %s"
-msgstr ""
+msgstr "%s disponibil"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
-msgstr ""
+msgstr "Alege toate"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
-msgstr ""
+msgstr "Adauga"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
-msgstr ""
+msgstr "Sterge"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
msgid "Chosen %s"
-msgstr ""
+msgstr "%s ales"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
-msgstr ""
+msgstr "Selectati-va alegera(ile) si dati click "
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
-msgstr ""
+msgstr "Elibereaza toate"
#: contrib/admin/media/js/dateparse.js:32
#: contrib/admin/media/js/calendar.js:24
-msgid ""
-"January February March April May June July August September October November "
-"December"
-msgstr ""
+msgid "January February March April May June July August September October November December"
+msgstr "Ianuarie Februare Martie Aprilie Mai Iunie Iulie August Septembrie Octombrie Noiembrie Decembrie"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
-msgstr ""
+msgstr "Duminica Luni Marti Miercuri Joi Vinery Sambata"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
-msgstr ""
+msgstr "D L M M J V S"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Now"
-msgstr ""
+msgstr "Acum"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock"
-msgstr ""
+msgstr "Ceas"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time"
-msgstr ""
+msgstr "Alege o ora"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "Midnight"
-msgstr ""
+msgstr "Miezul noptii"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m."
-msgstr ""
+msgstr "6 a.m."
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon"
-msgstr ""
+msgstr "Amiaza"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
-msgstr ""
+msgstr "Anuleaza"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today"
-msgstr ""
+msgstr "Astazi"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar"
-msgstr ""
+msgstr "Calendar"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday"
-msgstr ""
+msgstr "Ieri"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
-msgstr ""
+msgstr "Maine"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
msgid "Show"
-msgstr ""
+msgstr "Arata"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
msgid "Hide"
-msgstr ""
+msgstr "Ascunde"
+
View
BIN  django/conf/locale/ru/LC_MESSAGES/djangojs.mo
Binary file not shown
View
2  django/conf/locale/ru/LC_MESSAGES/djangojs.po
@@ -74,7 +74,7 @@ msgstr "Часы"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
msgid "Choose a time"
-msgstr "Выбирите время"
+msgstr "Выберите время"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Midnight"
View
18 django/contrib/admin/views/main.py
@@ -8,7 +8,7 @@
from django.core.paginator import QuerySetPaginator, InvalidPage
from django.shortcuts import get_object_or_404, render_to_response
from django.db import models
-from django.db.models.query import handle_legacy_orderlist, QuerySet
+from django.db.models.query import QuerySet
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.utils.html import escape
from django.utils.text import capfirst, get_text_list
@@ -627,7 +627,7 @@ def get_results(self, request):
# Perform a slight optimization: Check to see whether any filters were
# given. If not, use paginator.hits to calculate the number of objects,
# because we've already done paginator.hits and the value is cached.
- if isinstance(self.query_set._filters, models.Q) and not self.query_set._filters.kwargs:
+ if not self.query_set.query.where:
full_result_count = result_count
else:
full_result_count = self.manager.count()
@@ -653,15 +653,12 @@ def get_results(self, request):
def get_ordering(self):
lookup_opts, params = self.lookup_opts, self.params
- # For ordering, first check the "ordering" parameter in the admin options,
- # then check the object's default ordering. If neither of those exist,
- # order descending by ID by default. Finally, look for manually-specified
- # ordering from the query string.
+ # For ordering, first check the "ordering" parameter in the admin
+ # options, then check the object's default ordering. If neither of
+ # those exist, order descending by ID by default. Finally, look for
+ # manually-specified ordering from the query string.
ordering = lookup_opts.admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
- # Normalize it to new-style ordering.
- ordering = handle_legacy_orderlist(ordering)
-
if ordering[0].startswith('-'):
order_field, order_type = ordering[0][1:], 'desc'
else:
@@ -753,8 +750,7 @@ def construct_search(field_name):
for bit in self.query.split():
or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.lookup_opts.admin.search_fields]
other_qs = QuerySet(self.model)
- if qs._select_related:
- other_qs = other_qs.select_related()
+ other_qs.dup_select_related(qs)
other_qs = other_qs.filter(reduce(operator.or_, or_queries))
qs = qs & other_qs
View
5 django/contrib/contenttypes/generic.py
@@ -154,6 +154,11 @@ def set_attributes_from_rel(self):
def get_internal_type(self):
return "ManyToManyField"
+ def db_type(self):
+ # Since we're simulating a ManyToManyField, in effect, best return the
+ # same db_type as well.
+ return None
+
class ReverseGenericRelatedObjectsDescriptor(object):
"""
This class provides the functionality that makes the related-object
View
286 django/contrib/gis/db/backend/__init__.py
@@ -4,27 +4,20 @@
Specifically, this module will import the correct routines and modules
needed for GeoDjango.
- (1) GeoBackEndField, a base class needed for GeometryField.
- (2) GIS_TERMS, a list of acceptable geographic lookup types for
- the backend.
- (3) The `parse_lookup` function, used for spatial SQL construction by
- the GeoQuerySet.
- (4) The `create_spatial_db`, and `get_geo_where_clause`
- (needed by `parse_lookup`) functions.
- (5) The `SpatialBackend` object, which contains information specific
- to the spatial backend.
+ (1) `GeoBackEndField`, a base class needed for GeometryField.
+ (2) `GeoWhereNode`, a subclass of `WhereNode` used to contruct spatial SQL.
+ (3) `SpatialBackend`, a container object for information specific to the
+ spatial backend.
"""
from django.conf import settings
-from django.db import connection
-from django.db.models.query import field_choices, find_field, get_where_clause, \
- FieldFound, LOOKUP_SEPARATOR, QUERY_TERMS
-from django.utils.datastructures import SortedDict
+from django.db.models.sql.query import QUERY_TERMS
+from django.db.models.sql.where import WhereNode
from django.contrib.gis.db.backend.util import gqn
# These routines (needed by GeoManager), default to False.
ASGML, ASKML, DISTANCE, DISTANCE_SPHEROID, EXTENT, TRANSFORM, UNION, VERSION = tuple(False for i in range(8))
-# Lookup types in which the rest of the parameters are not
+# Lookup types in which the rest of the parameters are not
# needed to be substitute in the WHERE SQL (e.g., the 'relate'
# operation on Oracle does not need the mask substituted back
# into the query SQL.).
@@ -68,6 +61,28 @@
else:
raise NotImplementedError('No Geographic Backend exists for %s' % settings.DATABASE_ENGINE)
+class GeoWhereNode(WhereNode):
+ """
+ The GeoWhereNode calls the `get_geo_where_clause` from the appropriate
+ spatial backend in order to construct correct spatial SQL.
+ """
+ def make_atom(self, child, qn):
+ table_alias, name, field, lookup_type, value = child
+ if hasattr(field, '_geom'):
+ if lookup_type in GIS_TERMS:
+ # Getting the geographic where clause; substitution parameters
+ # will be populated in the GeoFieldSQL object returned by the
+ # GeometryField.
+ gwc = get_geo_where_clause(lookup_type, table_alias, field, value)
+ where, params = field.get_db_prep_lookup(lookup_type, value)
+ return gwc % tuple(where), params
+ else:
+ raise TypeError('Invalid lookup type: %r' % lookup_type)
+ else:
+ # If not a GeometryField, call the `make_atom` from the
+ # base class.
+ return super(GeoWhereNode, self).make_atom(child, qn)
+
class SpatialBackend(object):
"A container for properties of the SpatialBackend."
# Stored procedure names used by the `GeoManager`.
@@ -96,246 +111,3 @@ class SpatialBackend(object):
# Adaptor class used for quoting GEOS geometries in the database.
Adaptor = GeoAdaptor
-
-#### query.py overloaded functions ####
-# parse_lookup() and lookup_inner() are modified from their django/db/models/query.py
-# counterparts to support constructing SQL for geographic queries.
-#
-# Status: Synced with r7098.
-#
-def parse_lookup(kwarg_items, opts):
- # Helper function that handles converting API kwargs
- # (e.g. "name__exact": "tom") to SQL.
- # Returns a tuple of (joins, where, params).
-
- # 'joins' is a sorted dictionary describing the tables that must be joined
- # to complete the query. The dictionary is sorted because creation order
- # is significant; it is a dictionary to ensure uniqueness of alias names.
- #
- # Each key-value pair follows the form
- # alias: (table, join_type, condition)
- # where
- # alias is the AS alias for the joined table
- # table is the actual table name to be joined
- # join_type is the type of join (INNER JOIN, LEFT OUTER JOIN, etc)
- # condition is the where-like statement over which narrows the join.
- # alias will be derived from the lookup list name.
- #
- # At present, this method only every returns INNER JOINs; the option is
- # there for others to implement custom Q()s, etc that return other join
- # types.
- joins, where, params = SortedDict(), [], []
-
- for kwarg, value in kwarg_items:
- path = kwarg.split(LOOKUP_SEPARATOR)
- # Extract the last elements of the kwarg.
- # The very-last is the lookup_type (equals, like, etc).
- # The second-last is the table column on which the lookup_type is
- # to be performed. If this name is 'pk', it will be substituted with
- # the name of the primary key.
- # If there is only one part, or the last part is not a query
- # term, assume that the query is an __exact
- lookup_type = path.pop()
- if lookup_type == 'pk':
- lookup_type = 'exact'
- path.append(None)
- elif len(path) == 0 or not ((lookup_type in QUERY_TERMS) or (lookup_type in GIS_TERMS)):
- path.append(lookup_type)
- lookup_type = 'exact'
-
- if len(path) < 1:
- raise TypeError, "Cannot parse keyword query %r" % kwarg
-
- if value is None:
- # Interpret '__exact=None' as the sql '= NULL'; otherwise, reject
- # all uses of None as a query value.
- if lookup_type != 'exact':
- raise ValueError, "Cannot use None as a query value"
- elif callable(value):
- value = value()
-
- joins2, where2, params2 = lookup_inner(path, lookup_type, value, opts, opts.db_table, None)
- joins.update(joins2)
- where.extend(where2)
- params.extend(params2)
- return joins, where, params
-
-def lookup_inner(path, lookup_type, value, opts, table, column):
- qn = connection.ops.quote_name
- joins, where, params = SortedDict(), [], []
- current_opts = opts
- current_table = table
- current_column = column
- intermediate_table = None
- join_required = False
-
- name = path.pop(0)
- # Has the primary key been requested? If so, expand it out
- # to be the name of the current class' primary key
- if name is None or name == 'pk':
- name = current_opts.pk.name
-
- # Try to find the name in the fields associated with the current class
- try:
- # Does the name belong to a defined many-to-many field?
- field = find_field(name, current_opts.many_to_many, False)
- if field:
- new_table = current_table + '__' + name
- new_opts = field.rel.to._meta
- new_column = new_opts.pk.column
-
- # Need to create an intermediate table join over the m2m table
- # This process hijacks current_table/column to point to the
- # intermediate table.
- current_table = "m2m_" + new_table
- intermediate_table = field.m2m_db_table()
- join_column = field.m2m_reverse_name()
- intermediate_column = field.m2m_column_name()
-
- raise FieldFound
-
- # Does the name belong to a reverse defined many-to-many field?
- field = find_field(name, current_opts.get_all_related_many_to_many_objects(), True)
- if field:
- new_table = current_table + '__' + name
- new_opts = field.opts
- new_column = new_opts.pk.column
-
- # Need to create an intermediate table join over the m2m table.
- # This process hijacks current_table/column to point to the
- # intermediate table.
- current_table = "m2m_" + new_table
- intermediate_table = field.field.m2m_db_table()
- join_column = field.field.m2m_column_name()
- intermediate_column = field.field.m2m_reverse_name()
-
- raise FieldFound
-
- # Does the name belong to a one-to-many field?
- field = find_field(name, current_opts.get_all_related_objects(), True)
- if field:
- new_table = table + '__' + name
- new_opts = field.opts
- new_column = field.field.column
- join_column = opts.pk.column
-
- # 1-N fields MUST be joined, regardless of any other conditions.
- join_required = True
-
- raise FieldFound
-
- # Does the name belong to a one-to-one, many-to-one, or regular field?
- field = find_field(name, current_opts.fields, False)
- if field:
- if field.rel: # One-to-One/Many-to-one field
- new_table = current_table + '__' + name
- new_opts = field.rel.to._meta
- new_column = new_opts.pk.column
- join_column = field.column
- raise FieldFound
- elif path:
- # For regular fields, if there are still items on the path,
- # an error has been made. We munge "name" so that the error
- # properly identifies the cause of the problem.
- name += LOOKUP_SEPARATOR + path[0]
- else:
- raise FieldFound
-
- except FieldFound: # Match found, loop has been shortcut.
- pass
- else: # No match found.
- choices = field_choices(current_opts.many_to_many, False) + \
- field_choices(current_opts.get_all_related_many_to_many_objects(), True) + \
- field_choices(current_opts.get_all_related_objects(), True) + \
- field_choices(current_opts.fields, False)
- raise TypeError, "Cannot resolve keyword '%s' into field. Choices are: %s" % (name, ", ".join(choices))
-
- # Check whether an intermediate join is required between current_table
- # and new_table.
- if intermediate_table:
- joins[qn(current_table)] = (
- qn(intermediate_table), "LEFT OUTER JOIN",
- "%s.%s = %s.%s" % (qn(table), qn(current_opts.pk.column), qn(current_table), qn(intermediate_column))
- )
-
- if path:
- # There are elements left in the path. More joins are required.
- if len(path) == 1 and path[0] in (new_opts.pk.name, None) \
- and lookup_type in ('exact', 'isnull') and not join_required:
- # If the next and final name query is for a primary key,
- # and the search is for isnull/exact, then the current
- # (for N-1) or intermediate (for N-N) table can be used
- # for the search. No need to join an extra table just
- # to check the primary key.
- new_table = current_table
- else:
- # There are 1 or more name queries pending, and we have ruled out
- # any shortcuts; therefore, a join is required.
- joins[qn(new_table)] = (
- qn(new_opts.db_table), "INNER JOIN",
- "%s.%s = %s.%s" % (qn(current_table), qn(join_column), qn(new_table), qn(new_column))
- )
- # If we have made the join, we don't need to tell subsequent
- # recursive calls about the column name we joined on.
- join_column = None
-
- # There are name queries remaining. Recurse deeper.
- joins2, where2, params2 = lookup_inner(path, lookup_type, value, new_opts, new_table, join_column)
-
- joins.update(joins2)
- where.extend(where2)
- params.extend(params2)
- else:
- # No elements left in path. Current element is the element on which
- # the search is being performed.
- db_type = None
-
- if join_required:
- # Last query term is a RelatedObject
- if field.field.rel.multiple:
- # RelatedObject is from a 1-N relation.
- # Join is required; query operates on joined table.
- column = new_opts.pk.name
- joins[qn(new_table)] = (
- qn(new_opts.db_table), "INNER JOIN",
- "%s.%s = %s.%s" % (qn(current_table), qn(join_column), qn(new_table), qn(new_column))
- )
- current_table = new_table
- else:
- # RelatedObject is from a 1-1 relation,
- # No need to join; get the pk value from the related object,
- # and compare using that.
- column = current_opts.pk.name
- elif intermediate_table:
- # Last query term is a related object from an N-N relation.
- # Join from intermediate table is sufficient.
- column = join_column
- elif name == current_opts.pk.name and lookup_type in ('exact', 'isnull') and current_column:
- # Last query term is for a primary key. If previous iterations
- # introduced a current/intermediate table that can be used to
- # optimize the query, then use that table and column name.
- column = current_column
- else:
- # Last query term was a normal field.
- column = field.column
- db_type = field.db_type()
-
- # If the field is a geometry field, then the WHERE clause will need to be obtained
- # with the get_geo_where_clause()
- if hasattr(field, '_geom'):
- # Getting additional SQL WHERE and params arrays associated with
- # the geographic field.
- geo_where, geo_params = field.get_db_prep_lookup(lookup_type, value)
-
- # Getting the geographic WHERE clause.
- gwc = get_geo_where_clause(lookup_type, current_table, field, value)
-
- # Appending the geographic WHERE componnents and parameters onto
- # the where and params arrays.
- where.append(gwc % tuple(geo_where))
- params.extend(geo_params)
- else:
- where.append(get_where_clause(lookup_type, current_table + '.', column, value, db_type))
- params.extend(field.get_db_prep_lookup(lookup_type, value))
-
- return joins, where, params
View
2  django/contrib/gis/db/models/fields/__init__.py
@@ -1,5 +1,3 @@
-from decimal import Decimal
-from django.conf import settings
from django.db import connection
# Getting the SpatialBackend container and the geographic quoting method.
from django.contrib.gis.db.backend import SpatialBackend, gqn
View
459 django/contrib/gis/db/models/query.py
@@ -1,252 +1,161 @@
-import operator
from django.core.exceptions import ImproperlyConfigured
from django.db import connection
-from django.db.models.query import EmptyResultSet, Q, QuerySet, handle_legacy_orderlist, quote_only_if_word, orderfield2column, fill_table_cache
+from django.db.models.query import sql, QuerySet, Q
from django.db.models.fields import FieldDoesNotExist
-from django.utils.datastructures import SortedDict
+from django.contrib.gis.db.backend import gqn, GeoWhereNode, SpatialBackend, QUERY_TERMS
from django.contrib.gis.db.models.fields import GeometryField, PointField
-# parse_lookup depends on the spatial database backend.
-from django.contrib.gis.db.backend import gqn, parse_lookup, SpatialBackend
from django.contrib.gis.geos import GEOSGeometry, Point
-# Shortcut booleans for determining the backend.
-oracle = SpatialBackend.name == 'oracle'
+# Aliases.
+qn = connection.ops.quote_name
+oracle = SpatialBackend.name == 'oracle'
postgis = SpatialBackend.name == 'postgis'
-class GeoQ(Q):
- "Geographical query encapsulation object."
-
- def get_sql(self, opts):
- "Overloaded to use our own parse_lookup() function."
- return parse_lookup(self.kwargs.items(), opts)
-
-class GeoQuerySet(QuerySet):
- "Geographical-enabled QuerySet object."
-
- #### Overloaded QuerySet Routines ####
- def __init__(self, model=None):
- super(GeoQuerySet, self).__init__(model=model)
-
- # We only want to use the GeoQ object for our queries
- self._filters = GeoQ()
-
- # For replacement fields in the SELECT.
- self._custom_select = {}
- self._ewkt = None
-
- # If GEOM_SELECT is defined in the backend, then it will be used
- # for the selection format of the geometry column.
- if SpatialBackend.select:
- # Transformed geometries in Oracle use EWKT so that the SRID
- # on the transformed lazy geometries is set correctly).
- self._geo_fmt = SpatialBackend.select
- else:
- self._geo_fmt = '%s'
-
- def _filter_or_exclude(self, mapper, *args, **kwargs):
- # mapper is a callable used to transform Q objects,
- # or None for identity transform
- if mapper is None:
- mapper = lambda x: x
- if len(args) > 0 or len(kwargs) > 0:
- assert self._limit is None and self._offset is None, \
- "Cannot filter a query once a slice has been taken."
-
- clone = self._clone()
- if len(kwargs) > 0:
- # Using the GeoQ object for our filters instead
- clone._filters = clone._filters & mapper(GeoQ(**kwargs))
- if len(args) > 0:
- clone._filters = clone._filters & reduce(operator.and_, map(mapper, args))
- return clone
-
- def _get_sql_clause(self, get_full_query=False):
- qn = connection.ops.quote_name
- opts = self.model._meta
-
- # Construct the fundamental parts of the query: SELECT X FROM Y WHERE Z.
- select = []
-
- # This is the only component of this routine that is customized for the
- # GeoQuerySet. Specifically, this allows operations to be done on fields
- # in the SELECT, overriding their values -- this is different from using
- # QuerySet.extra(select=foo) because extra() adds an an _additional_
- # field to be selected. Used in returning transformed geometries, and
- # handling the selection of native database geometry formats.
- for f in opts.fields:
- # Getting the selection format string.
- if hasattr(f, '_geom'):
- sel_fmt = self._geo_fmt
-
- # If an SRID needs to specified other than what is in the field
- # (like when `transform` is called), make sure to explicitly set
- # the SRID by returning EWKT.
- if self._ewkt and oracle:
- sel_fmt = "'SRID=%d;'||%s" % (self._ewkt, sel_fmt)
- else:
- sel_fmt = '%s'
-
- # Getting the field selection substitution string
- if f.column in self._custom_select:
- fld_sel = self._custom_select[f.column]
- else:
- fld_sel = self._field_column(f)
-
- # Appending the selection
- select.append(sel_fmt % fld_sel)
-
- tables = [quote_only_if_word(t) for t in self._tables]
- joins = SortedDict()
- where = self._where[:]
- params = self._params[:]
-
- # Convert self._filters into SQL.
- joins2, where2, params2 = self._filters.get_sql(opts)
- joins.update(joins2)
- where.extend(where2)
- params.extend(params2)
-
- # Add additional tables and WHERE clauses based on select_related.
- if self._select_related:
- fill_table_cache(opts, select, tables, where,
- old_prefix=opts.db_table,
- cache_tables_seen=[opts.db_table],
- max_depth=self._max_related_depth)
-
- # Add any additional SELECTs.
- if self._select:
- select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), qn(s[0])) for s in self._select.items()])
-
- # Start composing the body of the SQL statement.
- sql = [" FROM", qn(opts.db_table)]
-
- # Compose the join dictionary into SQL describing the joins.
- if joins:
- sql.append(" ".join(["%s %s AS %s ON %s" % (join_type, table, alias, condition)
- for (alias, (table, join_type, condition)) in joins.items()]))
-
- # Compose the tables clause into SQL.
- if tables:
- sql.append(", " + ", ".join(tables))
-
- # Compose the where clause into SQL.
- if where:
- sql.append(where and "WHERE " + " AND ".join(where))
-
- # ORDER BY clause
- order_by = []
- if self._order_by is not None:
- ordering_to_use = self._order_by
- else:
- ordering_to_use = opts.ordering
- for f in handle_legacy_orderlist(ordering_to_use):
- if f == '?': # Special case.
- order_by.append(connection.ops.random_function_sql())
- else:
- if f.startswith('-'):
- col_name = f[1:]
- order = "DESC"
- else:
- col_name = f
- order = "ASC"
- if "." in col_name:
- table_prefix, col_name = col_name.split('.', 1)
- table_prefix = qn(table_prefix) + '.'
- else:
- # Use the database table as a column prefix if it wasn't given,
- # and if the requested column isn't a custom SELECT.
- if "." not in col_name and col_name not in (self._select or ()):
- table_prefix = qn(opts.db_table) + '.'
- else:
- table_prefix = ''
- order_by.append('%s%s %s' % (table_prefix, qn(orderfield2column(col_name, opts)), order))
- if order_by:
- sql.append("ORDER BY " + ", ".join(order_by))
-
- # LIMIT and OFFSET clauses
- if not oracle:
- if self._limit is not None:
- sql.append("%s " % connection.ops.limit_offset_sql(self._limit, self._offset))
- else:
- assert self._offset is None, "'offset' is not allowed without 'limit'"
+# All valid lookup terms.
+ALL_TERMS = QUERY_TERMS.copy()
+ALL_TERMS.update(dict((term, None) for term in SpatialBackend.gis_terms))
+
+# For backwards-compatibility; Q object should work just fine
+# using queryset-refactor.
+class GeoQ(Q): pass
+
+class GeomSQL(object):
+ "Simple wrapper object for geometric SQL."
+ def __init__(self, geo_sql):
+ self.sql = geo_sql
+
+ def as_sql(self, *args, **kwargs):
+ return self.sql
+
+# Getting the `Query` base class from the backend (needed specifically
+# for Oracle backends).
+Query = QuerySet().query.__class__
+
+class GeoQuery(Query):
+ "The Geographic Query, needed to construct spatial SQL."
+
+ # Overridding the valid query terms.
+ query_terms = ALL_TERMS
+
+ #### Methods overridden from the base Query class ####
+ def __init__(self, model, conn):
+ super(GeoQuery, self).__init__(model, conn, where=GeoWhereNode)
+ # The following attributes are customized for the GeoQuerySet.
+ # The GeoWhereNode and SpatialBackend classes contain backend-specific
+ # routines and functions.
+ self.custom_select = {}
+ self.ewkt = None
+
+ def clone(self, *args, **kwargs):
+ obj = super(GeoQuery, self).clone(*args, **kwargs)
+ # Customized selection dictionary and EWKT flag have to be added to obj.
+ obj.custom_select = self.custom_select.copy()
+ obj.ewkt = self.ewkt
+ return obj
+
+ def get_default_columns(self, with_aliases=False, col_aliases=None):
+ """
+ Computes the default columns for selecting every field in the base
+ model.
- return select, " ".join(sql), params
- else:
- # To support limits and offsets, Oracle requires some funky rewriting of an otherwise normal looking query.
- select_clause = ",".join(select)
- distinct = (self._distinct and "DISTINCT " or "")
+ Returns a list of strings, quoted appropriately for use in SQL
+ directly, as well as a set of aliases used in the select statement.
- if order_by:
- order_by_clause = " OVER (ORDER BY %s )" % (", ".join(order_by))
- else:
- #Oracle's row_number() function always requires an order-by clause.
- #So we need to define a default order-by, since none was provided.
- order_by_clause = " OVER (ORDER BY %s.%s)" % \
- (qn(opts.db_table), qn(opts.fields[0].db_column or opts.fields[0].column))
- # limit_and_offset_clause
- if self._limit is None:
- assert self._offset is None, "'offset' is not allowed without 'limit'"
-
- if self._offset is not None:
- offset = int(self._offset)
- else:
- offset = 0
- if self._limit is not None:
- limit = int(self._limit)
- else:
- limit = None
-
- limit_and_offset_clause = ''
- if limit is not None:
- limit_and_offset_clause = "WHERE rn > %s AND rn <= %s" % (offset, limit+offset)
- elif offset:
- limit_and_offset_clause = "WHERE rn > %s" % (offset)
-
- if len(limit_and_offset_clause) > 0:
- fmt = \
- """SELECT * FROM
- (SELECT %s%s,
- ROW_NUMBER()%s AS rn
- %s)
- %s"""
- full_query = fmt % (distinct, select_clause,
- order_by_clause, ' '.join(sql).strip(),
- limit_and_offset_clause)
+ This routine is overridden from Query to handle customized selection of
+ geometry columns.
+ """
+ result = []
+ table_alias = self.tables[0]
+ root_pk = self.model._meta.pk.column
+ seen = {None: table_alias}
+ qn = self.quote_name_unless_alias
+ qn2 = self.connection.ops.quote_name
+ aliases = set()
+ for field, model in self.model._meta.get_fields_with_model():