From a81d16dadaaf872e969e9e68fa9a04152053ebeb Mon Sep 17 00:00:00 2001 From: Georg Bauer Date: Fri, 18 Nov 2005 20:11:50 +0000 Subject: [PATCH 1/9] fixes #837: updated 'ru' translation git-svn-id: http://code.djangoproject.com/svn/django/trunk@1283 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/conf/locale/ru/LC_MESSAGES/django.mo | Bin 11784 -> 14108 bytes django/conf/locale/ru/LC_MESSAGES/django.po | 37 +++++++++++--------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/django/conf/locale/ru/LC_MESSAGES/django.mo b/django/conf/locale/ru/LC_MESSAGES/django.mo index ea8a9e44abd448c6922611918849bbccee29f886..c98881206ef1d79917102c804b16136b225486e5 100644 GIT binary patch delta 5713 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 E8#Xp#jsO4v delta 3506 zcmYk;drXyO0LSs?$W6f`ctN>nq6Y*;1wqBg3n~a|rjZC<@P^366mNL1<6TH4^G(rk zndxXVr_!;_{%~5UHLKZbmbK;|Wwz4VbZ$+j(f4=G!{$4G=kvVJIq&;i-xrT8tDED! z)g}0V;bpEN&6gA=Q}Gzfa6(j|;ghI_&)^6=k8AKgY9y8PLL;w1o!4RxZo)9U zfEvIR%*Sg;6Q&Epmwhpq_Du!_U67>;9AnKz-FPB)#A&GCm0~iMqdKq`wG@v1z7ciZ zQ4GgsWHn3+rs73plFVK7s=>z;G}2bod3)AD4Y^SlM&n@gpe`&#jbH)B;R;*72V*&J zLM`FPs197j2)u^6-w!w%Z+B(>6DWAtAsLv9YG^I)!e&&1gIPFc&x}HKY$~e5#i$vW zk7{r+#^Z9-jO{_jWDcWdr-$08ii!0;0&p?e}Hl|@YX5j%`jNjPr zhth2|Fd8+L`KS&T;dtDF{qPF%&)nlf4TUi+nt^oG^;xJ6dUGgfstQmyEJCeSnXRv} z=bKP#UT4n_q1N^Us^e$u`6s9jTt+R;U0Z)2^}8pihC`WNI^s2*C}@p(1S-q`R7WyV z9T|(da0;?)rWkdDrKpbAqJFm(HL?cOj5eY=a0Gc`&HJeP`fUBDnC4>rzo0OUFaGTn zc*7Mu7r4;^Yc*=>R$&EhKsE5It^WgAR`U<417W=b4Mth}ARFFfpgKAMHFJgNfBs7; zXhaK9H>yVZWVWGt{GL5OjVYXeg{k-uwMP;X0-LG?_501(9~&?e&*Nmghm|;@PhbGY z(5r@d=s8b9t=UjypO|d>!xo zN%$9PsiHX1{R+^*m0k+k{h>TFnt@nUPg770q+u{-p*Gh@WS^Qm)bGoXm!w&Vnvq@j z0y@a-o9oEFG!IZq*E!jkfjAC%r5JAwg##4oaVGX=hfy@^u?ml2Ax6;cQ8*XF@QC#U z26280tMDvp^TrJ@W;kY{W^Ng3ARAE~*^EQ={I^gjr{WHV;ESn&cYPu1!bQj=nH4w= z8&Ma#Hvb5MW0^3jbmQTMBmv~Si?P|xa7BRY(_um#vhHoXqW@K!*(8eeCb1-j=om}3`b)fE ztYQq&M$6X;M-|cEk4h3mCXn4kn|U;0ANr4-d@dzBh&K47z}BE-k2u^+YDr%bN!F4j zM91@F4snx#L@%T_$X=q?wqB`kku@ZRv>h)|SVcm}B3qe^uROcE`cu(BvPdCmBB`Vs zSwM7jck((-a(tbhIyWK*IU}QzeLJF72RUoIE%8l_{>n`U>N~!N=|En(F_(6|dPD@(6 e)09@?xYHl`VusvxIl-B^zH^z`K~C%NUjG9df=V<1 diff --git a/django/conf/locale/ru/LC_MESSAGES/django.po b/django/conf/locale/ru/LC_MESSAGES/django.po index aec5077111..f0a6027636 100644 --- a/django/conf/locale/ru/LC_MESSAGES/django.po +++ b/django/conf/locale/ru/LC_MESSAGES/django.po @@ -499,7 +499,7 @@ msgstr "URL" msgid "" "Example: '/about/contact/'. Make sure to have leading and trailing slashes." msgstr "" -"ðÒÉÍÅÒ: '/about/contact/'. âÕÄØÔÅ Õ×ÅÒÅÎÎÙ, ÞÔÏ ×ÓÔÁ×ÉÌÉ ÚÁ×ÅÐÒÛÁÀÝÉÊ ÓÌÜÛ." +"ðÒÉÍÅÒ: '/about/contact/'. âÕÄØÔÅ Õ×ÅÒÅÎÎÙ, ÞÔÏ ×ÓÔÁ×ÉÌÉ ÚÁ×ÅÒÛÁÀÝÉÊ ÓÌÜÛ." #: models/core.py:89 msgid "title" @@ -606,15 +606,15 @@ msgstr " #: models/auth.py:37 msgid "Use an MD5 hash -- not the raw password." -msgstr "éÓÐÏÌØÚÕÊÔÅ MD5 ÈÜÛ -- ÔÏÌØËÏ ÎÅ ÎÅÏÂÒÁÂÏÔÁÎÎÙÊ ÐÁÒÏÌØ" +msgstr "éÓÐÏÌØÚÕÊÔÅ MD5 ÈÜÛ -- ÔÏÌØËÏ ÎÅ ÎÅÏÂÒÁÂÏÔÁÎÎÙÊ ÐÁÒÏÌØ." #: models/auth.py:38 msgid "staff status" -msgstr "" +msgstr "ÓÔÁÔÕÓ ÐÅÒÓÏÎÁÌÁ" #: models/auth.py:38 msgid "Designates whether the user can log into this admin site." -msgstr "" +msgstr "ïÔÍÅÔÔÅ, ÅÓÌÉ ÐÏÌØÚÏ×ÁÔÅÌØ ÍÏÖÅÔ ×ÈÏÄÉÔØ × ÁÄÍÉÎ. ÞÁÓÔØ ÓÁÊÔÁ." #: models/auth.py:39 msgid "active" @@ -637,6 +637,8 @@ msgid "" "In addition to the permissions manually assigned, this user will also get " "all permissions granted to each group he/she is in." msgstr "" +"ë ÄÏÂÁ×ÌÅÎÉÀ Ë ÐÅÒÁ×ÁÍ ×ÙÂÒÎÁÎÎÙÍ ×ÕÒÕÞÎÕÀ, ÜÔÏÔ ÐÏÌØÚÏ×ÁÔÅÌØ ÍÏÖÅÔ ÐÏÌÕÞÉÔØ " +"×ÓÅ ÐÒÁ×Á ÇÒÕÐÐÙ, Ë ËÏÔÏÒÏÊ ÏÎ ÐÒÉÎÁÄÌÅÖÉÔ." #: models/auth.py:48 #, fuzzy @@ -843,8 +845,8 @@ msgstr " #, 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] "" -msgstr[1] "" +msgstr[0] "óÌÅÄÉÔÅ ÚÁ Ó×ÏÉÍÍÉ ÓÌÏ×ÁÍÉ! óÌÏ×Á %s ÚÄÅÓØ ÚÁÐÒÅÝÅÎÙ." +msgstr[1] "óÌÅÄÉÔÅ ÚÁ Ó×ÏÉÍÍÉ ÓÌÏ×ÁÍÉ! óÌÏ×Á %s ÚÄÅÓØ ÚÁÐÒÅÝÅÎÙ." #: core/validators.py:231 #, python-format @@ -871,7 +873,7 @@ msgstr "" #: core/validators.py:308 msgid "Duplicate values are not allowed." -msgstr "" +msgstr "ä×ÏÊÎÙÅ ÚÎÁÞÅÎÉÑ ÚÁÐÒÅÝÅÎÎÙ." #: core/validators.py:331 #, python-format @@ -880,52 +882,55 @@ msgstr "" #: core/validators.py:342 msgid "Please enter a valid decimal number." -msgstr "" +msgstr "ðÏÖÁÌÕÊÓÔÁ, ××ÏÄÉÔÅ ËÏÒÒÅËÔÎÏÅ ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ." #: core/validators.py:344 #, python-format msgid "Please enter a valid decimal number with at most %s total digit." msgid_plural "" "Please enter a valid decimal number with at most %s total digits." -msgstr[0] "" +msgstr[0] "ðÏÖÁÌÕÊÓÔÁ, ××ÏÄÉÔÅ ËÏÒÒÅËÔÎÏÅ ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ Ó ÍÁËÓÉÍÁÌØÎÙÍ ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁËÏ× %s." msgstr[1] "" +"ðÏÖÁÌÕÊÓÔÁ, ××ÏÄÉÔÅ ËÏÒÒÅËÔÎÏÅ ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ Ó ÍÁËÓÉÍÁÌØÎÙÍ ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁËÏ× %s." #: core/validators.py:347 #, python-format msgid "Please enter a valid decimal number with at most %s decimal place." msgid_plural "" "Please enter a valid decimal number with at most %s decimal places." -msgstr[0] "" +msgstr[0] "ðÏÖÁÌÕÊÓÔÁ, ××ÏÄÉÔÅ ËÏÒÒÅËÔÎÏÅ ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ Ó ÍÁËÓÉÍÁÌØÎÙÍ ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁËÏ× ÐÏÓÌÅ ÚÁÐÑÔÏÊ %s." msgstr[1] "" +"ðÏÖÁÌÕÊÓÔÁ, ××ÏÄÉÔÅ ËÏÒÒÅËÔÎÏÅ ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ Ó ÍÁËÓÉÍÁÌØÎÙÍ ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁËÏ× ÐÏÓÌÅ ÚÁÐÑÔÏÊ %s." #: core/validators.py:357 #, python-format msgid "Make sure your uploaded file is at least %s bytes big." -msgstr "" +msgstr "âÕÄÔÅ Õ×ÅÒÅÎÙ, ÞÔÏ ÚÁÇÒÕÖÅÎÎÙÊ ÆÁÊÌ ÐÏ ËÒÁÊÎÅÊ ÍÅÒÅ ÎÅ ÍÅÎØÛÅ %s ÂÁÊÔ." #: core/validators.py:358 #, python-format msgid "Make sure your uploaded file is at most %s bytes big." -msgstr "" +msgstr "âÕÄÔÅ Õ×ÅÒÅÎÙ, ÞÔÏ ÚÁÇÒÕÖÅÎÎÙÊ ÆÁÊÌ ÂÏÌØÛÅ ÞÅÍ %s ÂÁÊÔ." #: core/validators.py:371 msgid "The format for this field is wrong." -msgstr "" +msgstr "æÏÒÍÁÔ ÜÔÏÇÏ ÐÏÌÑ ÎÅ×ÅÒÅÎ" #: core/validators.py:386 msgid "This field is invalid." -msgstr "" +msgstr "üÔÏ ÐÏÌÅ ÎÅ×ÅÒÎÏ." #: core/validators.py:421 #, python-format msgid "Could not retrieve anything from %s." -msgstr "" +msgstr "îÅ×ÏÚÍÏÖÎÏ ÐÏÌÕÞÉÔØ ÞÔÏ ÌÉÂÏ Ó %s." #: core/validators.py:424 #, python-format msgid "" "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." msgstr "" +"URL %(url) ×ÅÒÎÕÌ ÎÅ×ÅÒÎÙ ÚÁÇÏÌÏ×ÏË Content-Type '%(contenttype)'." #: core/validators.py:457 #, python-format @@ -971,7 +976,7 @@ msgstr "" #: core/meta/fields.py:111 msgid " Separate multiple IDs with commas." -msgstr "" +msgstr "òÁÚÄÅÌÑÊÔÅ ÍÎÏÖÅÓÔ×Ï ID ÚÁÐÑÔÏÊ." #: core/meta/fields.py:114 msgid "" From cdbc94dbd27bacfcf758e76526c57db3f6001d1e Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Fri, 18 Nov 2005 21:42:45 +0000 Subject: [PATCH 2/9] Fixed #838 -- Removed unused link in tutorial01.txt. Thanks, paolo git-svn-id: http://code.djangoproject.com/svn/django/trunk@1285 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/tutorial01.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt index edf59b5b54..b20e3ce492 100644 --- a/docs/tutorial01.txt +++ b/docs/tutorial01.txt @@ -94,7 +94,6 @@ type ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to display the tables. .. _`Python path documentation`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000 -.. _Django's ticket system: http://code.djangoproject.com/report/1 Creating models =============== From f125fb0afc2e00612701f825c8456acdcb53e55b Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 19 Nov 2005 18:20:30 +0000 Subject: [PATCH 3/9] Beefed up docs/url_dispatch.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1291 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/overview.txt | 12 +- docs/tutorial03.txt | 14 ++- docs/url_dispatch.txt | 271 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 255 insertions(+), 42 deletions(-) diff --git a/docs/overview.txt b/docs/overview.txt index 1f251efcb6..11fa7d1fa9 100644 --- a/docs/overview.txt +++ b/docs/overview.txt @@ -162,9 +162,9 @@ Reporter/Article example, here's what that might look like:: from django.conf.urls.defaults import * urlpatterns = patterns('', - (r'^/articles/(?P\d{4})/$', 'myproject.news.views.articles.year_archive'), - (r'^/articles/(?P\d{4})/(?P\d{2})/$', 'myproject.news.views.articles.month_archive'), - (r'^/articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'myproject.news.views.articles.article_detail'), + (r'^/articles/(?P\d{4})/$', 'myproject.news.views.year_archive'), + (r'^/articles/(?P\d{4})/(?P\d{2})/$', 'myproject.news.views.month_archive'), + (r'^/articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'myproject.news.views.article_detail'), ) The code above maps URLs, as regular expressions, to the location of Python @@ -181,7 +181,7 @@ dictionaries -- and the values captured in the regex, via keyword arguments. For example, if a user requested the URL "/articles/2005/05/39323/", Django -would call the function ``myproject.news.views.articles.article_detail(request, +would call the function ``myproject.news.views.article_detail(request, year='2005', month='05', article_id='39323')``. Write your views @@ -280,8 +280,8 @@ This has been only a quick overview of Django's functionality. Some more useful features: * A caching framework that integrates with memcached or other backends. - * An RSS framework that makes creating RSS feeds as easy as writing a - small Python class. + * A syndication framework that makes creating RSS and Atom feeds as easy as + writing a small Python class. * More sexy automatically-generated admin features -- this overview barely scratched the surface. diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt index ebf1515aa3..ad13c323d9 100644 --- a/docs/tutorial03.txt +++ b/docs/tutorial03.txt @@ -60,6 +60,7 @@ regular expression as keyword arguments, and, optionally, arbitrary keyword arguments from the dictionary (an optional third item in the tuple). For more on ``HTTPRequest`` objects, see the `request and response documentation`_. +For more details on URLconfs, see the `URLconf documentation`_. When you ran ``django-admin.py startproject myproject`` at the beginning of Tutorial 1, it created a default URLconf in ``myproject/urls.py``. It also @@ -67,8 +68,7 @@ automatically set your ``ROOT_URLCONF`` setting to point at that file:: ROOT_URLCONF = 'myproject.urls' -Time for an example. Edit ``myproject/urls.py`` so it looks like -this:: +Time for an example. Edit ``myproject/urls.py`` so it looks like this:: from django.conf.urls.defaults import * @@ -88,9 +88,9 @@ associated Python package/module: ``myproject.apps.polls.views.detail``. That corresponds to the function ``detail()`` in ``myproject/apps/polls/views.py``. Finally, it calls that ``detail()`` function like so:: - detail(request=, poll_id=23) + detail(request=, poll_id='23') -The ``poll_id=23`` part comes from ``(?P\d+)``. Using +The ``poll_id='23'`` part comes from ``(?P\d+)``. Using ``(?Ppattern)`` "captures" the text matched by ``pattern`` and sends it as a keyword argument to the view function. @@ -103,6 +103,11 @@ something like this:: But, don't do that. It's silly. +Note that these regular expressions do not search GET and POST parameters, or +the domain name. For example, in a request to ``http://www.example.com/myapp/``, +the URLconf will look for ``/myapp/``. In a request to +``http://www.example.com/myapp/?page=3``, the URLconf will look for ``/myapp/``. + If you need help with regular expressions, see `Wikipedia's entry`_ and the `Python documentation`_. Also, the O'Reilly book "Mastering Regular Expressions" by Jeffrey Friedl is fantastic. @@ -113,6 +118,7 @@ time the URLconf module is loaded. They're super fast. .. _Wikipedia's entry: http://en.wikipedia.org/wiki/Regular_expression .. _Python documentation: http://www.python.org/doc/current/lib/module-re.html .. _request and response documentation: http://www.djangoproject.com/documentation/request_response/ +.. _URLconf documentation: http://www.djangoproject.com/documentation/url_dispatch/ Write your first view ===================== diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt index 363d31174a..d08ba702f6 100644 --- a/docs/url_dispatch.txt +++ b/docs/url_dispatch.txt @@ -2,52 +2,244 @@ URL dispatcher ============== -We're fanatics about good URLs. No ".php" or ".cgi", and certainly not any of -that "0,2097,1-1-1928,00" nonsense. Django's URL dispatcher lets you design -your URLs to be as pretty as the rest of your application. +A clean, elegant URL scheme is an important detail in a high-quality Web +application. Django lets you design URLs however you want, with no framework +limitations. -See `the Django overview`_ for a quick introduction to URL configurations; this -document will continue from there. +There's no ``.php`` or ``.cgi`` required, and certainly none of that +``0,2097,1-1-1928,00`` nonsense. -.. _`the Django overview`: http://www.djangoproject.com/documentation/overview/#design-your-urls +See `Cool URIs don't change`_, by World Wide Web creator Tim Berners-Lee, for +excellent arguments on why URLs should be clean and usable. -The view prefix -=============== +.. _http://www.w3.org/Provider/Style/URI: Cool URIs don't change -Here's the example from that overview:: +Overview +======== + +To design URLs for an app, you create a Python module informally called a +**URLconf** (URL configuration). This module is pure Python code and +is a simple mapping between URL patterns (as simple regular expressions) to +Python callback functions (your views). + +This mapping can be as short or as long as needed. It can reference other +mappings. And, because it's pure Python code, it can be constructed +dynamically. + +How Django processes a request +============================== + +When a user requests a page from your Django-powered site, this is the +algorithm the system follows to determine which Python code to execute: + + 1. The system looks at the ``ROOT_URLCONF`` setting in your + `settings file`_. This should be a string representing the full Python + import path to your URLconf. For example: ``"mydjangoapps.urls"``. + 2. The system loads that Python module and looks for the variable + ``urlpatterns``. This should be a Python list, in the format returned + by the function ``django.conf.urls.defaults.patterns()``. + 3. The system runs through each URL pattern, in order, and stops at the + first one that matches the requested URL. + 4. Once one of the regexes matches, Django imports and calls the given + view, which is a simple Python function. The view gets passed a + `request object`_ and any values captured in the regex as keyword + arguments. + +.. _settings file: http://www.djangoproject.com/documentation/settings/ +.. _request object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects + +Example +======= + +Here's a sample URLconf:: from django.conf.urls.defaults import * urlpatterns = patterns('', - (r'^/articles/(?P\d{4})/$', 'myproject.news.views.articles.year_archive'), - (r'^/articles/(?P\d{4})/(?P\d{2})/$', 'myproject.news.views.articles.month_archive'), - (r'^/articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'myproject.news.views.articles.article_detail'), + (r'^/articles/2003/$', 'news.views.special_case_2003'), + (r'^/articles/(?P\d{4})/$', 'news.views.year_archive'), + (r'^/articles/(?P\d{4})/(?P\d{2})/$', 'news.views.month_archive'), + (r'^/articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'news.views.article_detail'), ) -The first argument to ``patterns`` is an empty string in the above example, but -that argument can be useful. The first argument is prepended to all the view -functions in the urlpatterns list, so the above example could be written more -concisely as:: +Notes: - urlpatterns = patterns('myproject.news.views.articles', + * ``from django.conf.urls.defaults import *`` makes the ``patterns`` + function available. + + * To capture a value from the URL, use the syntax ``(?Ppattern)``, + where ``name`` is the name for that value and ``pattern`` is some pattern + to match. + + * The ``"r"`` in front of each regular expression string is optional but + recommended. It tells Python that a string is "raw" -- that nothing in + the string should be escaped. See `Dive Into Python's explanation`_. + +Examples: + + * A request to ``/articles/2005/03/`` would match the third entry in the + list. Django would call the function + ``news.views.month_archive(request, year='2005', month='03')``. + + * ``/articles/2005/3/`` would not match any URL patterns, because the + third entry in the list requires two digits for the month. + + * ``/articles/2003/`` would match the first pattern in the list, not the + second one, because the patterns are tested in order, and the first one + is the first test to pass. Feel free to exploit the ordering to insert + special cases like this. + + * ``/articles/2003`` would not match any of these patterns, because each + pattern requires that the URL end with a slash. + + * ``/articles/2003/03/3/`` would match the final pattern. Django would call + the function + ``news.views.article_detail(request, year='2003', month='03', day='3')``. + +.. _Dive Into Python's explanation: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3 + +What the URLconf searches against +================================= + +The URLconf searches against the requested URL, as a normal Python string. This +does not include GET or POST parameters, or the domain name. + +For example, in a request to ``http://www.example.com/myapp/``, the URLconf +will look for ``/myapp/``. + +In a request to ``http://www.example.com/myapp/?page=3``, the URLconf will look +for ``/myapp/``. + +Syntax of the urlpatterns variable +================================== + +``urlpatterns`` should be a Python list, in the format returned by the function +``django.conf.urls.defaults.patterns()``. Always use ``patterns()`` to create +the ``urlpatterns`` variable. + +Convention is to use ``from django.conf.urls.defaults import *`` at the top of +your URLconf. This gives your module access to these objects: + +patterns +-------- + +A function that takes a prefix an arbitrary number of URL patterns and returns +a list of URL patterns in the format Django needs. + +The first argument to ``patterns()`` is a string ``prefix``. See +"The view prefix" below. + +The remaining arguments should be tuples in this format:: + + (regular expression, Python callback function [, optional dictionary]) + +...where ``dictionary_of_extra_arguments`` is optional. (See +"Passing extra options to view functions" below.) + +handler404 +---------- + +A string representing the full Python import path to the view that should be +called if none of the URL patterns match. + +By default, this is ``'django.views.defaults.page_not_found'``. That default +value should suffice. + +handler500 +---------- + +A string representing the full Python import path to the view that should be +called in case of server errors. Server errors happen when you have runtime +errors in view code. + +By default, this is ``'django.views.defaults.server_error'``. That default +value should suffice. + +include +------- + +A function that takes a full Python import path to another URLconf that should +be "included" in this place. See "Including other URLconfs" below. + +Notes on capturing text in URLs +=============================== + +Each captured argument is sent to the view as a plain Python string, regardless +of what sort of match the regular expression makes. For example, in this +URLconf:: + + (r'^/articles/(?P\d{4})/$', 'news.views.year_archive'), + +...the ``year`` argument to ``news.views.year_archive()`` will be a string, not +an integer, even though the ``\d{4}`` will only match integer strings. + +A convenient trick is to specify default parameters for your views' arguments. +Here's an example URLconf and view:: + + # URLconf + urlpatterns = patterns('', + (r'^/blog/$', 'blog.views.page'), + (r'^/blog/page(?P\d+)/$', 'blog.views.page'), + ) + + # View (in blog/views.py) + def page(request, num="1"): + # Output the appropriate page of blog entries, according to num. + +In the above example, both URL patterns point to the same view -- +``blog.views.page`` -- but the first pattern doesn't capture anything from the +URL. If the first pattern matches, the ``page()`` function will use its +default argument for ``num``, ``"1"``. If the second pattern matches, +``page()`` will use whatever ``num`` value was captured by the regex. + +Performance +=========== + +Each regular expression in a ``urlpatterns`` is compiled the first time it's +accessed. This makes the system blazingly fast. + +The view prefix +=============== + +You can specify a common prefix in your ``patterns()`` call, to cut down on +code duplication. + +Here's the example URLconf from the `Django overview`_:: + + from django.conf.urls.defaults import * + + urlpatterns = patterns('', + (r'^/articles/(?P\d{4})/$', 'myproject.news.views.year_archive'), + (r'^/articles/(?P\d{4})/(?P\d{2})/$', 'myproject.news.views.month_archive'), + (r'^/articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'myproject.news.views.article_detail'), + ) + +In this example, each view has a common prefix -- ``"myproject.news.views"``. +Instead of typing that out for each entry in ``urlpatterns``, you can use the +first argument to the ``patterns()`` function to specify a prefix to apply to +each view function. + +With this in mind, the above example can be written more concisely as:: + + from django.conf.urls.defaults import * + + urlpatterns = patterns('myproject.news.views', (r'^/articles/(?P\d{4})/$', 'year_archive'), (r'^/articles/(?P\d{4})/(?P\d{2})/$', 'month_archive'), (r'^/articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'article_detail'), ) -.. admonition:: Note - - More precisely, the actual view function used is ``prefix + "." + - function_name``. The trailing "dot" does not need to be put in the prefix. +Note that you don't put a trailing dot (``"."``) in the prefix. Django puts +that in automatically. Including other URLconfs ======================== -You can also "include" other URLconf modules at any point along the path. This -essentially "roots" a set of URLs below other ones. This is most often used -for a site's "base" URLconf; the ``ROOT_URLCONF`` setting points to a urlconf -module that will be used for the entire site. Here's the URLconf for the -`Django website`_ itself. It includes a number of other URLconfs:: +At any point, your ``urlpatterns`` can "include" other URLconf modules. This +essentially "roots" a set of URLs below other ones. + +For example, here's the URLconf for the `Django website`_ itself. It includes a +number of other URLconfs:: from django.conf.urls.defaults import * @@ -70,6 +262,7 @@ URLconfs, so the following example is valid:: urlpatterns = patterns('foo.views' (r'^$', 'blog.index'), (r'^archive/$', 'blog.archive'), + ) In the above example, the captured ``"username"`` variable is passed to the included URLconf, as expected. @@ -79,11 +272,25 @@ included URLconf, as expected. Passing extra options to view functions ======================================= -There are two ways of passing arguments into your view functions: named captures -from the regex (which you've already seen) and the optional third element -in URLconf tuples. This third element can be a dictionary of extra keyword -arguments that will be passed to the view function:: +URLconfs have a hook that lets you pass extra arguments to your view functions, +as a Python dictionary. - urlpatterns = patterns('myproject.news.views.articles', - (r'^/articles/(?P\d{4})/$', 'year_archive', {key: value, key2: value2}), +Any URLconf tuple can have an optional third element, which should be a +dictionary of extra keyword arguments to pass to the view function. + +For example:: + + urlpatterns = patterns('blog.views', + (r'^/blog/(?P\d{4})/$', 'year_archive', {'foo': 'bar'}), ) + +In this example, for a request to ``/blog/2005/``, Django will call the +``blog.views.year_archive()`` view, passing it these keyword arguments:: + + year='2005', foo='bar' + +This technique is used in `generic views`_ and in the `syndication framework`_ +to pass metadata and options to views. + +.. _generic views: http://www.djangoproject.com/documentation/generic_views/ +.. _syndication framework: http://www.djangoproject.com/documentation/syndication/ From c5068ff4acb44cd2d30794618b972e7c045290be Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 19 Nov 2005 18:28:08 +0000 Subject: [PATCH 4/9] Fixed ReST bugs in [1291] git-svn-id: http://code.djangoproject.com/svn/django/trunk@1292 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/url_dispatch.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt index d08ba702f6..a18d5e9c18 100644 --- a/docs/url_dispatch.txt +++ b/docs/url_dispatch.txt @@ -12,7 +12,7 @@ There's no ``.php`` or ``.cgi`` required, and certainly none of that See `Cool URIs don't change`_, by World Wide Web creator Tim Berners-Lee, for excellent arguments on why URLs should be clean and usable. -.. _http://www.w3.org/Provider/Style/URI: Cool URIs don't change +.. _Cool URIs don't change: http://www.w3.org/Provider/Style/URI Overview ======== @@ -232,6 +232,8 @@ With this in mind, the above example can be written more concisely as:: Note that you don't put a trailing dot (``"."``) in the prefix. Django puts that in automatically. +.. _Django overview: http://www.djangoproject.com/documentation/overview/ + Including other URLconfs ======================== From 34560e0776e9ca090298df3fea2344743d5664cb Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 19 Nov 2005 20:20:13 +0000 Subject: [PATCH 5/9] Fixed typo in docs/model-api.txt. Thanks, anl git-svn-id: http://code.djangoproject.com/svn/django/trunk@1293 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/model-api.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/model-api.txt b/docs/model-api.txt index 1864de7e6a..e58df9df01 100644 --- a/docs/model-api.txt +++ b/docs/model-api.txt @@ -580,7 +580,7 @@ relationship should work. All are optional: Many-to-many relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~ -To define a many-to-one relationship, use ``ManyToManyField``. You use it just +To define a many-to-many relationship, use ``ManyToManyField``. You use it just like any other ``Field`` type: by including it as a class attribute of your model. From 72d8e07de42639fb653f62ff5a135d42b818b7b2 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sun, 20 Nov 2005 04:53:28 +0000 Subject: [PATCH 6/9] Fixed #846 -- Fixed bug in docs/syndication_feeds.txt. Thanks, deric git-svn-id: http://code.djangoproject.com/svn/django/trunk@1295 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/syndication_feeds.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/syndication_feeds.txt b/docs/syndication_feeds.txt index 94c10180ad..d234c2b7ec 100644 --- a/docs/syndication_feeds.txt +++ b/docs/syndication_feeds.txt @@ -328,7 +328,11 @@ Feed class reference This example illustrates all possible attributes and methods for a ``Feed`` class:: - class ExampleFeed(rss.Feed): + + from django.contrib.syndication.feeds import Feed + from django.utils import feedgenerator + + class ExampleFeed(Feed): # FEED TYPE -- Optional. This should be a class that subclasses # django.utils.feedgenerator.SyndicationFeed. This designates which From 09f32294e8a6b9f65bca44c252f78a904e9c3515 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sun, 20 Nov 2005 04:55:57 +0000 Subject: [PATCH 7/9] Fixed #845 -- flatpages middleware no longer throws 404 exception for DEBUG=True. Thanks, Hugo git-svn-id: http://code.djangoproject.com/svn/django/trunk@1296 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/flatpages/middleware.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/django/contrib/flatpages/middleware.py b/django/contrib/flatpages/middleware.py index 9c4e0bb44e..c6f286563d 100644 --- a/django/contrib/flatpages/middleware.py +++ b/django/contrib/flatpages/middleware.py @@ -1,4 +1,5 @@ from django.contrib.flatpages.views import flatpage +from django.core.extensions import Http404 from django.conf.settings import DEBUG class FlatpageFallbackMiddleware: @@ -9,6 +10,8 @@ class FlatpageFallbackMiddleware: return flatpage(request, request.path) # Return the original response if any errors happened. Because this # is a middleware, we can't assume the errors will be caught elsewhere. + except Http404: + return response except: if DEBUG: raise From b5feff39632e744bd63db7064b0056717a57288e Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sun, 20 Nov 2005 05:17:15 +0000 Subject: [PATCH 8/9] Fixed #842 -- 500 error view no longer breaks for local variable named 'items'. Thanks, rjwittams git-svn-id: http://code.djangoproject.com/svn/django/trunk@1297 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/views/debug.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django/views/debug.py b/django/views/debug.py index 0ddaa44a7f..4aece9443d 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -25,7 +25,7 @@ def technical_500_response(request, exc_type, exc_value, tb): 'filename' : filename, 'function' : function, 'lineno' : lineno, - 'vars' : tb.tb_frame.f_locals, + 'vars' : tb.tb_frame.f_locals.items(), 'id' : id(tb), 'pre_context' : pre_context, 'context_line' : context_line, @@ -253,7 +253,7 @@ TECHNICAL_500_TEMPLATE = """ - {% for var in frame.vars.items|dictsort:"0" %} + {% for var in frame.vars|dictsort:"0" %} {{ var.0 }}
{{ var.1|pprint|escape }}
From 85c50d4fdfb4011068932f4f26fbd5a7d77caf25 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sun, 20 Nov 2005 05:17:55 +0000 Subject: [PATCH 9/9] Fixed #839 -- Fixed typo in docs/cache.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1298 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/cache.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cache.txt b/docs/cache.txt index c426811219..8f81514e66 100644 --- a/docs/cache.txt +++ b/docs/cache.txt @@ -93,7 +93,7 @@ entire site. Just add ``django.middleware.cache.CacheMiddleware`` to your (The order of ``MIDDLEWARE_CLASSES`` matters. See "Order of MIDDLEWARE_CLASSES" below.) -Then, add the following three required settings to your Django settings file: +Then, add the following required settings to your Django settings file: * ``CACHE_MIDDLEWARE_SECONDS`` -- The number of seconds each page should be cached.