diff options
Diffstat (limited to 'docs')
48 files changed, 774 insertions, 233 deletions
diff --git a/docs/faq/index.txt b/docs/faq/index.txt index 347cabaabc..b7281946ee 100644 --- a/docs/faq/index.txt +++ b/docs/faq/index.txt @@ -11,4 +11,5 @@ Django FAQ help models admin - contributing
\ No newline at end of file + contributing + troubleshooting
\ No newline at end of file diff --git a/docs/faq/troubleshooting.txt b/docs/faq/troubleshooting.txt new file mode 100644 index 0000000000..f984be4bf5 --- /dev/null +++ b/docs/faq/troubleshooting.txt @@ -0,0 +1,16 @@ +=============== +Troubleshooting +=============== + +This page contains some advice about errors and problems commonly encountered +during the development of Django applications. + +"command not found: django-admin.py" +------------------------------------ + +:doc:`django-admin.py </ref/django-admin>` should be on your system path if you +installed Django via ``python setup.py``. If it's not on your path, you can +find it in ``site-packages/django/bin``, where ``site-packages`` is a directory +within your Python installation. Consider symlinking to :doc:`django-admin.py +</ref/django-admin>` from some place on your path, such as +:file:`/usr/local/bin`.
\ No newline at end of file diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt index 706cc25129..e73ef9aa42 100644 --- a/docs/howto/custom-model-fields.txt +++ b/docs/howto/custom-model-fields.txt @@ -688,7 +688,7 @@ smoothly: 2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're wrapping up as a field. There are a lot of places where the default behavior of the field code is to call - :func:`~django.utils.encoding.force_unicode` on the value. (In our + :func:`~django.utils.encoding.force_text` on the value. (In our examples in this document, ``value`` would be a ``Hand`` instance, not a ``HandField``). So if your :meth:`__unicode__` method automatically converts to the string form of your Python object, you can save yourself diff --git a/docs/index.txt b/docs/index.txt index 50e8471b14..011ecdb0bc 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -34,6 +34,8 @@ Having trouble? We'd like to help! First steps =========== +Are you new to Django or to programming? This is the place to start! + * **From scratch:** :doc:`Overview <intro/overview>` | :doc:`Installation <intro/install>` @@ -47,6 +49,9 @@ First steps The model layer =============== +Django provides an abstraction layer (the "models") for structuring and +manipulating the data of your Web application. Learn more about it below: + * **Models:** :doc:`Model syntax <topics/db/models>` | :doc:`Field types <ref/models/fields>` | @@ -74,20 +79,13 @@ The model layer :doc:`Providing initial data <howto/initial-data>` | :doc:`Optimize database access <topics/db/optimization>` -The template layer -================== - -* **For designers:** - :doc:`Syntax overview <topics/templates>` | - :doc:`Built-in tags and filters <ref/templates/builtins>` - -* **For programmers:** - :doc:`Template API <ref/templates/api>` | - :doc:`Custom tags and filters <howto/custom-template-tags>` - The view layer ============== +Django has the concept of "views" to encapsulate the logic responsible for +processing a user's request and for returning the response. Find all you need +to know about views via the links below: + * **The basics:** :doc:`URLconfs <topics/http/urls>` | :doc:`View functions <topics/http/views>` | @@ -118,9 +116,29 @@ The view layer :doc:`Overview <topics/http/middleware>` | :doc:`Built-in middleware classes <ref/middleware>` +The template layer +================== + +The template layer provides a designer-friendly syntax for rendering the +information to be presented to the user. Learn how this syntax can be used by +designers and how it can be extended by programmers: + +* **For designers:** + :doc:`Syntax overview <topics/templates>` | + :doc:`Built-in tags and filters <ref/templates/builtins>` | + :doc:`Web design helpers <ref/contrib/webdesign>` | + :doc:`Humanization <ref/contrib/humanize>` + +* **For programmers:** + :doc:`Template API <ref/templates/api>` | + :doc:`Custom tags and filters <howto/custom-template-tags>` + Forms ===== +Django provides a rich framework to facilitate the creation of forms and the +manipulation of form data. + * **The basics:** :doc:`Overview <topics/forms/index>` | :doc:`Form API <ref/forms/api>` | @@ -140,6 +158,9 @@ Forms The development process ======================= +Learn about the various components and tools to help you in the development and +testing of Django applications: + * **Settings:** :doc:`Overview <topics/settings>` | :doc:`Full list of settings <ref/settings>` @@ -161,51 +182,99 @@ The development process :doc:`Handling static files <howto/static-files>` | :doc:`Tracking code errors by email <howto/error-reporting>` -Other batteries included -======================== +The admin +========= -* :doc:`Admin site <ref/contrib/admin/index>` | :doc:`Admin actions <ref/contrib/admin/actions>` | :doc:`Admin documentation generator<ref/contrib/admin/admindocs>` -* :doc:`Authentication <topics/auth>` -* :doc:`Cache system <topics/cache>` +Find all you need to know about the automated admin interface, one of Django's +most popular features: + +* :doc:`Admin site <ref/contrib/admin/index>` +* :doc:`Admin actions <ref/contrib/admin/actions>` +* :doc:`Admin documentation generator<ref/contrib/admin/admindocs>` + +Security +======== + +Security is a topic of paramount importance in the development of Web +applications and Django provides multiple protection tools and mechanisms: + +* :doc:`Security overview <topics/security>` * :doc:`Clickjacking protection <ref/clickjacking>` -* :doc:`Comments <ref/contrib/comments/index>` | :doc:`Moderation <ref/contrib/comments/moderation>` | :doc:`Custom comments <ref/contrib/comments/custom>` -* :doc:`Conditional content processing <topics/conditional-view-processing>` -* :doc:`Content types and generic relations <ref/contrib/contenttypes>` * :doc:`Cross Site Request Forgery protection <ref/contrib/csrf>` * :doc:`Cryptographic signing <topics/signing>` -* :doc:`Databrowse <ref/contrib/databrowse>` -* :doc:`E-mail (sending) <topics/email>` -* :doc:`Flatpages <ref/contrib/flatpages>` -* :doc:`GeoDjango <ref/contrib/gis/index>` -* :doc:`Humanize <ref/contrib/humanize>` + +Internationalization and localization +===================================== + +Django offers a robust internationalization and localization framework to +assist you in the development of applications for multiple languages and world +regions: + * :doc:`Internationalization <topics/i18n/index>` -* :doc:`Jython support <howto/jython>` * :doc:`"Local flavor" <ref/contrib/localflavor>` + +Python compatibility +==================== + +Django aims to be compatible with multiple different flavors and versions of +Python: + +* :doc:`Jython support <howto/jython>` +* :doc:`Python 3 compatibility <topics/python3>` + +Geographic framework +==================== + +:doc:`GeoDjango <ref/contrib/gis/index>` intends to be a world-class geographic +Web framework. Its goal is to make it as easy as possible to build GIS Web +applications and harness the power of spatially enabled data. + +Common Web application tools +============================ + +Django offers multiple tools commonly needed in the development of Web +applications: + +* :doc:`Authentication <topics/auth>` +* :doc:`Caching <topics/cache>` * :doc:`Logging <topics/logging>` -* :doc:`Messages <ref/contrib/messages>` +* :doc:`Sending e-mails <topics/email>` +* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>` +* :doc:`Comments <ref/contrib/comments/index>`, :doc:`comment moderation <ref/contrib/comments/moderation>` and :doc:`custom comments <ref/contrib/comments/custom>` * :doc:`Pagination <topics/pagination>` -* :doc:`Python 3 compatibility <topics/python3>` -* :doc:`Redirects <ref/contrib/redirects>` -* :doc:`Security <topics/security>` +* :doc:`Messages framework <ref/contrib/messages>` * :doc:`Serialization <topics/serialization>` * :doc:`Sessions <topics/http/sessions>` -* :doc:`Signals <topics/signals>` * :doc:`Sitemaps <ref/contrib/sitemaps>` -* :doc:`Sites <ref/contrib/sites>` -* :doc:`Static Files <ref/contrib/staticfiles>` -* :doc:`Syndication feeds (RSS/Atom) <ref/contrib/syndication>` +* :doc:`Static files management <ref/contrib/staticfiles>` +* :doc:`Data validation <ref/validators>` + +Other core functionalities +========================== + +Learn about some other core functionalities of the Django framework: + +* :doc:`Conditional content processing <topics/conditional-view-processing>` +* :doc:`Content types and generic relations <ref/contrib/contenttypes>` +* :doc:`Databrowse <ref/contrib/databrowse>` +* :doc:`Flatpages <ref/contrib/flatpages>` +* :doc:`Redirects <ref/contrib/redirects>` +* :doc:`Signals <topics/signals>` +* :doc:`The sites framework <ref/contrib/sites>` * :doc:`Unicode in Django <ref/unicode>` -* :doc:`Web design helpers <ref/contrib/webdesign>` -* :doc:`Validators <ref/validators>` The Django open-source project ============================== +Learn about the development process for the Django project itself and about how +you can contribute: + * **Community:** :doc:`How to get involved <internals/contributing/index>` | :doc:`The release process <internals/release-process>` | :doc:`Team of committers <internals/committers>` | - :doc:`The Django source code repository <internals/git>` + :doc:`The Django source code repository <internals/git>` | + :doc:`Security policies <internals/security>` * **Design philosophies:** :doc:`Overview <misc/design-philosophies>` diff --git a/docs/internals/committers.txt b/docs/internals/committers.txt index fb601a24c0..5567c26fa1 100644 --- a/docs/internals/committers.txt +++ b/docs/internals/committers.txt @@ -149,6 +149,7 @@ Joseph Kocherhans .. _brian rosner: http://brosner.com/ .. _eldarion: http://eldarion.com/ .. _django dose: http://djangodose.com/ +.. _pinax: http://pinaxproject.com/ `Gary Wilson`_ Gary starting contributing patches to Django in 2006 while developing Web @@ -174,7 +175,7 @@ Justin Bronn implementing GeoDjango, Justin obtained a deep knowledge of Django's internals including the ORM, the admin, and Oracle support. - Justin lives in Houston, Texas. + Justin lives in San Francisco, CA. .. _GeoDjango: http://geodjango.org/ diff --git a/docs/internals/contributing/bugs-and-features.txt b/docs/internals/contributing/bugs-and-features.txt index 76a2bd2374..91a078cbc0 100644 --- a/docs/internals/contributing/bugs-and-features.txt +++ b/docs/internals/contributing/bugs-and-features.txt @@ -2,7 +2,16 @@ Reporting bugs and requesting features ====================================== -Before reporting a bug or requesting a new feature, please consider these +.. Important:: + + Please report security issues **only** to + security@djangoproject.com. This is a private list only open to + long-time, highly trusted Django developers, and its archives are + not public. For further details, please see :doc:`our security + policies </internals/security>`. + + +Otherwise, before reporting a bug or requesting a new feature, please consider these general points: * Check that someone hasn't already filed the bug or feature request by @@ -55,40 +64,6 @@ To understand the lifecycle of your ticket once you have created it, refer to .. _reporting-security-issues: -Reporting security issues -------------------------- - -.. Important:: - - Please report security issues **only** to security@djangoproject.com. - This is a private list only open to long-time, highly trusted Django - developers, and its archives are not publicly readable. - -In the event of a confirmed vulnerability in Django itself, we will take the -following actions: - -* Acknowledge to the reporter that we've received the report and that a - fix is forthcoming. We'll give a rough timeline and ask the reporter - to keep the issue confidential until we announce it. - -* Focus on developing a fix as quickly as possible and produce patches - against the current and two previous releases. - -* Determine a go-public date for announcing the vulnerability and the fix. - To try to mitigate a possible "arms race" between those applying the - patch and those trying to exploit the hole, we will not announce - security problems immediately. - -* Pre-notify third-party distributors of Django ("vendors"). We will send - these vendor notifications through private email which will include - documentation of the vulnerability, links to the relevant patch(es), and - a request to keep the vulnerability confidential until the official - go-public date. - -* Publicly announce the vulnerability and the fix on the pre-determined - go-public date. This will probably mean a new release of Django, but - in some cases it may simply be patches against current releases. - Reporting user interface bugs and features ------------------------------------------ diff --git a/docs/internals/index.txt b/docs/internals/index.txt index 3dba550fed..3ff4eb62d0 100644 --- a/docs/internals/index.txt +++ b/docs/internals/index.txt @@ -18,6 +18,7 @@ the hood". contributing/index committers + security release-process deprecation git diff --git a/docs/internals/release-process.txt b/docs/internals/release-process.txt index 97adb4a3f6..8affddb5e0 100644 --- a/docs/internals/release-process.txt +++ b/docs/internals/release-process.txt @@ -31,10 +31,14 @@ Since version 1.0, Django's release numbering works as follows: These are of the form ``A.B alpha/beta/rc N``, which means the ``Nth`` alpha/beta/release candidate of version ``A.B``. -In Subversion, each Django release will be tagged under ``tags/releases``. If -it's necessary to release a bug fix release or a security release that doesn't -come from the trunk, we'll copy that tag to ``branches/releases`` to make the -bug fix release. +In git, each Django release will have a tag indicating its version +number, signed with the Django release key. Additionally, each release +series (X.Y) has its own branch, and bugfix/security releases will be +issued from those branches. + +For more information about how the Django project issues new releases +for security purposes, please see :doc:`our security policies +<security>`. Major releases -------------- diff --git a/docs/internals/security.txt b/docs/internals/security.txt new file mode 100644 index 0000000000..7121ff31ec --- /dev/null +++ b/docs/internals/security.txt @@ -0,0 +1,215 @@ +========================== +Django's security policies +========================== + +Django's development team is strongly committed to responsible +reporting and disclosure of security-related issues. As such, we've +adopted and follow a set of policies which conform to that ideal and +are geared toward allowing us to deliver timely security updates to +the official distribution of Django, as well as to third-party +distributions. + +.. _reporting-security-issues: + +Reporting security issues +========================= + +**Short version: please report security issues by emailing +security@djangoproject.com**. + +Most normal bugs in Django are reported to `our public Trac +instance`_, but due to the sensitive nature of security issues, we ask +that they *not* be publicly reported in this fashion. + +Instead, if you believe you've found something in Django which has +security implications, please send a description of the issue via +email to ``security@djangoproject.com``. Mail sent to that address +reaches a subset of the core development team, who can forward +security issues into the private committers' mailing list for broader +discussion if needed. + +You can send encrypted email to this address; the public key ID for +``security@djangoproject.com`` is ``0xfcb84b8d1d17f80b``, and this +public key is available from most commonly-used keyservers. + +Once you've submitted an issue via email, you should receive an +acknowledgment from a member of the Django development team within 48 +hours, and depending on the action to be taken, you may receive +further followup emails. + +.. _our public Trac instance: https://code.djangoproject.com/query + +.. _security-support: + +Supported versions +================== + +At any given time, the Django team provides official security support +for several versions of Django: + +* The `master development branch`_, hosted on GitHub, which will + become the next release of Django, receives security support. + +* The two most recent Django release series receive security + support. For example, during the development cycle leading to the + release of Django 1.5, support will be provided for Django 1.4 and + Django 1.3. Upon the release of Django 1.5, Django 1.3's security + support will end. + +When new releases are issued for security reasons, the accompanying +notice will include a list of affected versions. This list is +comprised solely of *supported* versions of Django: older versions may +also be affected, but we do not investigate to determine that, and +will not issue patches or new releases for those versions. + +.. _master development branch: https://github.com/django/django/ + +.. _security-disclosure: + +How Django discloses security issues +==================================== + +Our process for taking a security issue from private discussion to +public disclosure involves multiple steps. + +Approximately one week before full public disclosure, we will send +advance notification of the issue to a list of people and +organizations, primarily composed of operating-system vendors and +other distributors of Django. This notification will consist of an +email message, signed with the Django release key, containing: + +* A full description of the issue and the affected versions of Django. + +* The steps we will be taking to remedy the issue. + +* The patch(es), if any, that will be applied to Django. + +* The date on which the Django team will apply these patches, issue + new releases and publicy disclose the issue. + +Simultaneously, the reporter of the issue will receive notification of +the date on which we plan to take the issue public. + +On the day of disclosure, we will take the following steps: + +1. Apply the relevant patch(es) to Django's codebase. The commit + messages for these patches will indicate that they are for security + issues, but will not describe the issue in any detail; instead, + they will warn of upcoming disclosure. + +2. Issue the relevant release(s), by placing new packages on `the + Python Package Index`_ and on the Django website, and tagging the + new release(s) in Django's git repository. + +3. Post a public entry on `the official Django development blog`_, + describing the issue and its resolution in detail, pointing to the + relevant patches and new releases, and crediting the reporter of + the issue (if the reporter wishes to be publicly identified). + +.. _the Python Package Index: http://pypi.python.org/pypi +.. _the official Django development blog: https://www.djangoproject.com/weblog/ + +If a reported issue is believed to be particularly time-sensitive -- +due to a known exploit in the wild, for example -- the time between +advance notification and public disclosure may be shortened +considerably. + +Additionally, if we have reason to believe that an issue reported to +us affects other frameworks or tools in the Python/web ecosystem, we +may privately contact and discuss those issues with the appropriate +maintainers, and coordinate our own disclosure and resolution with +theirs. + +.. _security-notifications: + +Who receives advance notification +================================= + +The full list of people and organizations who receive advance +notification of security issues is not and will not be made public. + +We also aim to keep this list as small as effectively possible, in +order to better manage the flow of confidential information prior to +disclosure. As such, our notification list is *not* simply a list of +users of Django, and merely being a user of Django is not sufficient +reason to be placed on the notification list. + +In broad terms, recipients of security notifications fall into three +groups: + +1. Operating-system vendors and other distributors of Django who + provide a suitably-generic (i.e., *not* an individual's personal + email address) contact address for reporting issues with their + Django package, or for general security reporting. In either case, + such addresses **must not** forward to public mailing lists or bug + trackers. Addresses which forward to the private email of an + individual maintainer or security-response contact are acceptable, + although private security trackers or security-response groups are + strongly preferred. + +2. On a case-by-case basis, individual package maintainers who have + demonstrated a commitment to responding to and responsibly acting + on these notifications. + +3. On a case-by-case basis, other entities who, in the judgment of the + Django development team, need to be made aware of a pending + security issue. Typically, membership in this group will consist of + some of the largest and/or most likely to be severely impacted + known users or distributors of Django, and will require a + demonstrated ability to responsibly receive, keep confidential and + act on these notifications. + +Additionally, a maximum of six days prior to disclosure, notification +will be sent to the ``distros@vs.openwall.org`` mailing list, whose +membership includes representatives of most major open-source +operating system vendors. + +Requesting notifications +======================== + +If you believe that you, or an organization you are authorized to +represent, fall into one of the groups listed above, you can ask to be +added to Django's notification list by emailing +``security@djangoproject.com``. Please use the subject line "Security +notification request". + +Your request **must** include the following information: + +* Your full, real name and the name of the organization you represent, + if applicable, as well as your role within that organization. + +* A detailed explanation of how you or your organization fit at least + one set of criteria listed above. + +* A detailed explanation of why you are requesting security + notifications. Again, please keep in mind that this is *not* simply + a list for users of Django, and the overwhelming majority of users + of Django should not request notifications and will not be added to + our notification list if they do. + +* The email address you would like to have added to our notification + list. + +* An explanation of who will be receiving/reviewing mail sent to that + address, as well as information regarding any automated actions that + will be taken (i.e., filing of a confidential issue in a bug + tracker). + +* For individuals, the ID of a public key associated with your address + which can be used to verify email received from you and encrypt + email sent to you, as needed. + +Once submitted, your request will be considered by the Django +development team; you will receive a reply notifying you of the result +of your request within 30 days. + +Please also bear in mind that for any individual or organization, +receiving security notifications is a privilege granted at the sole +discretion of the Django development team, and that this privilege can +be revoked at any time, with or without explanation. + +If you are added to the notification list, security-related emails +will be sent to you by Django's release manager, and all notification +emails will be signed with the same key used to sign Django releases; +that key has the ID ``0x3684C0C08C8B2AE1``, and is available from most +commonly-used keyservers.
\ No newline at end of file diff --git a/docs/intro/_images/admin15t.png b/docs/intro/_images/admin15t.png Binary files differnew file mode 100644 index 0000000000..999d0519fb --- /dev/null +++ b/docs/intro/_images/admin15t.png diff --git a/docs/intro/install.txt b/docs/intro/install.txt index 7e8c7db7b3..70c8034c5d 100644 --- a/docs/intro/install.txt +++ b/docs/intro/install.txt @@ -84,8 +84,9 @@ Then at the Python prompt, try to import Django:: >>> import django >>> print(django.get_version()) - 1.4 + 1.5 +You may have another version of Django installed. That's it! ---------- diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt index 250c0f1f41..1e2231d1e0 100644 --- a/docs/intro/tutorial01.txt +++ b/docs/intro/tutorial01.txt @@ -52,7 +52,8 @@ code, then run the following command: django-admin.py startproject mysite -This will create a ``mysite`` directory in your current directory. +This will create a ``mysite`` directory in your current directory. If it didn't +work, see :doc:`Troubleshooting </faq/troubleshooting>`. .. admonition:: Script name may differ in distribution packages @@ -78,13 +79,6 @@ This will create a ``mysite`` directory in your current directory. ``django`` (which will conflict with Django itself) or ``test`` (which conflicts with a built-in Python package). -:doc:`django-admin.py </ref/django-admin>` should be on your system path if you -installed Django via ``python setup.py``. If it's not on your path, you can find -it in ``site-packages/django/bin``, where ``site-packages`` is a directory -within your Python installation. Consider symlinking to :doc:`django-admin.py -</ref/django-admin>` from some place on your path, such as -:file:`/usr/local/bin`. - .. admonition:: Where should this code live? If your background is in PHP, you're probably used to putting code under the diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index 84da36be86..fd13230c8b 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -311,6 +311,14 @@ It works like this: There are three slots for related Choices -- as specified by ``extra`` -- and each time you come back to the "Change" page for an already-created object, you get another three extra slots. +At the end of the three current slots you will find an "Add another Choice" +link. If you click on it, a new slot will be added. If you want to remove the +added slot, you can click on the X to the top right of the added slot. Note +that you can't remove the original three slots. This image shows an added slot: + +.. image:: _images/admin15t.png + :alt: Additional slot added dynamically + One small problem, though. It takes a lot of screen space to display all the fields for entering related ``Choice`` objects. For that reason, Django offers a tabular way of displaying inline related objects; you just need to change diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt index fd3a04ba93..d15b2f43ae 100644 --- a/docs/intro/tutorial03.txt +++ b/docs/intro/tutorial03.txt @@ -533,5 +533,22 @@ under "/content/polls/", or any other path root, and the app will still work. All the poll app cares about is its relative path, not its absolute path. +Removing hardcoded URLs in templates +------------------------------------ + +Remember, when we wrote the link to a poll in our template, the link was +partially hardcoded like this: + +.. code-block:: html+django + + <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li> + +To use the decoupled URLs we've just introduced, replace the hardcoded link +with the :ttag:`url` template tag: + +.. code-block:: html+django + + <li><a href="{% url 'polls.views.detail' poll.id %}">{{ poll.question }}</a></li> + When you're comfortable with writing views, read :doc:`part 4 of this tutorial </intro/tutorial04>` to learn about simple form processing and generic views. diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt index 44b9c16c2a..31680ea5e5 100644 --- a/docs/intro/tutorial04.txt +++ b/docs/intro/tutorial04.txt @@ -18,7 +18,7 @@ tutorial, so that the template contains an HTML ``<form>`` element: {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} - <form action="/polls/{{ poll.id }}/vote/" method="post"> + <form action="{% url 'polls.views.vote' poll.id %}" method="post"> {% csrf_token %} {% for choice in poll.choice_set.all %} <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" /> @@ -35,7 +35,7 @@ A quick rundown: selects one of the radio buttons and submits the form, it'll send the POST data ``choice=3``. This is HTML Forms 101. -* We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we +* We set the form's ``action`` to ``{% url 'polls.views.vote' poll.id %}``, and we set ``method="post"``. Using ``method="post"`` (as opposed to ``method="get"``) is very important, because the act of submitting this form will alter data server-side. Whenever you create a form that alters @@ -172,7 +172,7 @@ Now, create a ``results.html`` template: {% endfor %} </ul> - <a href="/polls/{{ poll.id }}/">Vote again?</a> + <a href="{% url 'polls.views.detail' poll.id %}">Vote again?</a> Now, go to ``/polls/1/`` in your browser and vote in the poll. You should see a results page that gets updated each time you vote. If you submit the form @@ -238,11 +238,13 @@ Change it like so:: ListView.as_view( queryset=Poll.objects.order_by('-pub_date')[:5], context_object_name='latest_poll_list', - template_name='polls/index.html')), + template_name='polls/index.html'), + name='poll_index'), url(r'^(?P<pk>\d+)/$', DetailView.as_view( model=Poll, - template_name='polls/detail.html')), + template_name='polls/detail.html'), + name='poll_detail'), url(r'^(?P<pk>\d+)/results/$', DetailView.as_view( model=Poll, @@ -265,8 +267,8 @@ two views abstract the concepts of "display a list of objects" and ``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic views. -* We've added a name, ``poll_results``, to the results view so - that we have a way to refer to its URL later on (see the +* We've added the ``name`` argument to the views (e.g. ``name='poll_results'``) + so that we have a way to refer to their URL later on (see the documentation about :ref:`naming URL patterns <naming-url-patterns>` for information). We're also using the :func:`~django.conf.urls.url` function from @@ -317,6 +319,13 @@ function anymore -- generic views can be (and are) used multiple times return HttpResponseRedirect(reverse('poll_results', args=(p.id,))) +The same rule apply for the :ttag:`url` template tag. For example in the +``results.html`` template: + +.. code-block:: html+django + + <a href="{% url 'poll_detail' poll.id %}">Vote again?</a> + Run the server, and use your new polling app based on generic views. For full details on generic views, see the :doc:`generic views documentation diff --git a/docs/ref/class-based-views/generic-editing.txt b/docs/ref/class-based-views/generic-editing.txt index d5df369fb3..a65a59bc8b 100644 --- a/docs/ref/class-based-views/generic-editing.txt +++ b/docs/ref/class-based-views/generic-editing.txt @@ -2,7 +2,28 @@ Generic editing views ===================== -The views described here provide a foundation for editing content. +The following views are described on this page and provide a foundation for +editing content: + +* :class:`django.views.generic.edit.FormView` +* :class:`django.views.generic.edit.CreateView` +* :class:`django.views.generic.edit.UpdateView` +* :class:`django.views.generic.edit.DeleteView` + +.. note:: + + Some of the examples on this page assume that a model titled 'Author' + has been defined. For these cases we assume the following has been defined + in `myapp/models.py`:: + + from django import models + from django.core.urlresolvers import reverse + + class Author(models.Model): + name = models.CharField(max_length=200) + + def get_absolute_url(self): + return reverse('author-detail', kwargs={'pk': self.pk}) .. class:: django.views.generic.edit.FormView @@ -11,6 +32,8 @@ The views described here provide a foundation for editing content. **Ancestors (MRO)** + This view inherits methods and attributes from the following views: + * :class:`django.views.generic.edit.FormView` * :class:`django.views.generic.base.TemplateResponseMixin` * :class:`django.views.generic.edit.BaseFormView` @@ -18,6 +41,35 @@ The views described here provide a foundation for editing content. * :class:`django.views.generic.edit.ProcessFormView` * :class:`django.views.generic.base.View` + **Example forms.py**:: + + from django import forms + + class ContactForm(forms.Form): + name = forms.CharField() + message = forms.CharField(widget=forms.Textarea) + + def send_email(self): + # send email using the self.cleaned_data dictionary + pass + + **Example views.py**:: + + from myapp.forms import ContactForm + from django.views.generic.edit import FormView + + class ContactView(FormView): + template_name = 'contact.html' + form_class = ContactForm + success_url = '/thanks/' + + def form_valid(self, form): + # This method is called when valid form data has been POSTed. + # It should return an HttpResponse. + form.send_email() + return super(ContactView, self).form_valid(form) + + .. class:: django.views.generic.edit.CreateView A view that displays a form for creating an object, redisplaying the form @@ -25,6 +77,8 @@ The views described here provide a foundation for editing content. **Ancestors (MRO)** + This view inherits methods and attributes from the following views: + * :class:`django.views.generic.edit.CreateView` * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin` * :class:`django.views.generic.base.TemplateResponseMixin` @@ -35,6 +89,24 @@ The views described here provide a foundation for editing content. * :class:`django.views.generic.edit.ProcessFormView` * :class:`django.views.generic.base.View` + **Attributes** + + .. attribute:: template_name_suffix + + The CreateView page displayed to a GET request uses a + ``template_name_suffix`` of ``'_form.html'``. For + example, changing this attribute to ``'_create_form.html'`` for a view + creating objects for the the example `Author` model would cause the the + default `template_name` to be ``'myapp/author_create_form.html'``. + + **Example views.py**:: + + from django.views.generic.edit import CreateView + from myapp.models import Author + + class AuthorCreate(CreateView): + model = Author + .. class:: django.views.generic.edit.UpdateView A view that displays a form for editing an existing object, redisplaying @@ -44,6 +116,8 @@ The views described here provide a foundation for editing content. **Ancestors (MRO)** + This view inherits methods and attributes from the following views: + * :class:`django.views.generic.edit.UpdateView` * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin` * :class:`django.views.generic.base.TemplateResponseMixin` @@ -54,6 +128,24 @@ The views described here provide a foundation for editing content. * :class:`django.views.generic.edit.ProcessFormView` * :class:`django.views.generic.base.View` + **Attributes** + + .. attribute:: template_name_suffix + + The UpdateView page displayed to a GET request uses a + ``template_name_suffix`` of ``'_form.html'``. For + example, changing this attribute to ``'_update_form.html'`` for a view + updating objects for the the example `Author` model would cause the the + default `template_name` to be ``'myapp/author_update_form.html'``. + + **Example views.py**:: + + from django.views.generic.edit import UpdateView + from myapp.models import Author + + class AuthorUpdate(UpdateView): + model = Author + .. class:: django.views.generic.edit.DeleteView A view that displays a confirmation page and deletes an existing object. @@ -63,6 +155,8 @@ The views described here provide a foundation for editing content. **Ancestors (MRO)** + This view inherits methods and attributes from the following views: + * :class:`django.views.generic.edit.DeleteView` * :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin` * :class:`django.views.generic.base.TemplateResponseMixin` @@ -72,7 +166,23 @@ The views described here provide a foundation for editing content. * :class:`django.views.generic.detail.SingleObjectMixin` * :class:`django.views.generic.base.View` - **Notes** + **Attributes** + + .. attribute:: template_name_suffix + + The DeleteView page displayed to a GET request uses a + ``template_name_suffix`` of ``'_confirm_delete.html'``. For + example, changing this attribute to ``'_check_delete.html'`` for a view + deleting objects for the the example `Author` model would cause the the + default `template_name` to be ``'myapp/author_check_delete.html'``. + + + **Example views.py**:: + + from django.views.generic.edit import DeleteView + from django.core.urlresolvers import reverse_lazy + from myapp.models import Author - * The delete confirmation page displayed to a GET request uses a - ``template_name_suffix`` of ``'_confirm_delete'``. + class AuthorDelete(DeleteView): + model = Author + success_url = reverse_lazy('author-list') diff --git a/docs/ref/class-based-views/index.txt b/docs/ref/class-based-views/index.txt index c10e66b396..f2271d2506 100644 --- a/docs/ref/class-based-views/index.txt +++ b/docs/ref/class-based-views/index.txt @@ -32,9 +32,9 @@ A class-based view is deployed into a URL pattern using the Arguments passed to a view are shared between every instance of a view. This means that you shoudn't use a list, dictionary, or any other - variable object as an argument to a view. If you did, the actions of - one user visiting your view could have an effect on subsequent users - visiting the same view. + mutable object as an argument to a view. If you do and the shared object + is modified, the actions of one user visiting your view could have an + effect on subsequent users visiting the same view. Any argument passed into :meth:`~View.as_view()` will be assigned onto the instance that is used to service a request. Using the previous example, diff --git a/docs/ref/class-based-views/mixins-editing.txt b/docs/ref/class-based-views/mixins-editing.txt index 7258893d63..89610889db 100644 --- a/docs/ref/class-based-views/mixins-editing.txt +++ b/docs/ref/class-based-views/mixins-editing.txt @@ -2,6 +2,18 @@ Editing mixins ============== +The following mixins are used to construct Django's editing views: + +* :class:`django.views.generic.edit.FormMixin` +* :class:`django.views.generic.edit.ModelFormMixin` +* :class:`django.views.generic.edit.ProcessFormView` +* :class:`django.views.generic.edit.DeletionMixin` + +.. note:: + + Examples of how these are combined into editing views can be found at + the documentation on ``Generic editing views``. + .. class:: django.views.generic.edit.FormMixin A mixin class that provides facilities for creating and displaying forms. diff --git a/docs/ref/contrib/admin/_images/article_actions.png b/docs/ref/contrib/admin/_images/article_actions.png Binary files differindex 78a78ae494..1d35e60e5d 100644 --- a/docs/ref/contrib/admin/_images/article_actions.png +++ b/docs/ref/contrib/admin/_images/article_actions.png diff --git a/docs/ref/contrib/admin/_images/article_actions_message.png b/docs/ref/contrib/admin/_images/article_actions_message.png Binary files differindex 6ea9439b8e..16a2d0e197 100644 --- a/docs/ref/contrib/admin/_images/article_actions_message.png +++ b/docs/ref/contrib/admin/_images/article_actions_message.png diff --git a/docs/ref/contrib/admin/_images/user_actions.png b/docs/ref/contrib/admin/_images/user_actions.png Binary files differindex fdbe2ad897..22d40e0181 100644 --- a/docs/ref/contrib/admin/_images/user_actions.png +++ b/docs/ref/contrib/admin/_images/user_actions.png diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index f28aa4687b..4d39981a4d 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -1266,11 +1266,11 @@ provided some extra mapping data that would not otherwise be available:: # ... pass - def change_view(self, request, object_id, extra_context=None): + def change_view(self, request, object_id, form_url='', extra_context=None): extra_context = extra_context or {} extra_context['osm_data'] = self.get_osm_info() return super(MyModelAdmin, self).change_view(request, object_id, - extra_context=extra_context) + form_url, extra_context=extra_context) .. versionadded:: 1.4 diff --git a/docs/ref/contrib/comments/custom.txt b/docs/ref/contrib/comments/custom.txt index 5007ddff69..0ef37a9a0b 100644 --- a/docs/ref/contrib/comments/custom.txt +++ b/docs/ref/contrib/comments/custom.txt @@ -51,9 +51,9 @@ To make this kind of customization, we'll need to do three things: custom :setting:`COMMENTS_APP`. So, carrying on the example above, we're dealing with a typical app structure in -the ``my_custom_app`` directory:: +the ``my_comment_app`` directory:: - my_custom_app/ + my_comment_app/ __init__.py models.py forms.py @@ -98,11 +98,11 @@ Django provides a couple of "helper" classes to make writing certain types of custom comment forms easier; see :mod:`django.contrib.comments.forms` for more. -Finally, we'll define a couple of methods in ``my_custom_app/__init__.py`` to +Finally, we'll define a couple of methods in ``my_comment_app/__init__.py`` to point Django at these classes we've created:: - from my_comments_app.models import CommentWithTitle - from my_comments_app.forms import CommentFormWithTitle + from my_comment_app.models import CommentWithTitle + from my_comment_app.forms import CommentFormWithTitle def get_model(): return CommentWithTitle diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index eda9617381..f4e706d275 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -75,6 +75,17 @@ return a :class:`GEOSGeometry` object from an input string or a file:: >>> pnt = fromfile('/path/to/pnt.wkt') >>> pnt = fromfile(open('/path/to/pnt.wkt')) +.. _geos-exceptions-in-logfile: + +.. admonition:: My logs are filled with GEOS-related errors + + You find many ``TypeError`` or ``AttributeError`` exceptions filling your + Web server's log files. This generally means that you are creating GEOS + objects at the top level of some of your Python modules. Then, due to a race + condition in the garbage collector, your module is garbage collected before + the GEOS object. To prevent this, create :class:`GEOSGeometry` objects + inside the local scope of your functions/methods. + Geometries are Pythonic ----------------------- :class:`GEOSGeometry` objects are 'Pythonic', in other words components may diff --git a/docs/ref/contrib/gis/install.txt b/docs/ref/contrib/gis/install.txt index 5ee6d5153d..72bd72a6f8 100644 --- a/docs/ref/contrib/gis/install.txt +++ b/docs/ref/contrib/gis/install.txt @@ -191,6 +191,8 @@ GEOS C library. For example: The setting must be the *full* path to the **C** shared library; in other words you want to use ``libgeos_c.so``, not ``libgeos.so``. +See also :ref:`My logs are filled with GEOS-related errors <geos-exceptions-in-logfile>`. + .. _proj4: PROJ.4 diff --git a/docs/ref/contrib/humanize.txt b/docs/ref/contrib/humanize.txt index cdc3009a51..57978288b1 100644 --- a/docs/ref/contrib/humanize.txt +++ b/docs/ref/contrib/humanize.txt @@ -103,9 +103,9 @@ naturaltime .. versionadded:: 1.4 For datetime values, returns a string representing how many seconds, -minutes or hours ago it was -- falling back to a longer date format if the -value is more than a day old. In case the datetime value is in the future -the return value will automatically use an appropriate phrase. +minutes or hours ago it was -- falling back to the :tfilter:`timesince` +format if the value is more than a day old. In case the datetime value is in +the future the return value will automatically use an appropriate phrase. Examples (when 'now' is 17 Feb 2007 16:30:00): @@ -115,13 +115,14 @@ Examples (when 'now' is 17 Feb 2007 16:30:00): * ``17 Feb 2007 16:25:35`` becomes ``4 minutes ago``. * ``17 Feb 2007 15:30:29`` becomes ``an hour ago``. * ``17 Feb 2007 13:31:29`` becomes ``2 hours ago``. -* ``16 Feb 2007 13:31:29`` becomes ``1 day ago``. +* ``16 Feb 2007 13:31:29`` becomes ``1 day, 3 hours ago``. * ``17 Feb 2007 16:30:30`` becomes ``29 seconds from now``. * ``17 Feb 2007 16:31:00`` becomes ``a minute from now``. * ``17 Feb 2007 16:34:35`` becomes ``4 minutes from now``. * ``17 Feb 2007 16:30:29`` becomes ``an hour from now``. * ``17 Feb 2007 18:31:29`` becomes ``2 hours from now``. * ``18 Feb 2007 16:31:29`` becomes ``1 day from now``. +* ``26 Feb 2007 18:31:29`` becomes ``1 week, 2 days from now``. .. templatefilter:: ordinal diff --git a/docs/ref/contrib/messages.txt b/docs/ref/contrib/messages.txt index 6929a3b0d0..4cf90ee381 100644 --- a/docs/ref/contrib/messages.txt +++ b/docs/ref/contrib/messages.txt @@ -5,12 +5,14 @@ The messages framework .. module:: django.contrib.messages :synopsis: Provides cookie- and session-based temporary message storage. -Django provides full support for cookie- and session-based messaging, for -both anonymous and authenticated clients. The messages framework allows you -to temporarily store messages in one request and retrieve them for display -in a subsequent request (usually the next one). Every message is tagged -with a specific ``level`` that determines its priority (e.g., ``info``, -``warning``, or ``error``). +Quite commonly in web applications, you may need to display a one-time +notification message (also know as "flash message") to the user after +processing a form or some other types of user input. For this, Django provides +full support for cookie- and session-based messaging, for both anonymous and +authenticated users. The messages framework allows you to temporarily store +messages in one request and retrieve them for display in a subsequent request +(usually the next one). Every message is tagged with a specific ``level`` that +determines its priority (e.g., ``info``, ``warning``, or ``error``). Enabling messages ================= diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt index 74e6b48f07..92b5665bea 100644 --- a/docs/ref/databases.txt +++ b/docs/ref/databases.txt @@ -238,7 +238,7 @@ to you, the developer, to handle the fact that you will receive bytestrings if you configure your table(s) to use ``utf8_bin`` collation. Django itself should mostly work smoothly with such columns (except for the ``contrib.sessions`` ``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but -your code must be prepared to call ``django.utils.encoding.smart_unicode()`` at +your code must be prepared to call ``django.utils.encoding.smart_text()`` at times if it really wants to work with consistent data -- Django will not do this for you (the database backend layer and the model population layer are separated internally so the database layer doesn't know it needs to make this diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index c4295c68d5..5ff7ecba2c 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -747,7 +747,7 @@ use the ``--plain`` option, like so:: If you would like to specify either IPython or bpython as your interpreter if you have both installed you can specify an alternative interpreter interface -with the ``-i`` or ``--interface`` options like so:: +with the ``-i`` or ``--interface`` options like so: IPython:: diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt index 50488b026a..777d73e015 100644 --- a/docs/ref/forms/api.txt +++ b/docs/ref/forms/api.txt @@ -199,8 +199,8 @@ Note that any text-based field -- such as ``CharField`` or ``EmailField`` -- always cleans the input into a Unicode string. We'll cover the encoding implications later in this document. -If your data does *not* validate, your ``Form`` instance will not have a -``cleaned_data`` attribute:: +If your data does *not* validate, the ``cleaned_data`` dictionary contains +only the valid fields:: >>> data = {'subject': '', ... 'message': 'Hi there', @@ -210,9 +210,12 @@ If your data does *not* validate, your ``Form`` instance will not have a >>> f.is_valid() False >>> f.cleaned_data - Traceback (most recent call last): - ... - AttributeError: 'ContactForm' object has no attribute 'cleaned_data' + {'cc_myself': True, 'message': u'Hi there'} + +.. versionchanged:: 1.5 + +Until Django 1.5, the ``cleaned_data`` attribute wasn't defined at all when +the ``Form`` didn't validate. ``cleaned_data`` will always *only* contain a key for fields defined in the ``Form``, even if you pass extra data when you define the ``Form``. In this @@ -232,9 +235,9 @@ but ``cleaned_data`` contains only the form's fields:: >>> f.cleaned_data # Doesn't contain extra_field_1, etc. {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'} -``cleaned_data`` will include a key and value for *all* fields defined in the -``Form``, even if the data didn't include a value for fields that are not -required. In this example, the data dictionary doesn't include a value for the +When the ``Form`` is valid, ``cleaned_data`` will include a key and value for +*all* its fields, even if the data didn't include a value for some optional +fields. In this example, the data dictionary doesn't include a value for the ``nick_name`` field, but ``cleaned_data`` includes it, with an empty value:: >>> class OptionalPersonForm(Form): @@ -583,7 +586,7 @@ lazy developers -- they're not the only way a form object can be displayed. Used to display HTML or access attributes for a single field of a :class:`Form` instance. - + The :meth:`__unicode__` and :meth:`__str__` methods of this object displays the HTML for this field. diff --git a/docs/ref/forms/validation.txt b/docs/ref/forms/validation.txt index 97883d7880..95424d0cd0 100644 --- a/docs/ref/forms/validation.txt +++ b/docs/ref/forms/validation.txt @@ -362,7 +362,9 @@ Secondly, once we have decided that the combined data in the two fields we are considering aren't valid, we must remember to remove them from the ``cleaned_data``. -In fact, Django will currently completely wipe out the ``cleaned_data`` -dictionary if there are any errors in the form. However, this behavior may -change in the future, so it's not a bad idea to clean up after yourself in the -first place. +.. versionchanged:: 1.5 + +Django used to remove the ``cleaned_data`` attribute entirely if there were +any errors in the form. Since version 1.5, ``cleaned_data`` is present even if +the form doesn't validate, but it contains only field values that did +validate. diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt index c280202ebf..a6ea9a6c41 100644 --- a/docs/ref/middleware.txt +++ b/docs/ref/middleware.txt @@ -146,7 +146,7 @@ Locale middleware Enables language selection based on data from the request. It customizes content for each user. See the :doc:`internationalization documentation -</topics/i18n/index>`. +</topics/i18n/translation>`. Message middleware ------------------ diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 5039ba4373..a43163c5e9 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -86,42 +86,43 @@ field. If this is given, Django's admin will use a select box instead of the standard text field and will limit choices to the choices given. -A choices list looks like this:: +A choices list is an iterable of 2-tuples; the first element in each +tuple is the actual value to be stored, and the second element is the +human-readable name. For example:: YEAR_IN_SCHOOL_CHOICES = ( ('FR', 'Freshman'), ('SO', 'Sophomore'), ('JR', 'Junior'), ('SR', 'Senior'), - ('GR', 'Graduate'), ) -The first element in each tuple is the actual value to be stored. The second -element is the human-readable name for the option. +Generally, it's best to define choices inside a model class, and to +define a suitably-named constant for each value:: -The choices list can be defined either as part of your model class:: - - class Foo(models.Model): + class Student(models.Model): + FRESHMAN = 'FR' + SOPHOMORE = 'SO' + JUNIOR = 'JR' + SENIOR = 'SR' YEAR_IN_SCHOOL_CHOICES = ( - ('FR', 'Freshman'), - ('SO', 'Sophomore'), - ('JR', 'Junior'), - ('SR', 'Senior'), - ('GR', 'Graduate'), + (FRESHMAN, 'Freshman'), + (SOPHOMORE, 'Sophomore'), + (JUNIOR, 'Junior'), + (SENIOR, 'Senior'), ) - year_in_school = models.CharField(max_length=2, choices=YEAR_IN_SCHOOL_CHOICES) + year_in_school = models.CharField(max_length=2, + choices=YEAR_IN_SCHOOL_CHOICES, + default=FRESHMAN) -or outside your model class altogether:: + def is_upperclass(self): + return self.year_in_school in (self.JUNIOR, self.SENIOR) - YEAR_IN_SCHOOL_CHOICES = ( - ('FR', 'Freshman'), - ('SO', 'Sophomore'), - ('JR', 'Junior'), - ('SR', 'Senior'), - ('GR', 'Graduate'), - ) - class Foo(models.Model): - year_in_school = models.CharField(max_length=2, choices=YEAR_IN_SCHOOL_CHOICES) +Though you can define a choices list outside of a model class and then +refer to it, defining the choices and names for each choice inside the +model class keeps all of that information with the class that uses it, +and makes the choices easy to reference (e.g, ``Student.SOPHOMORE`` +will work anywhere that the ``Student`` model has been imported). You can also collect your available choices into named groups that can be used for organizational purposes:: @@ -1002,9 +1003,10 @@ define the details of how the relation works. <abstract-base-classes>`; and when you do so :ref:`some special syntax <abstract-related-name>` is available. - If you'd prefer Django didn't create a backwards relation, set ``related_name`` - to ``'+'``. For example, this will ensure that the ``User`` model won't get a - backwards relation to this model:: + If you'd prefer Django not to create a backwards relation, set + ``related_name`` to ``'+'`` or end it with ``'+'``. For example, this will + ensure that the ``User`` model won't have a backwards relation to this + model:: user = models.ForeignKey(User, related_name='+') @@ -1095,6 +1097,13 @@ that control how the relationship functions. Same as :attr:`ForeignKey.related_name`. + If you have more than one ``ManyToManyField`` pointing to the same model + and want to suppress the backwards relations, set each ``related_name`` + to a unique value ending with ``'+'``:: + + users = models.ManyToManyField(User, related_name='u+') + referents = models.ManyToManyField(User, related_name='ref+') + .. attribute:: ManyToManyField.limit_choices_to Same as :attr:`ForeignKey.limit_choices_to`. diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 509ea9d30e..14541ad0d1 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -453,9 +453,9 @@ using ``__str__()`` like this:: last_name = models.CharField(max_length=50) def __str__(self): - # Note use of django.utils.encoding.smart_str() here because + # Note use of django.utils.encoding.smart_bytes() here because # first_name and last_name will be unicode strings. - return smart_str('%s %s' % (self.first_name, self.last_name)) + return smart_bytes('%s %s' % (self.first_name, self.last_name)) ``get_absolute_url`` -------------------- diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 72d60453c3..531ff33da2 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -183,7 +183,7 @@ compose a prefix, version and key into a final cache key. The default implementation is equivalent to the function:: def make_key(key, key_prefix, version): - return ':'.join([key_prefix, str(version), smart_str(key)]) + return ':'.join([key_prefix, str(version), smart_bytes(key)]) You may use any key function you want, as long as it has the same argument signature. diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 500a47c6f1..072eebf69f 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -1184,7 +1184,7 @@ Removes all values of arg from the given string. For example:: - {{ value|cut:" "}} + {{ value|cut:" " }} If ``value`` is ``"String with spaces"``, the output will be ``"Stringwithspaces"``. diff --git a/docs/ref/unicode.txt b/docs/ref/unicode.txt index b9253e70b3..ffab647379 100644 --- a/docs/ref/unicode.txt +++ b/docs/ref/unicode.txt @@ -129,7 +129,7 @@ Conversion functions The ``django.utils.encoding`` module contains a few functions that are handy for converting back and forth between Unicode and bytestrings. -* ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')`` +* ``smart_text(s, encoding='utf-8', strings_only=False, errors='strict')`` converts its input to a Unicode string. The ``encoding`` parameter specifies the input encoding. (For example, Django uses this internally when processing form input data, which might not be UTF-8 encoded.) The @@ -139,27 +139,27 @@ for converting back and forth between Unicode and bytestrings. that are accepted by Python's ``unicode()`` function for its error handling. - If you pass ``smart_unicode()`` an object that has a ``__unicode__`` + If you pass ``smart_text()`` an object that has a ``__unicode__`` method, it will use that method to do the conversion. -* ``force_unicode(s, encoding='utf-8', strings_only=False, - errors='strict')`` is identical to ``smart_unicode()`` in almost all +* ``force_text(s, encoding='utf-8', strings_only=False, + errors='strict')`` is identical to ``smart_text()`` in almost all cases. The difference is when the first argument is a :ref:`lazy - translation <lazy-translations>` instance. While ``smart_unicode()`` - preserves lazy translations, ``force_unicode()`` forces those objects to a + translation <lazy-translations>` instance. While ``smart_text()`` + preserves lazy translations, ``force_text()`` forces those objects to a Unicode string (causing the translation to occur). Normally, you'll want - to use ``smart_unicode()``. However, ``force_unicode()`` is useful in + to use ``smart_text()``. However, ``force_text()`` is useful in template tags and filters that absolutely *must* have a string to work with, not just something that can be converted to a string. -* ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')`` - is essentially the opposite of ``smart_unicode()``. It forces the first +* ``smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict')`` + is essentially the opposite of ``smart_text()``. It forces the first argument to a bytestring. The ``strings_only`` parameter has the same - behavior as for ``smart_unicode()`` and ``force_unicode()``. This is + behavior as for ``smart_text()`` and ``force_text()``. This is slightly different semantics from Python's builtin ``str()`` function, but the difference is needed in a few places within Django's internals. -Normally, you'll only need to use ``smart_unicode()``. Call it as early as +Normally, you'll only need to use ``smart_text()``. Call it as early as possible on any input data that might be either Unicode or a bytestring, and from then on, you can treat the result as always being Unicode. @@ -324,7 +324,7 @@ A couple of tips to remember when writing your own template tags and filters: * Always return Unicode strings from a template tag's ``render()`` method and from template filters. -* Use ``force_unicode()`` in preference to ``smart_unicode()`` in these +* Use ``force_text()`` in preference to ``smart_text()`` in these places. Tag rendering and filter calls occur as the template is being rendered, so there is no advantage to postponing the conversion of lazy translation objects into strings. It's easier to work solely with Unicode diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index c2f2025bc3..b6cb1035d3 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -178,33 +178,53 @@ The functions defined in this module share the following properties: .. class:: StrAndUnicode - A class whose ``__str__`` returns its ``__unicode__`` as a UTF-8 - bytestring. Useful as a mix-in. + A class that derives ``__str__`` from ``__unicode__``. -.. function:: smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict') + On Python 2, ``__str__`` returns the output of ``__unicode__`` encoded as + a UTF-8 bytestring. On Python 3, ``__str__`` returns the output of + ``__unicode__``. + + Useful as a mix-in. If you support Python 2 and 3 with a single code base, + you can inherit this mix-in and just define ``__unicode__``. + +.. function:: smart_text(s, encoding='utf-8', strings_only=False, errors='strict') - Returns a ``unicode`` object representing ``s``. Treats bytestrings using - the 'encoding' codec. + .. versionadded:: 1.5 + + Returns a text object representing ``s`` -- ``unicode`` on Python 2 and + ``str`` on Python 3. Treats bytestrings using the ``encoding`` codec. If ``strings_only`` is ``True``, don't convert (some) non-string-like objects. +.. function:: smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict') + + Historical name of :func:`smart_text`. Only available under Python 2. + .. function:: is_protected_type(obj) Determine if the object instance is of a protected type. Objects of protected types are preserved as-is when passed to - ``force_unicode(strings_only=True)``. + ``force_text(strings_only=True)``. -.. function:: force_unicode(s, encoding='utf-8', strings_only=False, errors='strict') +.. function:: force_text(s, encoding='utf-8', strings_only=False, errors='strict') + + .. versionadded:: 1.5 - Similar to ``smart_unicode``, except that lazy instances are resolved to + Similar to ``smart_text``, except that lazy instances are resolved to strings, rather than kept as lazy objects. If ``strings_only`` is ``True``, don't convert (some) non-string-like objects. -.. function:: smart_str(s, encoding='utf-8', strings_only=False, errors='strict') +.. function:: force_unicode(s, encoding='utf-8', strings_only=False, errors='strict') + + Historical name of :func:`force_text`. Only available under Python 2. + +.. function:: smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict') + + .. versionadded:: 1.5 Returns a bytestring version of ``s``, encoded as specified in ``encoding``. @@ -212,6 +232,14 @@ The functions defined in this module share the following properties: If ``strings_only`` is ``True``, don't convert (some) non-string-like objects. +.. function:: smart_str(s, encoding='utf-8', strings_only=False, errors='strict') + + Alias of :func:`smart_bytes` on Python 2 and :func:`smart_text` on Python + 3. This function always returns a :class:`str`. + + For instance, this is suitable for writing to :attr:`sys.stdout` on + Python 2 and 3. + .. function:: iri_to_uri(iri) Convert an Internationalized Resource Identifier (IRI) portion to a URI @@ -406,7 +434,7 @@ escaping HTML. Returns the given text with ampersands, quotes and angle brackets encoded for use in HTML. The input is first passed through - :func:`~django.utils.encoding.force_unicode` and the output has + :func:`~django.utils.encoding.force_text` and the output has :func:`~django.utils.safestring.mark_safe` applied. .. function:: conditional_escape(text) @@ -448,7 +476,7 @@ escaping HTML. interpolation, some of the formatting options provided by `str.format`_ (e.g. number formatting) will not work, since all arguments are passed through :func:`conditional_escape` which (ultimately) calls - :func:`~django.utils.encoding.force_unicode` on the values. + :func:`~django.utils.encoding.force_text` on the values. .. _str.format: http://docs.python.org/library/stdtypes.html#str.format @@ -504,11 +532,13 @@ escaping HTML. .. function:: base36_to_int(s) - Converts a base 36 string to an integer. + Converts a base 36 string to an integer. On Python 2 the output is + guaranteed to be an :class:`int` and not a :class:`long`. .. function:: int_to_base36(i) - Converts a positive integer less than sys.maxint to a base 36 string. + Converts a positive integer to a base 36 string. On Python 2 ``i`` must be + smaller than :attr:`sys.maxint`. ``django.utils.safestring`` =========================== diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt index aae8b25e07..f789ebde40 100644 --- a/docs/releases/1.5.txt +++ b/docs/releases/1.5.txt @@ -107,7 +107,7 @@ Django 1.5 also includes several smaller improvements worth noting: connect to more than one signal by supplying a list of signals. * :meth:`QuerySet.bulk_create() - <django.db.models.query.QuerySet.bulk_create>` has now a batch_size + <django.db.models.query.QuerySet.bulk_create>` now has a batch_size argument. By default the batch_size is unlimited except for SQLite where single batch is limited so that 999 parameters per query isn't exceeded. @@ -161,7 +161,7 @@ If you have written a :ref:`custom password hasher <auth_password_storage>`, your ``encode()``, ``verify()`` or ``safe_summary()`` methods should accept Unicode parameters (``password``, ``salt`` or ``encoded``). If any of the hashing methods need byte strings, you can use the -:func:`~django.utils.encoding.smart_str` utility to encode the strings. +:func:`~django.utils.encoding.smart_bytes` utility to encode the strings. Validation of previous_page_number and next_page_number ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -239,11 +239,24 @@ database state behind or unit tests that rely on some form of state being preserved after the execution of other tests. Such tests are already very fragile, and must now be changed to be able to run independently. +`cleaned_data` dictionary kept for invalid forms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :attr:`~django.forms.Form.cleaned_data` dictionary is now always present +after form validation. When the form doesn't validate, it contains only the +fields that passed validation. You should test the success of the validation +with the :meth:`~django.forms.Form.is_valid()` method and not with the +presence or absence of the :attr:`~django.forms.Form.cleaned_data` attribute +on the form. + Miscellaneous ~~~~~~~~~~~~~ * GeoDjango dropped support for GDAL < 1.5 +* :func:`~django.utils.http.int_to_base36` properly raises a :exc:`TypeError` + instead of :exc:`ValueError` for non-integer inputs. + Features deprecated in 1.5 ========================== diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt index c0e56dbba0..307691bd4a 100644 --- a/docs/topics/auth.txt +++ b/docs/topics/auth.txt @@ -98,12 +98,13 @@ Fields This doesn't necessarily control whether or not the user can log in. Authentication backends aren't required to check for the ``is_active`` - flag, so if you want to reject a login based on ``is_active`` being - ``False``, it's up to you to check that in your own login view. - However, the :class:`~django.contrib.auth.forms.AuthenticationForm` - used by the :func:`~django.contrib.auth.views.login` view *does* - perform this check, as do the permission-checking methods such as - :meth:`~models.User.has_perm` and the authentication in the Django + flag, and the default backends do not. If you want to reject a login + based on ``is_active`` being ``False``, it's up to you to check that in + your own login view or a custom authentication backend. However, the + :class:`~django.contrib.auth.forms.AuthenticationForm` used by the + :func:`~django.contrib.auth.views.login` view (which is the default) + *does* perform this check, as do the permission-checking methods such + as :meth:`~models.User.has_perm` and the authentication in the Django admin. All of those functions/methods will return ``False`` for inactive users. @@ -1447,10 +1448,10 @@ The permission_required decorator .. currentmodule:: django.contrib.auth -Limiting access to generic views --------------------------------- +Applying permissions to generic views +------------------------------------- -To limit access to a :doc:`class-based generic view +To apply a permission to a :doc:`class-based generic view </ref/class-based-views/index>`, decorate the :meth:`View.dispatch <django.views.generic.base.View.dispatch>` method on the class. See :ref:`decorating-class-based-views` for details. @@ -1476,12 +1477,13 @@ The Django admin site uses permissions as follows: * Access to delete an object is limited to users with the "delete" permission for that type of object. -Permissions are set globally per type of object, not per specific object -instance. For example, it's possible to say "Mary may change news stories," but -it's not currently possible to say "Mary may change news stories, but only the -ones she created herself" or "Mary may only change news stories that have a -certain status, publication date or ID." The latter functionality is something -Django developers are currently discussing. +Permissions can be set not only per type of object, but also per specific +object instance. By using the +:meth:`~django.contrib.admin.ModelAdmin.has_add_permission`, +:meth:`~django.contrib.admin.ModelAdmin.has_change_permission` and +:meth:`~django.contrib.admin.ModelAdmin.has_delete_permission` methods provided +by the :class:`~django.contrib.admin.ModelAdmin` class, it is possible to +customize permissions for different object instances of the same type. Default permissions ------------------- @@ -1747,7 +1749,11 @@ By default, :setting:`AUTHENTICATION_BACKENDS` is set to:: ('django.contrib.auth.backends.ModelBackend',) -That's the basic authentication scheme that checks the Django users database. +That's the basic authentication backend that checks the Django users database +and queries the builtin permissions. It does not provide protection against +brute force attacks via any rate limiting mechanism. You may either implement +your own rate limiting mechanism in a custom auth backend, or use the +mechanisms provided by most Web servers. The order of :setting:`AUTHENTICATION_BACKENDS` matters, so if the same username and password is valid in multiple backends, Django will stop @@ -1767,8 +1773,9 @@ processing at the first positive match. Writing an authentication backend --------------------------------- -An authentication backend is a class that implements two methods: -``get_user(user_id)`` and ``authenticate(**credentials)``. +An authentication backend is a class that implements two required methods: +``get_user(user_id)`` and ``authenticate(**credentials)``, as well as a set of +optional permission related :ref:`authorization methods <authorization_methods>`. The ``get_user`` method takes a ``user_id`` -- which could be a username, database ID or whatever -- and returns a ``User`` object. @@ -1837,6 +1844,8 @@ object the first time a user authenticates:: except User.DoesNotExist: return None +.. _authorization_methods: + Handling authorization in custom backends ----------------------------------------- @@ -1867,13 +1876,16 @@ fairly simply:: return False This gives full permissions to the user granted access in the above example. -Notice that the backend auth functions all take the user object as an argument, -and they also accept the same arguments given to the associated -:class:`django.contrib.auth.models.User` functions. +Notice that in addition to the same arguments given to the associated +:class:`django.contrib.auth.models.User` functions, the backend auth functions +all take the user object, which may be an anonymous user, as an argument. -A full authorization implementation can be found in -`django/contrib/auth/backends.py`_, which is the default backend and queries -the ``auth_permission`` table most of the time. +A full authorization implementation can be found in the ``ModelBackend`` class +in `django/contrib/auth/backends.py`_, which is the default backend and queries +the ``auth_permission`` table most of the time. If you wish to provide +custom behavior for only part of the backend API, you can take advantage of +Python inheritence and subclass ``ModelBackend`` instead of implementing the +complete API in a custom backend. .. _django/contrib/auth/backends.py: https://github.com/django/django/blob/master/django/contrib/auth/backends.py @@ -1889,25 +1901,27 @@ authorize anonymous users to browse most of the site, and many allow anonymous posting of comments etc. Django's permission framework does not have a place to store permissions for -anonymous users. However, it has a foundation that allows custom authentication -backends to specify authorization for anonymous users. This is especially useful -for the authors of re-usable apps, who can delegate all questions of authorization -to the auth backend, rather than needing settings, for example, to control -anonymous access. +anonymous users. However, the user object passed to an authentication backend +may be an :class:`django.contrib.auth.models.AnonymousUser` object, allowing +the backend to specify custom authorization behavior for anonymous users. This +is especially useful for the authors of re-usable apps, who can delegate all +questions of authorization to the auth backend, rather than needing settings, +for example, to control anonymous access. +.. _inactive_auth: Authorization for inactive users ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 1.3 +.. versionchanged:: 1.3 An inactive user is a one that is authenticated but has its attribute ``is_active`` set to ``False``. However this does not mean they are not authorized to do anything. For example they are allowed to activate their account. -The support for anonymous users in the permission system allows for -anonymous users to have permissions to do something while inactive +The support for anonymous users in the permission system allows for a scenario +where anonymous users have permissions to do something while inactive authenticated users do not. Do not forget to test for the ``is_active`` attribute of the user in your own @@ -1915,9 +1929,11 @@ backend permission methods. Handling object permissions ---------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~ Django's permission framework has a foundation for object permissions, though there is no implementation for it in the core. That means that checking for object permissions will always return ``False`` or an empty list (depending on -the check performed). +the check performed). An authentication backend will receive the keyword +parameters ``obj`` and ``user_obj`` for each object related authorization +method and can return the object level permission as appropriate. diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt index 03afa86647..219b6c7795 100644 --- a/docs/topics/cache.txt +++ b/docs/topics/cache.txt @@ -595,7 +595,8 @@ the ``cache`` template tag. To give your template access to this tag, put The ``{% cache %}`` template tag caches the contents of the block for a given amount of time. It takes at least two arguments: the cache timeout, in seconds, -and the name to give the cache fragment. For example: +and the name to give the cache fragment. The name will be taken as is, do not +use a variable. For example: .. code-block:: html+django @@ -863,7 +864,7 @@ key version to provide a final cache key. By default, the three parts are joined using colons to produce a final string:: def make_key(key, key_prefix, version): - return ':'.join([key_prefix, str(version), smart_str(key)]) + return ':'.join([key_prefix, str(version), smart_bytes(key)]) If you want to combine the parts in different ways, or apply other processing to the final key (e.g., taking a hash digest of the key diff --git a/docs/topics/class-based-views/index.txt b/docs/topics/class-based-views/index.txt index 6c2848944c..1ac70e6938 100644 --- a/docs/topics/class-based-views/index.txt +++ b/docs/topics/class-based-views/index.txt @@ -87,7 +87,7 @@ Where class based views shine is when you want to do the same thing many times. Suppose you're writing an API, and every view should return JSON instead of rendered HTML. -We can use create a mixin class to use in all of our views, handling the +We can create a mixin class to use in all of our views, handling the conversion to JSON once. For example, a simple JSON mixin might look something like this:: diff --git a/docs/topics/db/optimization.txt b/docs/topics/db/optimization.txt index 573e1fd0aa..772792d39d 100644 --- a/docs/topics/db/optimization.txt +++ b/docs/topics/db/optimization.txt @@ -230,7 +230,7 @@ It is optimal because: #. Use of :ttag:`with` means that we store ``user.emails.all`` in a variable for later use, allowing its cache to be re-used. -#. The line ``{% if emails %}`` causes ``QuerySet.__nonzero__()`` to be called, +#. The line ``{% if emails %}`` causes ``QuerySet.__bool__()`` to be called, which causes the ``user.emails.all()`` query to be run on the database, and at the least the first line to be turned into an ORM object. If there aren't any results, it will return False, otherwise True. diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index 4cfde400a7..0ca37745c7 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -437,6 +437,10 @@ parameter when declaring the form field:: class Meta: model = Article + You must ensure that the type of the form field can be used to set the + contents of the corresponding model field. When they are not compatible, + you will get a ``ValueError`` as no implicit conversion takes place. + See the :doc:`form field documentation </ref/forms/fields>` for more information on fields and their arguments. diff --git a/docs/topics/i18n/formatting.txt b/docs/topics/i18n/formatting.txt index d18781c0a9..b09164769e 100644 --- a/docs/topics/i18n/formatting.txt +++ b/docs/topics/i18n/formatting.txt @@ -21,7 +21,10 @@ necessary to set :setting:`USE_L10N = True <USE_L10N>` in your settings file. The default :file:`settings.py` file created by :djadmin:`django-admin.py startproject <startproject>` includes :setting:`USE_L10N = True <USE_L10N>` - for convenience. + for convenience. Note, however, that to enable number formatting with + thousand separators it is necessary to set :setting:`USE_THOUSAND_SEPARATOR + = True <USE_THOUSAND_SEPARATOR>` in your settings file. Alternatively, you + could use :tfilter:`intcomma` to format numbers in your template. .. note:: diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index c912bf9575..bdbb04823d 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -1247,6 +1247,12 @@ Activate this view by adding the following line to your URLconf:: (Note that this example makes the view available at ``/i18n/setlang/``.) +.. warning:: + + Make sure that you don't include the above URL within + :func:`~django.conf.urls.i18n.i18n_patterns` - it needs to be + language-independent itself to work correctly. + The view expects to be called via the ``POST`` method, with a ``language`` parameter set in request. If session support is enabled, the view saves the language choice in the user's session. Otherwise, it saves the @@ -1266,7 +1272,7 @@ Here's example HTML template code: .. code-block:: html+django - <form action="/i18n/setlang/" method="post"> + <form action="{% url 'set_language' %}" method="post"> {% csrf_token %} <input name="next" type="hidden" value="{{ redirect_to }}" /> <select name="language"> diff --git a/docs/topics/python3.txt b/docs/topics/python3.txt index 3f799edac7..b09c1d2347 100644 --- a/docs/topics/python3.txt +++ b/docs/topics/python3.txt @@ -36,6 +36,11 @@ In order to enable the same behavior in Python 2, every module must import my_string = "This is an unicode literal" my_bytestring = b"This is a bytestring" +If you need a byte string under Python 2 and a unicode string under Python 3, +use the :func:`str` builtin:: + + str('my string') + Be cautious if you have to `slice bytestrings`_. .. _slice bytestrings: http://docs.python.org/py3k/howto/pyporting.html#bytes-literals diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt index 505ac17f09..ac1a77ed98 100644 --- a/docs/topics/serialization.txt +++ b/docs/topics/serialization.txt @@ -173,12 +173,12 @@ In particular, :ref:`lazy translation objects <lazy-translations>` need a import json from django.utils.functional import Promise - from django.utils.encoding import force_unicode + from django.utils.encoding import force_text class LazyEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, Promise): - return force_unicode(obj) + return force_text(obj) return super(LazyEncoder, self).default(obj) .. _special encoder: http://docs.python.org/library/json.html#encoders-and-decoders |
