Fixed #30573 -- Rephrased documentation to avoid words that minimise the involved difficulty.

This patch does not remove all occurrences of the words in question.
Rather, I went through all of the occurrences of the words listed
below, and judged if they a) suggested the reader had some kind of
knowledge/experience, and b) if they added anything of value (including
tone of voice, etc). I left most of the words alone. I looked at the
following words:

- simply/simple
- easy/easier/easiest
- obvious
- just
- merely
- straightforward
- ridiculous

Thanks to Carlton Gibson for guidance on how to approach this issue, and
to Tim Bell for providing the idea. But the enormous lion's share of
thanks go to Adam Johnson for his patient and helpful review.
This commit is contained in:
Tobias Kunze 2019-06-17 16:54:55 +02:00 committed by Mariusz Felisiak
parent addabc492b
commit 4a954cfd11
149 changed files with 1101 additions and 1157 deletions

View file

@ -82,8 +82,8 @@ backends that follow.
authenticated user is needed. This effectively means that authentication
sources are cached on a per-session basis, so if you change
:setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data if
you need to force users to re-authenticate using different methods. A simple
way to do that is simply to execute ``Session.objects.all().delete()``.
you need to force users to re-authenticate using different methods. A
simple way to do that is to execute ``Session.objects.all().delete()``.
Writing an authentication backend
---------------------------------
@ -98,7 +98,7 @@ database ID or whatever, but has to be the primary key of your user object --
and returns a user object or ``None``.
The ``authenticate`` method takes a ``request`` argument and credentials as
keyword arguments. Most of the time, it'll just look like this::
keyword arguments. Most of the time, it'll look like this::
from django.contrib.auth.backends import BaseBackend
@ -197,7 +197,7 @@ exception in :meth:`~django.contrib.auth.models.User.has_perm()` or
:meth:`~django.contrib.auth.models.User.has_module_perms()`, the authorization
will immediately fail and Django won't check the backends that follow.
A backend could implement permissions for the magic admin fairly simply::
A backend could implement permissions for the magic admin like this::
from django.contrib.auth.backends import BaseBackend
@ -729,7 +729,7 @@ Writing a manager for a custom user model
You should also define a custom manager for your user model. If your user model
defines ``username``, ``email``, ``is_staff``, ``is_active``, ``is_superuser``,
``last_login``, and ``date_joined`` fields the same as Django's default user,
you can just install Django's :class:`~django.contrib.auth.models.UserManager`;
you can install Django's :class:`~django.contrib.auth.models.UserManager`;
however, if your user model defines different fields, you'll need to define a
custom manager that extends :class:`~django.contrib.auth.models.BaseUserManager`
providing two additional methods:
@ -793,10 +793,10 @@ Extending Django's default ``User``
-----------------------------------
If you're entirely happy with Django's :class:`~django.contrib.auth.models.User`
model and you just want to add some additional profile information, you could
simply subclass :class:`django.contrib.auth.models.AbstractUser` and add your
custom profile fields, although we'd recommend a separate model as described in
the "Model design considerations" note of :ref:`specifying-custom-user-model`.
model, but you want to add some additional profile information, you could
subclass :class:`django.contrib.auth.models.AbstractUser` and add your custom
profile fields, although we'd recommend a separate model as described in the
"Model design considerations" note of :ref:`specifying-custom-user-model`.
``AbstractUser`` provides the full implementation of the default
:class:`~django.contrib.auth.models.User` as an :ref:`abstract model
<abstract-base-classes>`.
@ -835,8 +835,8 @@ to work with a custom user model:
* :class:`~django.contrib.auth.forms.UserCreationForm`
* :class:`~django.contrib.auth.forms.UserChangeForm`
If your custom user model is a simple subclass of ``AbstractUser``, then you
can extend these forms in this manner::
If your custom user model is a subclass of ``AbstractUser``, then you can
extend these forms in this manner::
from django.contrib.auth.forms import UserCreationForm
from myapp.models import CustomUser
@ -1009,10 +1009,10 @@ A full example
Here is an example of an admin-compliant custom user app. This user model uses
an email address as the username, and has a required date of birth; it
provides no permission checking, beyond a simple ``admin`` flag on the user
account. This model would be compatible with all the built-in auth forms and
views, except for the user creation forms. This example illustrates how most of
the components work together, but is not intended to be copied directly into
provides no permission checking beyond an ``admin`` flag on the user account.
This model would be compatible with all the built-in auth forms and views,
except for the user creation forms. This example illustrates how most of the
components work together, but is not intended to be copied directly into
projects for production use.
This code would all live in a ``models.py`` file for a custom

View file

@ -150,7 +150,7 @@ Authenticating users
Permissions and Authorization
=============================
Django comes with a simple permissions system. It provides a way to assign
Django comes with a built-in permissions system. It provides a way to assign
permissions to specific users and groups of users.
It's used by the Django admin site, but you're welcome to use it in your own
@ -473,7 +473,7 @@ Limiting access to logged-in users
The raw way
~~~~~~~~~~~
The simple, raw way to limit access to pages is to check
The raw way to limit access to pages is to check
:attr:`request.user.is_authenticated
<django.contrib.auth.models.User.is_authenticated>` and either redirect to a
login page::
@ -615,10 +615,9 @@ Limiting access to logged-in users that pass a test
To limit access based on certain permissions or some other test, you'd do
essentially the same thing as described in the previous section.
The simple way is to run your test on :attr:`request.user
<django.http.HttpRequest.user>` in the view directly. For example, this view
checks to make sure the user has an email in the desired domain and if not,
redirects to the login page::
You can run your test on :attr:`request.user <django.http.HttpRequest.user>` in
the view directly. For example, this view checks to make sure the user has an
email in the desired domain and if not, redirects to the login page::
from django.shortcuts import redirect
@ -1015,8 +1014,8 @@ implementation details see :ref:`using-the-views`.
* ``redirect_field_name``: The name of a ``GET`` field containing the
URL to redirect to after login. Defaults to ``next``.
* ``authentication_form``: A callable (typically just a form class) to
use for authentication. Defaults to
* ``authentication_form``: A callable (typically a form class) to use for
authentication. Defaults to
:class:`~django.contrib.auth.forms.AuthenticationForm`.
* ``extra_context``: A dictionary of context data that will be added to the

View file

@ -423,8 +423,8 @@ Password validation
Users often choose poor passwords. To help mitigate this problem, Django
offers pluggable password validation. You can configure multiple password
validators at the same time. A few validators are included in Django, but it's
simple to write your own as well.
validators at the same time. A few validators are included in Django, but you
can write your own as well.
Each password validator must provide a help text to explain the requirements to
the user, validate a given password and return an error message if it does not
@ -434,7 +434,7 @@ Validators can also have optional settings to fine tune their behavior.
Validation is controlled by the :setting:`AUTH_PASSWORD_VALIDATORS` setting.
The default for the setting is an empty list, which means no validators are
applied. In new projects created with the default :djadmin:`startproject`
template, a simple set of validators is enabled.
template, a set of validators is enabled by default.
By default, validators are used in the forms to reset or change passwords and
in the :djadmin:`createsuperuser` and :djadmin:`changepassword` management
@ -479,10 +479,9 @@ This example enables all four included validators:
* ``UserAttributeSimilarityValidator``, which checks the similarity between
the password and a set of attributes of the user.
* ``MinimumLengthValidator``, which simply checks whether the password meets a
minimum length. This validator is configured with a custom option: it now
requires the minimum length to be nine characters, instead of the default
eight.
* ``MinimumLengthValidator``, which checks whether the password meets a minimum
length. This validator is configured with a custom option: it now requires
the minimum length to be nine characters, instead of the default eight.
* ``CommonPasswordValidator``, which checks whether the password occurs in a
list of common passwords. By default, it compares to an included list of
20,000 common passwords.
@ -490,8 +489,8 @@ This example enables all four included validators:
entirely numeric.
For ``UserAttributeSimilarityValidator`` and ``CommonPasswordValidator``,
we're simply using the default settings in this example.
``NumericPasswordValidator`` has no settings.
we're using the default settings in this example. ``NumericPasswordValidator``
has no settings.
The help texts and any errors from password validators are always returned in
the order they are listed in :setting:`AUTH_PASSWORD_VALIDATORS`.
@ -601,15 +600,15 @@ Writing your own validator
--------------------------
If Django's built-in validators are not sufficient, you can write your own
password validators. Validators are fairly simple classes. They must implement
two methods:
password validators. Validators have a fairly small interface. They must
implement two methods:
* ``validate(self, password, user=None)``: validate a password. Return
``None`` if the password is valid, or raise a
:exc:`~django.core.exceptions.ValidationError` with an error message if the
password is not valid. You must be able to deal with ``user`` being
``None`` - if that means your validator can't run, simply return ``None``
for no error.
``None`` - if that means your validator can't run, return ``None`` for no
error.
* ``get_help_text()``: provide a help text to explain the requirements to
the user.

View file

@ -10,9 +10,9 @@ processing-overhead perspective, than your standard
read-a-file-off-the-filesystem server arrangement.
For most Web applications, this overhead isn't a big deal. Most Web
applications aren't ``washingtonpost.com`` or ``slashdot.org``; they're simply
small- to medium-sized sites with so-so traffic. But for medium- to
high-traffic sites, it's essential to cut as much overhead as possible.
applications aren't ``washingtonpost.com`` or ``slashdot.org``; they're small-
to medium-sized sites with so-so traffic. But for medium- to high-traffic
sites, it's essential to cut as much overhead as possible.
That's where caching comes in.
@ -366,7 +366,7 @@ as reference implementations. You'll find the code in the
Note: Without a really compelling reason, such as a host that doesn't support
them, you should stick to the cache backends included with Django. They've
been well-tested and are easy to use.
been well-tested and are well-documented.
.. _cache_arguments:
@ -556,8 +556,7 @@ The per-view cache
A more granular way to use the caching framework is by caching the output of
individual views. ``django.views.decorators.cache`` defines a ``cache_page``
decorator that will automatically cache the view's response for you. It's easy
to use::
decorator that will automatically cache the view's response for you::
from django.views.decorators.cache import cache_page
@ -618,8 +617,8 @@ want to use them without being cached. The solution to these problems is to
specify the per-view cache in the URLconf rather than next to the view functions
themselves.
Doing so is easy: simply wrap the view function with ``cache_page`` when you
refer to it in the URLconf. Here's the old URLconf from earlier::
You can do so by wrapping the view function with ``cache_page`` when you refer
to it in the URLconf. Here's the old URLconf from earlier::
urlpatterns = [
path('foo/<int:code>/', my_view),
@ -697,7 +696,7 @@ equivalent:
{% cache my_timeout sidebar %} ... {% endcache %}
This feature is useful in avoiding repetition in templates. You can set the
timeout in a variable, in one place, and just reuse that value.
timeout in a variable, in one place, and reuse that value.
By default, the cache tag will try to use the cache called "template_fragments".
If no such cache exists, it will fall back to using the default cache. You may
@ -743,11 +742,11 @@ per-site or per-view cache strategies offer, because you wouldn't want to
cache the entire result (since some of the data changes often), but you'd still
want to cache the results that rarely change.
For cases like this, Django exposes a simple, low-level cache API. You can use
this API to store objects in the cache with any level of granularity you like.
You can cache any Python object that can be pickled safely: strings,
dictionaries, lists of model objects, and so forth. (Most common Python objects
can be pickled; refer to the Python documentation for more information about
For cases like this, Django exposes a low-level cache API. You can use this API
to store objects in the cache with any level of granularity you like. You can
cache any Python object that can be pickled safely: strings, dictionaries,
lists of model objects, and so forth. (Most common Python objects can be
pickled; refer to the Python documentation for more information about
pickling.)
Accessing the cache
@ -840,7 +839,7 @@ check the return value. It will return ``True`` if the value was stored,
If you want to get a key's value or set a value if the key isn't in the cache,
there is the ``get_or_set()`` method. It takes the same parameters as ``get()``
but the default is set as the new cache value for that key, rather than simply
but the default is set as the new cache value for that key, rather than
returned::
>>> cache.get('my_new_key') # returns None
@ -881,8 +880,8 @@ failed to be inserted.
.. method:: cache.delete(key, version=None)
You can delete keys explicitly with ``delete()``. This is an easy way of
clearing the cache for a particular object::
You can delete keys explicitly with ``delete()`` to clear the cache for a
particular object::
>>> cache.delete('a')
@ -1111,11 +1110,11 @@ Many Web pages' contents differ based on authentication and a host of other
variables, and cache systems that blindly save pages based purely on URLs could
expose incorrect or sensitive data to subsequent visitors to those pages.
For example, say you operate a Web email system, and the contents of the
"inbox" page obviously depend on which user is logged in. If an ISP blindly
cached your site, then the first user who logged in through that ISP would have
their user-specific inbox page cached for subsequent visitors to the site.
That's not cool.
For example, if you operate a Web email system, then the contents of the
"inbox" page depend on which user is logged in. If an ISP blindly cached your
site, then the first user who logged in through that ISP would have their
user-specific inbox page cached for subsequent visitors to the site. That's
not cool.
Fortunately, HTTP provides a solution to this problem. A number of HTTP headers
exist to instruct downstream caches to differ their cache contents depending on

View file

@ -29,8 +29,8 @@ Django ships with generic views to do the following:
* Allow users to create, update, and delete objects -- with or
without authorization.
Taken together, these views provide easy interfaces to perform the most common
tasks developers encounter.
Taken together, these views provide interfaces to perform the most common tasks
developers encounter.
Extending generic views
@ -43,10 +43,10 @@ Django developers is how to make generic views handle a wider array of
situations.
This is one of the reasons generic views were redesigned for the 1.3 release -
previously, they were just view functions with a bewildering array of options;
now, rather than passing in a large amount of configuration in the URLconf,
the recommended way to extend generic views is to subclass them, and override
their attributes or methods.
previously, they were view functions with a bewildering array of options; now,
rather than passing in a large amount of configuration in the URLconf, the
recommended way to extend generic views is to subclass them, and override their
attributes or methods.
That said, generic views will have a limit. If you find you're struggling to
implement your view as a subclass of a generic view, then you may find it more
@ -63,8 +63,7 @@ Generic views of objects
:class:`~django.views.generic.base.TemplateView` certainly is useful, but
Django's generic views really shine when it comes to presenting views of your
database content. Because it's such a common task, Django comes with a handful
of built-in generic views that make generating list and detail views of objects
incredibly easy.
of built-in generic views to help generate list and detail views of objects.
Let's start by looking at some examples of showing a list of objects or an
individual object.
@ -130,7 +129,7 @@ however. We could explicitly tell the view which template to use by adding a
template Django will infer one from the object's name. In this case, the
inferred template will be ``"books/publisher_list.html"`` -- the "books" part
comes from the name of the app that defines the model, while the "publisher"
bit is just the lowercased version of the model's name.
bit is the lowercased version of the model's name.
.. note::
@ -139,8 +138,8 @@ bit is just the lowercased version of the model's name.
be: /path/to/project/books/templates/books/publisher_list.html
This template will be rendered against a context containing a variable called
``object_list`` that contains all the publisher objects. A very simple template
might look like the following:
``object_list`` that contains all the publisher objects. A template might look
like the this:
.. code-block:: html+django
@ -197,17 +196,16 @@ coworkers who design templates will thank you.
Adding extra context
--------------------
Often you simply need to present some extra information beyond that
provided by the generic view. For example, think of showing a list of
all the books on each publisher detail page. The
:class:`~django.views.generic.detail.DetailView` generic view provides
the publisher to the context, but how do we get additional information
in that template?
Often you need to present some extra information beyond that provided by the
generic view. For example, think of showing a list of all the books on each
publisher detail page. The :class:`~django.views.generic.detail.DetailView`
generic view provides the publisher to the context, but how do we get
additional information in that template?
The answer is to subclass :class:`~django.views.generic.detail.DetailView`
and provide your own implementation of the ``get_context_data`` method.
The default implementation simply adds the object being displayed to the
template, but you can override it to send more::
The default implementation adds the object being displayed to the template, but
you can override it to send more::
from django.views.generic import DetailView
from books.models import Book, Publisher
@ -261,16 +259,16 @@ specify the list of objects using the ``queryset`` argument::
context_object_name = 'publisher'
queryset = Publisher.objects.all()
Specifying ``model = Publisher`` is really just shorthand for saying
``queryset = Publisher.objects.all()``. However, by using ``queryset``
to define a filtered list of objects you can be more specific about the
objects that will be visible in the view (see :doc:`/topics/db/queries`
for more information about :class:`~django.db.models.query.QuerySet` objects,
and see the :doc:`class-based views reference </ref/class-based-views/index>`
for the complete details).
Specifying ``model = Publisher`` is shorthand for saying ``queryset =
Publisher.objects.all()``. However, by using ``queryset`` to define a filtered
list of objects you can be more specific about the objects that will be visible
in the view (see :doc:`/topics/db/queries` for more information about
:class:`~django.db.models.query.QuerySet` objects, and see the
:doc:`class-based views reference </ref/class-based-views/index>` for the
complete details).
To pick a simple example, we might want to order a list of books by
publication date, with the most recent first::
To pick an example, we might want to order a list of books by publication date,
with the most recent first::
from django.views.generic import ListView
from books.models import Book
@ -279,7 +277,7 @@ publication date, with the most recent first::
queryset = Book.objects.order_by('-publication_date')
context_object_name = 'book_list'
That's a pretty simple example, but it illustrates the idea nicely. Of course,
That's a pretty minimal example, but it illustrates the idea nicely. Of course,
you'll usually want to do more than just reorder objects. If you want to
present a list of books by a particular publisher, you can use the same
technique::
@ -321,8 +319,8 @@ publisher?
Handily, the ``ListView`` has a
:meth:`~django.views.generic.list.MultipleObjectMixin.get_queryset` method we
can override. Previously, it has just been returning the value of the
``queryset`` attribute, but now we can add more logic.
can override. By default, it returns the value of the ``queryset`` attribute,
but we can use it to add more logic.
The key part to making this work is that when class-based views are called,
various useful things are stored on ``self``; as well as the request
@ -354,9 +352,10 @@ Next, we'll write the ``PublisherBookList`` view itself::
self.publisher = get_object_or_404(Publisher, name=self.kwargs['publisher'])
return Book.objects.filter(publisher=self.publisher)
As you can see, it's quite easy to add more logic to the queryset selection;
if we wanted, we could use ``self.request.user`` to filter using the current
user, or other more complex logic.
Using ``get_queryset`` to add logic to the queryset selection is as convenient
as it is powerful. For instance, if we wanted, we could use
``self.request.user`` to filter using the current user, or other more complex
logic.
We can also add the publisher into the context at the same time, so we can
use it in the template::
@ -407,7 +406,7 @@ custom view::
]
Then we'd write our new view -- ``get_object`` is the method that retrieves the
object -- so we simply override it and wrap the call::
object -- so we override it and wrap the call::
from django.utils import timezone
from django.views.generic import DetailView

View file

@ -16,7 +16,7 @@ processing.
Basic forms
===========
Given a simple contact form:
Given a contact form:
.. code-block:: python
:caption: forms.py
@ -85,7 +85,7 @@ You don't even need to provide a ``success_url`` for
:meth:`~django.db.models.Model.get_absolute_url()` on the model object if available.
If you want to use a custom :class:`~django.forms.ModelForm` (for instance to
add extra validation) simply set
add extra validation), set
:attr:`~django.views.generic.edit.FormMixin.form_class` on your view.
.. note::
@ -132,8 +132,8 @@ here; we don't have to write any logic ourselves:
success_url = reverse_lazy('author-list')
.. note::
We have to use :func:`~django.urls.reverse_lazy` here, not just
``reverse()`` as the urls are not loaded when the file is imported.
We have to use :func:`~django.urls.reverse_lazy` instead of
``reverse()``, as the urls are not loaded when the file is imported.
The ``fields`` attribute works the same way as the ``fields`` attribute on the
inner ``Meta`` class on :class:`~django.forms.ModelForm`. Unless you define the
@ -225,7 +225,7 @@ handle unauthorized users in :meth:`~.ModelFormMixin.form_valid()`.
AJAX example
============
Here is a simple example showing how you might go about implementing a form that
Here is an example showing how you might go about implementing a form that
works for AJAX requests as well as 'normal' form POSTs::
from django.http import JsonResponse

View file

@ -6,10 +6,10 @@ A view is a callable which takes a request and returns a
response. This can be more than just a function, and Django provides
an example of some classes which can be used as views. These allow you
to structure your views and reuse code by harnessing inheritance and
mixins. There are also some generic views for simple tasks which we'll
get to later, but you may want to design your own structure of
reusable views which suits your use case. For full details, see the
:doc:`class-based views reference documentation</ref/class-based-views/index>`.
mixins. There are also some generic views for tasks which we'll get to later,
but you may want to design your own structure of reusable views which suits
your use case. For full details, see the :doc:`class-based views reference
documentation</ref/class-based-views/index>`.
.. toctree::
:maxdepth: 1
@ -25,18 +25,18 @@ Basic examples
Django provides base view classes which will suit a wide range of applications.
All views inherit from the :class:`~django.views.generic.base.View` class, which
handles linking the view in to the URLs, HTTP method dispatching and other
simple features. :class:`~django.views.generic.base.RedirectView` is for a
simple HTTP redirect, and :class:`~django.views.generic.base.TemplateView`
extends the base class to make it also render a template.
common features. :class:`~django.views.generic.base.RedirectView` provides a
HTTP redirect, and :class:`~django.views.generic.base.TemplateView` extends the
base class to make it also render a template.
Simple usage in your URLconf
============================
Usage in your URLconf
=====================
The simplest way to use generic views is to create them directly in your
URLconf. If you're only changing a few simple attributes on a class-based view,
you can simply pass them into the
:meth:`~django.views.generic.base.View.as_view` method call itself::
The most direct way to use generic views is to create them directly in your
URLconf. If you're only changing a few attributes on a class-based view, you
can pass them into the :meth:`~django.views.generic.base.View.as_view` method
call itself::
from django.urls import path
from django.views.generic import TemplateView
@ -59,8 +59,8 @@ existing view and override attributes (such as the ``template_name``) or
methods (such as ``get_context_data``) in your subclass to provide new values
or methods. Consider, for example, a view that just displays one template,
``about.html``. Django has a generic view to do this -
:class:`~django.views.generic.base.TemplateView` - so we can just subclass it,
and override the template name::
:class:`~django.views.generic.base.TemplateView` - so we can subclass it, and
override the template name::
# some_app/views.py
from django.views.generic import TemplateView
@ -68,11 +68,10 @@ and override the template name::
class AboutView(TemplateView):
template_name = "about.html"
Then we just need to add this new view into our URLconf.
:class:`~django.views.generic.base.TemplateView` is a class, not a function,
so we point the URL to the :meth:`~django.views.generic.base.View.as_view`
class method instead, which provides a function-like entry to class-based
views::
Then we need to add this new view into our URLconf.
:class:`~django.views.generic.base.TemplateView` is a class, not a function, so
we point the URL to the :meth:`~django.views.generic.base.View.as_view` class
method instead, which provides a function-like entry to class-based views::
# urls.py
from django.urls import path
@ -123,9 +122,8 @@ And the view::
response['Last-Modified'] = last_book.publication_date.strftime('%a, %d %b %Y %H:%M:%S GMT')
return response
If the view is accessed from a ``GET`` request, a plain-and-simple object
list is returned in the response (using ``book_list.html`` template). But if
the client issues a ``HEAD`` request, the response has an empty body and
the ``Last-Modified`` header indicates when the most recent book was published.
Based on this information, the client may or may not download the full object
list.
If the view is accessed from a ``GET`` request, an object list is returned in
the response (using the ``book_list.html`` template). But if the client issues
a ``HEAD`` request, the response has an empty body and the ``Last-Modified``
header indicates when the most recent book was published. Based on this
information, the client may or may not download the full object list.

View file

@ -25,7 +25,7 @@ these patterns and ease view development for the common cases.
The problem with function-based generic views is that while they covered the
simple cases well, there was no way to extend or customize them beyond some
simple configuration options, limiting their usefulness in many real-world
configuration options, limiting their usefulness in many real-world
applications.
Class-based generic views were created with the same objective as
@ -35,9 +35,9 @@ results in class-based generic views being more extensible and flexible than
their function-based counterparts.
If you have tried function based generic views in the past and found them
lacking, you should not think of class-based generic views as simply a
class-based equivalent, but rather as a fresh approach to solving the original
problems that generic views were meant to solve.
lacking, you should not think of class-based generic views as a class-based
equivalent, but rather as a fresh approach to solving the original problems
that generic views were meant to solve.
The toolkit of base classes and mixins that Django uses to build class-based
generic views are built for maximum flexibility, and as such have many hooks in
@ -45,11 +45,11 @@ the form of default method implementations and attributes that you are unlikely
to be concerned with in the simplest use cases. For example, instead of
limiting you to a class-based attribute for ``form_class``, the implementation
uses a ``get_form`` method, which calls a ``get_form_class`` method, which in
its default implementation just returns the ``form_class`` attribute of the
class. This gives you several options for specifying what form to use, from a
simple attribute, to a fully dynamic, callable hook. These options seem to add
hollow complexity for simple situations, but without them, more advanced
designs would be limited.
its default implementation returns the ``form_class`` attribute of the class.
This gives you several options for specifying what form to use, from an
attribute, to a fully dynamic, callable hook. These options seem to add hollow
complexity for simple situations, but without them, more advanced designs would
be limited.
Using class-based views
=======================
@ -221,7 +221,7 @@ A similar class-based view might look like::
return render(request, self.template_name, {'form': form})
This is a very simple case, but you can see that you would then have the option
This is a minimal case, but you can see that you would then have the option
of customizing this view by overriding any of the class attributes, e.g.
``form_class``, via URLconf configuration, or subclassing and overriding one or
more of the methods (or both!).
@ -236,9 +236,9 @@ differently depending on if you're using ``as_view()`` or creating a subclass.
Decorating in URLconf
---------------------
The simplest way of decorating class-based views is to decorate the
result of the :meth:`~django.views.generic.base.View.as_view` method.
The easiest place to do this is in the URLconf where you deploy your view::
You can adjust class-based views by decorating the result of the
:meth:`~django.views.generic.base.View.as_view` method. The easiest place to do
this is in the URLconf where you deploy your view::
from django.contrib.auth.decorators import login_required, permission_required
from django.views.generic import TemplateView
@ -263,11 +263,11 @@ To decorate every instance of a class-based view, you need to decorate
the class definition itself. To do this you apply the decorator to the
:meth:`~django.views.generic.base.View.dispatch` method of the class.
A method on a class isn't quite the same as a standalone function, so
you can't just apply a function decorator to the method -- you need to
transform it into a method decorator first. The ``method_decorator``
decorator transforms a function decorator into a method decorator so
that it can be used on an instance method. For example::
A method on a class isn't quite the same as a standalone function, so you can't
just apply a function decorator to the method -- you need to transform it into
a method decorator first. The ``method_decorator`` decorator transforms a
function decorator into a method decorator so that it can be used on an
instance method. For example::
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@ -306,9 +306,9 @@ The decorators will process a request in the order they are passed to the
decorator. In the example, ``never_cache()`` will process the request before
``login_required()``.
In this example, every instance of ``ProtectedView`` will have login protection.
These examples use ``login_required``, however, the same behavior can be
obtained more simply using
In this example, every instance of ``ProtectedView`` will have login
protection. These examples use ``login_required``, however, the same behavior
can be obtained by using
:class:`~django.contrib.auth.mixins.LoginRequiredMixin`.
.. note::

View file

@ -46,7 +46,7 @@ interface to working with templates in class-based views.
``render_to_response()`` itself calls
:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names`,
which by default will just look up
which by default will look up
:attr:`~django.views.generic.base.TemplateResponseMixin.template_name` on
the class-based view; two other mixins
(:class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`
@ -61,8 +61,8 @@ interface to working with templates in class-based views.
:meth:`~django.views.generic.base.ContextMixin.get_context_data()` passing
any data they want to ensure is in there as keyword arguments.
``get_context_data()`` returns a dictionary; in ``ContextMixin`` it
simply returns its keyword arguments, but it is common to override this to
add more members to the dictionary. You can also use the
returns its keyword arguments, but it is common to override this to add
more members to the dictionary. You can also use the
:attr:`~django.views.generic.base.ContextMixin.extra_context` attribute.
Building up Django's generic class-based views
@ -142,7 +142,7 @@ and
:meth:`~django.views.generic.list.MultipleObjectMixin.paginate_queryset`. Unlike
with :class:`~django.views.generic.detail.SingleObjectMixin`, there's no need
to key off parts of the URL to figure out the queryset to work with, so the
default just uses the
default uses the
:attr:`~django.views.generic.list.MultipleObjectMixin.queryset` or
:attr:`~django.views.generic.list.MultipleObjectMixin.model` attribute
on the view class. A common reason to override
@ -212,11 +212,10 @@ the box.
Using ``SingleObjectMixin`` with View
-------------------------------------
If we want to write a simple class-based view that responds only to
``POST``, we'll subclass :class:`~django.views.generic.base.View` and
write a ``post()`` method in the subclass. However if we want our
processing to work on a particular object, identified from the URL,
we'll want the functionality provided by
If we want to write a class-based view that responds only to ``POST``, we'll
subclass :class:`~django.views.generic.base.View` and write a ``post()`` method
in the subclass. However if we want our processing to work on a particular
object, identified from the URL, we'll want the functionality provided by
:class:`~django.views.generic.detail.SingleObjectMixin`.
We'll demonstrate this with the ``Author`` model we used in the
@ -249,9 +248,8 @@ In practice you'd probably want to record the interest in a key-value
store rather than in a relational database, so we've left that bit
out. The only bit of the view that needs to worry about using
:class:`~django.views.generic.detail.SingleObjectMixin` is where we want to
look up the author we're interested in, which it just does with a simple call
to ``self.get_object()``. Everything else is taken care of for us by the
mixin.
look up the author we're interested in, which it does with a call to
``self.get_object()``. Everything else is taken care of for us by the mixin.
We can hook this into our URLs easily enough:
@ -288,8 +286,8 @@ object. In order to do this, we need to have two different querysets:
``Book`` queryset for use by :class:`~django.views.generic.list.ListView`
Since we have access to the ``Publisher`` whose books we want to list, we
simply override ``get_queryset()`` and use the ``Publisher``s
:ref:`reverse foreign key manager<backwards-related-objects>`.
override ``get_queryset()`` and use the ``Publisher``s :ref:`reverse
foreign key manager<backwards-related-objects>`.
``Publisher`` queryset for use in :meth:`~django.views.generic.detail.SingleObjectMixin.get_object()`
We'll rely on the default implementation of ``get_object()`` to fetch the
@ -476,24 +474,23 @@ Our new ``AuthorDetail`` looks like this::
# passed in form.cleaned_data['message']
return super().form_valid(form)
``get_success_url()`` is just providing somewhere to redirect to,
``get_success_url()`` is provides somewhere to redirect to,
which gets used in the default implementation of
``form_valid()``. We have to provide our own ``post()`` as noted earlier.
A better solution
-----------------
It should be obvious that the number of subtle interactions between
The number of subtle interactions between
:class:`~django.views.generic.edit.FormMixin` and :class:`DetailView` is
already testing our ability to manage things. It's unlikely you'd want to
write this kind of class yourself.
In this case, it would be fairly easy to just write the ``post()``
method yourself, keeping :class:`DetailView` as the only generic
functionality, although writing :class:`~django.forms.Form` handling code
involves a lot of duplication.
In this case, you could write the ``post()`` method yourself, keeping
:class:`DetailView` as the only generic functionality, although writing
:class:`~django.forms.Form` handling code involves a lot of duplication.
Alternatively, it would still be easier than the above approach to
Alternatively, it would still be less work than the above approach to
have a separate view for processing the form, which could use
:class:`~django.views.generic.edit.FormView` distinct from
:class:`DetailView` without concerns.
@ -529,11 +526,11 @@ write our own ``get_context_data()`` to make the
context['form'] = AuthorInterestForm()
return context
Then the ``AuthorInterest`` is a simple :class:`FormView`, but we
have to bring in :class:`~django.views.generic.detail.SingleObjectMixin` so we
can find the author we're talking about, and we have to remember to set
``template_name`` to ensure that form errors will render the same
template as ``AuthorDisplay`` is using on ``GET``::
Then the ``AuthorInterest`` is a :class:`FormView`, but we have to bring in
:class:`~django.views.generic.detail.SingleObjectMixin` so we can find the
author we're talking about, and we have to remember to set ``template_name`` to
ensure that form errors will render the same template as ``AuthorDisplay`` is
using on ``GET``::
from django.http import HttpResponseForbidden
from django.urls import reverse
@ -593,7 +590,7 @@ rendered HTML.
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::
For example, a JSON mixin might look something like this::
from django.http import JsonResponse
@ -628,8 +625,8 @@ For example, a simple JSON mixin might look something like this::
This mixin provides a ``render_to_json_response()`` method with the same signature
as :func:`~django.views.generic.base.TemplateResponseMixin.render_to_response()`.
To use it, we simply need to mix it into a ``TemplateView`` for example,
and override ``render_to_response()`` to call ``render_to_json_response()`` instead::
To use it, we need to mix it into a ``TemplateView`` for example, and override
``render_to_response()`` to call ``render_to_json_response()`` instead::
from django.views.generic import TemplateView
@ -657,8 +654,8 @@ same behavior -- except for the format of the response.
If you want to be really adventurous, you could even mix a
:class:`~django.views.generic.detail.DetailView` subclass that is able
to return *both* HTML and JSON content, depending on some property of
the HTTP request, such as a query argument or a HTTP header. Just mix
in both the ``JSONResponseMixin`` and a
the HTTP request, such as a query argument or a HTTP header. Mix in both the
``JSONResponseMixin`` and a
:class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`,
and override the implementation of
:func:`~django.views.generic.base.TemplateResponseMixin.render_to_response()`

View file

@ -71,7 +71,7 @@ if they are not already set by the view and if the request's method is safe
(``GET`` or ``HEAD``).
Using this feature usefully is probably best explained with an example.
Suppose you have this pair of models, representing a simple blog system::
Suppose you have this pair of models, representing a small blog system::
import datetime
from django.db import models
@ -205,10 +205,9 @@ every time.
Comparison with middleware conditional processing
=================================================
Django provides simple and straightforward conditional ``GET`` handling via
:class:`django.middleware.http.ConditionalGetMiddleware`. While being easy to
use and suitable for many situations, the middleware has limitations for
advanced usage:
Django provides conditional ``GET`` handling via
:class:`django.middleware.http.ConditionalGetMiddleware`. While being suitable
for many situations, the middleware has limitations for advanced usage:
* It's applied globally to all views in your project.
* It doesn't save you from generating the response, which may be expensive.

View file

@ -135,9 +135,9 @@ by providing that name when you specify the aggregate clause::
>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}
If you want to generate more than one aggregate, you just add another
argument to the ``aggregate()`` clause. So, if we also wanted to know
the maximum and minimum price of all books, we would issue the query::
If you want to generate more than one aggregate, you add another argument to
the ``aggregate()`` clause. So, if we also wanted to know the maximum and
minimum price of all books, we would issue the query::
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))

View file

@ -102,9 +102,9 @@ raises ``ValueError``::
...
ValueError: save() prohibited to prevent data loss due to unsaved related object 'place'.
Restaurant.objects.all() just returns the Restaurants, not the Places. Note
that there are two restaurants - Ace Hardware the Restaurant was created in the
call to r.place = p2::
Restaurant.objects.all() returns the Restaurants, not the Places. Note that
there are two restaurants - Ace Hardware the Restaurant was created in the call
to r.place = p2::
>>> Restaurant.objects.all()
<QuerySet [<Restaurant: Demon Dogs the restaurant>, <Restaurant: Ace Hardware the restaurant>]>

View file

@ -145,8 +145,8 @@ So these statements are all legal::
This example also pointed out another interesting technique: using multiple
managers on the same model. You can attach as many ``Manager()`` instances to
a model as you'd like. This is an easy way to define common "filters" for your
models.
a model as you'd like. This is a non-repetitive way to define common "filters"
for your models.
For example::
@ -396,7 +396,7 @@ manager, you can provide the default manager on the child class::
default_manager = OtherManager()
Here, ``default_manager`` is the default. The ``objects`` manager is
still available, since it's inherited. It just isn't used as the default.
still available, since it's inherited, but isn't used as the default.
Finally for this example, suppose you want to add extra managers to the child
class, but still use the default from ``AbstractBase``. You can't add the new

View file

@ -265,7 +265,7 @@ By default, Django gives each model the following field::
This is an auto-incrementing primary key.
If you'd like to specify a custom primary key, just specify
If you'd like to specify a custom primary key, specify
:attr:`primary_key=True <Field.primary_key>` on one of your fields. If Django
sees you've explicitly set :attr:`Field.primary_key`, it won't add the automatic
``id`` column.
@ -436,8 +436,8 @@ should work; all are optional.
Extra fields on many-to-many relationships
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When you're only dealing with simple many-to-many relationships such as
mixing and matching pizzas and toppings, a standard
When you're only dealing with many-to-many relationships such as mixing and
matching pizzas and toppings, a standard
:class:`~django.db.models.ManyToManyField` is all you need. However, sometimes
you may need to associate data with the relationship between two models.
@ -640,7 +640,7 @@ Models across files
It's perfectly OK to relate a model to one from another app. To do this, import
the related model at the top of the file where your model is defined. Then,
just refer to the other model class wherever needed. For example::
refer to the other model class wherever needed. For example::
from django.db import models
from geography.models import ZipCode
@ -1218,7 +1218,7 @@ accessible through ``MyPerson``, and vice-versa::
You could also use a proxy model to define a different default ordering on
a model. You might not always want to order the ``Person`` model, but regularly
order by the ``last_name`` attribute when you use the proxy. This is easy::
order by the ``last_name`` attribute when you use the proxy::
class OrderedPerson(Person):
class Meta:

View file

@ -438,8 +438,8 @@ Manually selecting a database for a ``QuerySet``
------------------------------------------------
You can select the database for a ``QuerySet`` at any point in the
``QuerySet`` "chain." Just call ``using()`` on the ``QuerySet`` to get
another ``QuerySet`` that uses the specified database.
``QuerySet`` "chain." Call ``using()`` on the ``QuerySet`` to get another
``QuerySet`` that uses the specified database.
``using()`` takes a single argument: the alias of the database on
which you want to run the query. For example::

View file

@ -53,7 +53,7 @@ Use standard DB optimization techniques
* Appropriate use of field types.
We will assume you have done the obvious things above. The rest of this document
We will assume you have done the things listed above. The rest of this document
focuses on how to use Django in such a way that you are not doing unnecessary
work. This document also does not address other optimization techniques that
apply to all expensive operations, such as :doc:`general purpose caching
@ -217,7 +217,7 @@ Don't retrieve things you don't need
Use ``QuerySet.values()`` and ``values_list()``
-----------------------------------------------
When you just want a ``dict`` or ``list`` of values, and don't need ORM model
When you only want a ``dict`` or ``list`` of values, and don't need ORM model
objects, make appropriate usage of
:meth:`~django.db.models.query.QuerySet.values()`.
These can be useful for replacing model objects in template code - as long as
@ -260,7 +260,7 @@ But:
Don't overuse ``count()`` and ``exists()``
------------------------------------------
If you are going to need other data from the QuerySet, just evaluate it.
If you are going to need other data from the QuerySet, evaluate it immediately.
For example, assuming an Email model that has a ``body`` attribute and a
many-to-many relation to User, the following template code is optimal:

View file

@ -96,10 +96,10 @@ Saving ``ForeignKey`` and ``ManyToManyField`` fields
----------------------------------------------------
Updating a :class:`~django.db.models.ForeignKey` field works exactly the same
way as saving a normal field -- simply assign an object of the right type to
the field in question. This example updates the ``blog`` attribute of an
``Entry`` instance ``entry``, assuming appropriate instances of ``Entry`` and
``Blog`` are already saved to the database (so we can retrieve them below)::
way as saving a normal field -- assign an object of the right type to the field
in question. This example updates the ``blog`` attribute of an ``Entry``
instance ``entry``, assuming appropriate instances of ``Entry`` and ``Blog``
are already saved to the database (so we can retrieve them below)::
>>> from blog.models import Blog, Entry
>>> entry = Entry.objects.get(pk=1)
@ -365,9 +365,9 @@ Further filtering or ordering of a sliced queryset is prohibited due to the
ambiguous nature of how that might work.
To retrieve a *single* object rather than a list
(e.g. ``SELECT foo FROM bar LIMIT 1``), use a simple index instead of a
slice. For example, this returns the first ``Entry`` in the database, after
ordering entries alphabetically by headline::
(e.g. ``SELECT foo FROM bar LIMIT 1``), use an index instead of a slice. For
example, this returns the first ``Entry`` in the database, after ordering
entries alphabetically by headline::
>>> Entry.objects.order_by('headline')[0]
@ -484,7 +484,7 @@ Lookups that span relationships
Django offers a powerful and intuitive way to "follow" relationships in
lookups, taking care of the SQL ``JOIN``\s for you automatically, behind the
scenes. To span a relationship, just use the field name of related fields
scenes. To span a relationship, use the field name of related fields
across models, separated by double underscores, until you get to the field you
want.
@ -495,7 +495,7 @@ is ``'Beatles Blog'``::
This spanning can be as deep as you'd like.
It works backwards, too. To refer to a "reverse" relationship, just use the
It works backwards, too. To refer to a "reverse" relationship, use the
lowercase name of the model.
This example retrieves all ``Blog`` objects which have at least one ``Entry``
@ -700,8 +700,8 @@ statement, the percent sign signifies a multiple-character wildcard and the
underscore signifies a single-character wildcard.)
This means things should work intuitively, so the abstraction doesn't leak.
For example, to retrieve all the entries that contain a percent sign, just use
the percent sign as any other character::
For example, to retrieve all the entries that contain a percent sign, use the
percent sign as any other character::
>>> Entry.objects.filter(headline__contains='%')
@ -746,8 +746,8 @@ your database load. Also, there's a possibility the two lists may not include
the same database records, because an ``Entry`` may have been added or deleted
in the split second between the two requests.
To avoid this problem, simply save the
:class:`~django.db.models.query.QuerySet` and reuse it::
To avoid this problem, save the :class:`~django.db.models.query.QuerySet` and
reuse it::
>>> queryset = Entry.objects.all()
>>> print([p.headline for p in queryset]) # Evaluate the query set.
@ -875,7 +875,7 @@ precede the definition of any keyword arguments. For example::
Comparing objects
=================
To compare two model instances, just use the standard Python comparison operator,
To compare two model instances, use the standard Python comparison operator,
the double equals sign: ``==``. Behind the scenes, that compares the primary
key values of two models.
@ -954,7 +954,7 @@ Copying model instances
Although there is no built-in method for copying model instances, it is
possible to easily create new instance with all fields' values copied. In the
simplest case, you can just set ``pk`` to ``None``. Using our blog example::
simplest case, you can set ``pk`` to ``None``. Using our blog example::
blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1
@ -1040,8 +1040,8 @@ statement. It is a bulk operation for direct updates. It doesn't run any
:attr:`~django.db.models.DateField.auto_now` field option.
If you want to save every item in a :class:`~django.db.models.query.QuerySet`
and make sure that the :meth:`~django.db.models.Model.save` method is called on
each instance, you don't need any special function to handle that. Just loop
over them and call :meth:`~django.db.models.Model.save`::
each instance, you don't need any special function to handle that. Loop over
them and call :meth:`~django.db.models.Model.save`::
for item in my_queryset:
item.save()
@ -1096,8 +1096,7 @@ Forward
~~~~~~~
If a model has a :class:`~django.db.models.ForeignKey`, instances of that model
will have access to the related (foreign) object via a simple attribute of the
model.
will have access to the related (foreign) object via an attribute of the model.
Example::
@ -1285,7 +1284,7 @@ One-to-one relationships
One-to-one relationships are very similar to many-to-one relationships. If you
define a :class:`~django.db.models.OneToOneField` on your model, instances of
that model will have access to the related object via a simple attribute of the
that model will have access to the related object via an attribute of the
model.
For example::

View file

@ -16,8 +16,8 @@ Use Cases
Standard textual queries
------------------------
Text-based fields have a selection of simple matching operations. For example,
you may wish to allow lookup of an author like so::
Text-based fields have a selection of matching operations. For example, you may
wish to allow lookup up an author like so::
>>> Author.objects.filter(name__contains='Terry')
[<Author: Terry Gilliam>, <Author: Terry Jones>]
@ -77,7 +77,7 @@ enter something close (by varying definitions) to the source data.
Document-based search
---------------------
Simple database operations are too simple an approach when you start
Standard database operations stop being a useful approach when you start
considering large blocks of text. Whereas the examples above can be thought of
as operations on a string of characters, full text search looks at the actual
words. Depending on the system used, it's likely to use some of the following
@ -109,8 +109,8 @@ your database and so can easily be combined with other relational queries such
as categorization.
The :mod:`django.contrib.postgres` module provides some helpers to make these
queries. For example, a simple query might be to select all the blog entries
which mention "cheese"::
queries. For example, a query might select all the blog entries which mention
"cheese"::
>>> Entry.objects.filter(body_text__search='cheese')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]

View file

@ -46,8 +46,8 @@ return model instances:
This method takes a raw SQL query, executes it, and returns a
``django.db.models.query.RawQuerySet`` instance. This ``RawQuerySet`` instance
can be iterated over just like a normal
:class:`~django.db.models.query.QuerySet` to provide object instances.
can be iterated over like a normal :class:`~django.db.models.query.QuerySet` to
provide object instances.
This is best illustrated with an example. Suppose you have the following model::

View file

@ -61,7 +61,7 @@ either all or none of the changes will be committed.
generating a streaming response, since there's no sensible way to handle
errors after starting to send the response.
In practice, this feature simply wraps every view function in the :func:`atomic`
In practice, this feature wraps every view function in the :func:`atomic`
decorator described below.
Note that only the execution of your view is enclosed in the transactions.
@ -410,7 +410,7 @@ For instance, if your database connection is dropped because your process was
killed without a chance to shut down gracefully, your rollback hook will never
run.
The solution is simple: instead of doing something during the atomic block
But there is a solution: instead of doing something during the atomic block
(transaction) and then undoing it if the transaction fails, use
:func:`on_commit` to delay doing it in the first place until after the
transaction succeeds. It's a lot easier to undo something you never did in the
@ -432,8 +432,8 @@ Low-level APIs
Autocommit
----------
Django provides a straightforward API in the :mod:`django.db.transaction`
module to manage the autocommit state of each database connection.
Django provides an API in the :mod:`django.db.transaction` module to manage the
autocommit state of each database connection.
.. function:: get_autocommit(using=None)
@ -622,7 +622,7 @@ Handling exceptions within PostgreSQL transactions
Inside a transaction, when a call to a PostgreSQL cursor raises an exception
(typically ``IntegrityError``), all subsequent SQL in the same transaction
will fail with the error "current transaction is aborted, queries ignored
until end of transaction block". While simple use of ``save()`` is unlikely
until end of transaction block". While the basic use of ``save()`` is unlikely
to raise an exception in PostgreSQL, there are more advanced usage patterns
which might, such as saving objects with unique fields, saving using the
force_insert/force_update flag, or invoking custom SQL.

View file

@ -5,11 +5,10 @@ Sending email
.. module:: django.core.mail
:synopsis: Helpers to easily send email.
Although Python makes sending email relatively easy via the :mod:`smtplib`
Although Python provides a mail sending interface via the :mod:`smtplib`
module, Django provides a couple of light wrappers over it. These wrappers are
provided to make sending email extra quick, to make it easy to test email
sending during development, and to provide support for platforms that can't use
SMTP.
provided to make sending email extra quick, to help test email sending during
development, and to provide support for platforms that can't use SMTP.
The code lives in the ``django.core.mail`` module.
@ -45,8 +44,7 @@ a secure connection is used.
.. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)
The simplest way to send email is using
``django.core.mail.send_mail()``.
In most cases, you can send email using ``django.core.mail.send_mail()``.
The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters
are required.
@ -186,7 +184,7 @@ will not send the email. It's your responsibility to validate all data before
passing it to the email functions.
If a ``message`` contains headers at the start of the string, the headers will
simply be printed as the first bit of the email message.
be printed as the first bit of the email message.
Here's an example view that takes a ``subject``, ``message`` and ``from_email``
from the request's POST data, sends that to admin@example.com and redirects to
@ -239,9 +237,9 @@ recipients, file attachments, or multi-part email, you'll need to create
message itself. The :ref:`email backend <topic-email-backends>` is then
responsible for sending the email.
For convenience, :class:`~django.core.mail.EmailMessage` provides a simple
``send()`` method for sending a single email. If you need to send multiple
messages, the email backend API :ref:`provides an alternative
For convenience, :class:`~django.core.mail.EmailMessage` provides a ``send()``
method for sending a single email. If you need to send multiple messages, the
email backend API :ref:`provides an alternative
<topics-sending-multiple-emails>`.
``EmailMessage`` Objects
@ -360,7 +358,7 @@ The class has the following methods:
* ``attach_file()`` creates a new attachment using a file from your
filesystem. Call it with the path of the file to attach and, optionally,
the MIME type to use for the attachment. If the MIME type is omitted, it
will be guessed from the filename. The simplest use would be::
will be guessed from the filename. You can use it like this::
message.attach_file('/images/weather_map.png')
@ -672,9 +670,9 @@ anything. Python has a built-in way to accomplish this with a single command::
python -m smtpd -n -c DebuggingServer localhost:1025
This command will start a simple SMTP server listening on port 1025 of
localhost. This server simply prints to standard output all email headers and
the email body. You then only need to set the :setting:`EMAIL_HOST` and
This command will start a minimal SMTP server listening on port 1025 of
localhost. This server prints to standard output all email headers and the
email body. You then only need to set the :setting:`EMAIL_HOST` and
:setting:`EMAIL_PORT` accordingly. For a more detailed discussion of SMTP
server options, see the Python documentation for the :mod:`smtpd` module.

View file

@ -79,8 +79,8 @@ The ``File`` object
Internally, Django uses a :class:`django.core.files.File` instance any time it
needs to represent a file.
Most of the time you'll simply use a ``File`` that Django's given you (i.e. a
file attached to a model as above, or perhaps an uploaded file).
Most of the time you'll use a ``File`` that Django's given you (i.e. a file
attached to a model as above, or perhaps an uploaded file).
If you need to construct a ``File`` yourself, the easiest way is to create one
using a Python built-in ``file`` object::

View file

@ -569,8 +569,8 @@ Adding additional fields to a formset
If you need to add additional fields to the formset this can be easily
accomplished. The formset base class provides an ``add_fields`` method. You
can simply override this method to add your own fields or even redefine the
default fields/attributes of the order and deletion fields::
can override this method to add your own fields or even redefine the default
fields/attributes of the order and deletion fields::
>>> from django.forms import BaseFormSet
>>> from django.forms import formset_factory
@ -651,9 +651,9 @@ This is useful if you want to :ref:`use more than one formset in a view
Using a formset in views and templates
======================================
Using a formset inside a view is as easy as using a regular ``Form`` class.
The only thing you will want to be aware of is making sure to use the
management form inside the template. Let's look at a sample view::
Using a formset inside a view is not very different from using a regular
``Form`` class. The only thing you will want to be aware of is making sure to
use the management form inside the template. Let's look at a sample view::
from django.forms import formset_factory
from django.shortcuts import render

View file

@ -26,11 +26,11 @@ allow a visitor to do things like enter text, select options, manipulate
objects or controls, and so on, and then send that information back to the
server.
Some of these form interface elements - text input or checkboxes - are fairly
simple and are built into HTML itself. Others are much more complex; an
interface that pops up a date picker or allows you to move a slider or
manipulate controls will typically use JavaScript and CSS as well as HTML form
``<input>`` elements to achieve these effects.
Some of these form interface elements - text input or checkboxes - are built
into HTML itself. Others are much more complex; an interface that pops up a
date picker or allows you to move a slider or manipulate controls will
typically use JavaScript and CSS as well as HTML form ``<input>`` elements to
achieve these effects.
As well as its ``<input>`` elements, a form must specify two things:
@ -326,8 +326,7 @@ telling it where to go next.
The template
~~~~~~~~~~~~
We don't need to do much in our ``name.html`` template. The simplest example
is:
We don't need to do much in our ``name.html`` template:
.. code-block:: html+django
@ -671,8 +670,7 @@ Useful attributes on ``{{ field }}`` include:
Outputs a ``<ul class="errorlist">`` containing any validation errors
corresponding to this field. You can customize the presentation of
the errors with a ``{% for error in field.errors %}`` loop. In this
case, each object in the loop is a simple string containing the error
message.
case, each object in the loop is a string containing the error message.
``{{ field.is_hidden }}``
This attribute is ``True`` if the form field is a hidden field and

View file

@ -16,7 +16,7 @@ Calendar widget. This widget can then be associated with the CSS and
JavaScript that is required to render the calendar. When the Calendar
widget is used on a form, Django is able to identify the CSS and
JavaScript files that are required, and provide the list of file names
in a form suitable for easy inclusion on your Web page.
in a form suitable for inclusion on your Web page.
.. admonition:: Assets and Django Admin
@ -49,7 +49,7 @@ The easiest way to define assets is as a static definition. Using this
method, the declaration is an inner ``Media`` class. The properties of the
inner class define the requirements.
Here's a simple example::
Here's an example::
from django import forms
@ -362,8 +362,7 @@ are part of the form::
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
If you want to associate additional assets with a form -- for example,
CSS for form layout -- simply add a ``Media`` declaration to the
form::
CSS for form layout -- add a ``Media`` declaration to the form::
>>> class ContactForm(forms.Form):
... date = DateField(widget=CalendarWidget)

View file

@ -389,9 +389,8 @@ you've manually saved the instance produced by the form, you can invoke
>>> f.save_m2m()
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
When you use a simple ``save()`` on a form, all data -- including
many-to-many data -- is saved without the need for any additional method calls.
For example:
When you use a ``save()`` on a form, all data -- including many-to-many data --
is saved without the need for any additional method calls. For example:
.. code-block:: python
@ -731,8 +730,8 @@ to make::
>>> from myapp.models import Book
>>> BookForm = modelform_factory(Book, fields=("author", "title"))
This can also be used to make simple modifications to existing forms, for
example by specifying the widgets to be used for a given field::
This can also be used to make modifications to existing forms, for example by
specifying the widgets to be used for a given field::
>>> from django.forms import Textarea
>>> Form = modelform_factory(Book, form=BookForm,
@ -755,8 +754,8 @@ Model formsets
.. class:: models.BaseModelFormSet
Like :doc:`regular formsets </topics/forms/formsets>`, Django provides a couple
of enhanced formset classes that make it easy to work with Django models. Let's
reuse the ``Author`` model from above::
of enhanced formset classes to make working with Django models more
convenient. Let's reuse the ``Author`` model from above::
>>> from django.forms import modelformset_factory
>>> from myapp.models import Author
@ -786,8 +785,8 @@ with the ``Author`` model. It works just like a regular formset::
:func:`~django.forms.models.modelformset_factory` uses
:func:`~django.forms.formsets.formset_factory` to generate formsets. This
means that a model formset is just an extension of a basic formset that
knows how to interact with a particular model.
means that a model formset is an extension of a basic formset that knows
how to interact with a particular model.
Changing the queryset
---------------------
@ -952,7 +951,7 @@ extra forms displayed.
Also, ``extra=0`` doesn't prevent creation of new model instances as you can
:ref:`add additional forms with JavaScript <understanding-the-managementform>`
or just send additional POST data. Formsets `don't yet provide functionality
or send additional POST data. Formsets `don't yet provide functionality
<https://code.djangoproject.com/ticket/26142>`_ for an "edit only" view that
prevents creation of new instances.

View file

@ -19,7 +19,7 @@ and in memory, and how to customize the default behavior.
Basic file uploads
==================
Consider a simple form containing a :class:`~django.forms.FileField`:
Consider a form containing a :class:`~django.forms.FileField`:
.. code-block:: python
:caption: forms.py
@ -42,9 +42,8 @@ contain data if the request method was ``POST`` and the ``<form>`` that posted
the request has the attribute ``enctype="multipart/form-data"``. Otherwise,
``request.FILES`` will be empty.
Most of the time, you'll simply pass the file data from ``request`` into the
form as described in :ref:`binding-uploaded-files`. This would look
something like:
Most of the time, you'll pass the file data from ``request`` into the form as
described in :ref:`binding-uploaded-files`. This would look something like:
.. code-block:: python
:caption: views.py
@ -107,9 +106,9 @@ corresponding :class:`~django.db.models.FileField` when calling
form = ModelFormWithFileField()
return render(request, 'upload.html', {'form': form})
If you are constructing an object manually, you can simply assign the file
object from :attr:`request.FILES <django.http.HttpRequest.FILES>` to the file
field in the model::
If you are constructing an object manually, you can assign the file object from
:attr:`request.FILES <django.http.HttpRequest.FILES>` to the file field in the
model::
from django.http import HttpResponseRedirect
from django.shortcuts import render
@ -205,8 +204,8 @@ platform this means you can expect Django to generate a file called something
like ``/tmp/tmpzfp6I6.upload``. If an upload is large enough, you can watch this
file grow in size as Django streams the data onto disk.
These specifics -- 2.5 megabytes; ``/tmp``; etc. -- are simply "reasonable
defaults" which can be customized as described in the next section.
These specifics -- 2.5 megabytes; ``/tmp``; etc. -- are "reasonable defaults"
which can be customized as described in the next section.
Changing upload handler behavior
--------------------------------
@ -235,7 +234,7 @@ You'd probably want to use ``list.insert()`` in this case (instead of
``append()``) because a progress bar handler would need to run *before* any
other handlers. Remember, the upload handlers are processed in order.
If you want to replace the upload handlers completely, you can just assign a new
If you want to replace the upload handlers completely, you can assign a new
list::
request.upload_handlers = [ProgressBarUploadHandler(request)]

View file

@ -379,7 +379,7 @@ convenience and security. If you wish to store more advanced data types
including ``datetime`` and ``Decimal`` in JSON backed sessions, you will need
to write a custom serializer (or convert such values to a JSON serializable
object before storing them in ``request.session``). While serializing these
values is fairly straightforward
values is often straightforward
(:class:`~django.core.serializers.json.DjangoJSONEncoder` may be helpful),
writing a decoder that can reliably get back the same thing that you put in is
more fragile. For example, you run the risk of returning a ``datetime`` that
@ -444,10 +444,9 @@ objects, not as a full ``logout()`` implementation.
Setting test cookies
====================
As a convenience, Django provides an easy way to test whether the user's
browser accepts cookies. Just call the
:meth:`~backends.base.SessionBase.set_test_cookie` method of
``request.session`` in a view, and call
As a convenience, Django provides a way to test whether the user's browser
accepts cookies. Call the :meth:`~backends.base.SessionBase.set_test_cookie`
method of ``request.session`` in a view, and call
:meth:`~backends.base.SessionBase.test_cookie_worked` in a subsequent view --
not in the same view call.
@ -509,7 +508,7 @@ generating a ``session_key`` that collides with an existing one. ``create()``
calls ``save()`` and loops until an unused ``session_key`` is generated.
If you're using the ``django.contrib.sessions.backends.db`` backend, each
session is just a normal Django model. The ``Session`` model is defined in
session is a normal Django model. The ``Session`` model is defined in
``django/contrib/sessions/models.py``. Because it's a normal model, you can
access sessions using the normal Django database API::
@ -701,9 +700,9 @@ In order to build a custom session engine or to customize an existing one, you
may create a new class inheriting from :class:`~backends.base.SessionBase` or
any other existing ``SessionStore`` class.
Extending most of the session engines is quite straightforward, but doing so
with database-backed session engines generally requires some extra effort (see
the next section for details).
You can extend the session engines, but doing so with database-backed session
engines generally requires some extra effort (see the next section for
details).
.. _extending-database-backed-session-engines:

View file

@ -48,7 +48,7 @@ algorithm the system follows to determine which Python code to execute:
one that matches the requested URL.
#. Once one of the URL patterns matches, Django imports and calls the given
view, which is a simple Python function (or a :doc:`class-based view
view, which is a Python function (or a :doc:`class-based view
</topics/class-based-views/index>`). The view gets passed the following
arguments:
@ -131,7 +131,7 @@ The following path converters are available by default:
* ``path`` - Matches any non-empty string, including the path separator,
``'/'``. This allows you to match against a complete URL path rather than
just a segment of a URL path as with ``str``.
a segment of a URL path as with ``str``.
.. _registering-custom-path-converters:
@ -679,13 +679,13 @@ instances of an application are deployed. In other words, since multiple
instances of a single application will share named URLs, namespaces provide a
way to tell these named URLs apart.
Django applications that make proper use of URL namespacing can be deployed more
than once for a particular site. For example :mod:`django.contrib.admin` has an
:class:`~django.contrib.admin.AdminSite` class which allows you to easily
:ref:`deploy more than one instance of the admin <multiple-admin-sites>`.
In a later example, we'll discuss the idea of deploying the polls application
from the tutorial in two different locations so we can serve the same
functionality to two different audiences (authors and publishers).
Django applications that make proper use of URL namespacing can be deployed
more than once for a particular site. For example :mod:`django.contrib.admin`
has an :class:`~django.contrib.admin.AdminSite` class which allows you to
:ref:`deploy more than one instance of the admin <multiple-admin-sites>`. In a
later example, we'll discuss the idea of deploying the polls application from
the tutorial in two different locations so we can serve the same functionality
to two different audiences (authors and publishers).
A URL namespace comes in two parts, both of which are strings:

View file

@ -2,7 +2,7 @@
Writing views
=============
A view function, or *view* for short, is simply a Python function that takes a
A view function, or *view* for short, is a Python function that takes a
Web request and returns a Web response. This response can be the HTML contents
of a Web page, or a redirect, or a 404 error, or an XML document, or an image .
. . or anything, really. The view itself contains whatever arbitrary logic is
@ -60,12 +60,12 @@ date and time. To display this view at a particular URL, you'll need to create a
Returning errors
================
Returning HTTP error codes in Django is easy. There are subclasses of
Django provides help for returning HTTP error codes. There are subclasses of
:class:`~django.http.HttpResponse` for a number of common HTTP status codes
other than 200 (which means *"OK"*). You can find the full list of available
subclasses in the :ref:`request/response <ref-httpresponse-subclasses>`
documentation. Just return an instance of one of those subclasses instead of
a normal :class:`~django.http.HttpResponse` in order to signify an error. For
documentation. Return an instance of one of those subclasses instead of a
normal :class:`~django.http.HttpResponse` in order to signify an error. For
example::
from django.http import HttpResponse, HttpResponseNotFound
@ -138,9 +138,9 @@ Customizing error views
=======================
The default error views in Django should suffice for most Web applications,
but can easily be overridden if you need any custom behavior. Simply specify
the handlers as seen below in your URLconf (setting them anywhere else will
have no effect).
but can easily be overridden if you need any custom behavior. Specify the
handlers as seen below in your URLconf (setting them anywhere else will have no
effect).
The :func:`~django.views.defaults.page_not_found` view is overridden by
:data:`~django.conf.urls.handler404`::

View file

@ -45,8 +45,8 @@ locales when guessing the format used by the user when inputting data on forms.
``%b`` (abbreviated month name), ``%B`` (full month name),
or ``%p`` (AM/PM).
To enable a form field to localize input and output data simply use its
``localize`` argument::
To enable a form field to localize input and output data use its ``localize``
argument::
class CashRegisterForm(forms.Form):
product = forms.CharField()
@ -152,8 +152,8 @@ want to create your own, because a format files doesn't exist for your locale,
or because you want to overwrite some of the values.
To use custom formats, specify the path where you'll place format files
first. To do that, just set your :setting:`FORMAT_MODULE_PATH` setting to
the package where format files will exist, for instance::
first. To do that, set your :setting:`FORMAT_MODULE_PATH` setting to the
package where format files will exist, for instance::
FORMAT_MODULE_PATH = [
'mysite.formats',

View file

@ -28,9 +28,9 @@ Essentially, Django does two things:
* It uses these hooks to localize Web apps for particular users according to
their preferences.
Obviously, translation depends on the target language, and formatting usually
depends on the target country. This information is provided by browsers in
the ``Accept-Language`` header. However, the time zone isn't readily available.
Translation depends on the target language, and formatting usually depends on
the target country. This information is provided by browsers in the
``Accept-Language`` header. However, the time zone isn't readily available.
Definitions
===========

View file

@ -62,8 +62,8 @@ You can use :func:`~django.utils.timezone.is_aware` and
aware or naive.
When time zone support is disabled, Django uses naive datetime objects in local
time. This is simple and sufficient for many use cases. In this mode, to obtain
the current time, you would write::
time. This is sufficient for many use cases. In this mode, to obtain the
current time, you would write::
import datetime
@ -155,11 +155,11 @@ time zone automatically. Instead, Django provides :ref:`time zone selection
functions <time-zone-selection-functions>`. Use them to build the time zone
selection logic that makes sense for you.
Most websites that care about time zones just ask users in which time zone they
live and store this information in the user's profile. For anonymous users,
they use the time zone of their primary audience or UTC. pytz_ provides
helpers_, like a list of time zones per country, that you can use to pre-select
the most likely choices.
Most websites that care about time zones ask users in which time zone they live
and store this information in the user's profile. For anonymous users, they use
the time zone of their primary audience or UTC. pytz_ provides helpers_, like a
list of time zones per country, that you can use to pre-select the most likely
choices.
Here's an example that stores the current timezone in the session. (It skips
error handling entirely for the sake of simplicity.)
@ -437,7 +437,7 @@ When serializing an aware datetime, the UTC offset is included, like this::
"2011-09-01T13:20:30+03:00"
For a naive datetime, it obviously isn't::
While for a naive datetime, it isn't::
"2011-09-01T13:20:30"
@ -451,8 +451,8 @@ zone support, you'll see :exc:`RuntimeWarning`\ s when you load them. To get
rid of the warnings, you must convert your fixtures to the "aware" format.
You can regenerate fixtures with :djadmin:`loaddata` then :djadmin:`dumpdata`.
Or, if they're small enough, you can simply edit them to add the UTC offset
that matches your :setting:`TIME_ZONE` to each serialized datetime.
Or, if they're small enough, you can edit them to add the UTC offset that
matches your :setting:`TIME_ZONE` to each serialized datetime.
.. _time-zones-faq:
@ -470,8 +470,8 @@ Setup
When you enable time zone support, you'll encounter some errors because
you're using naive datetimes where Django expects aware datetimes. Such
errors show up when running tests and they're easy to fix. You'll quickly
learn how to avoid invalid operations.
errors show up when running tests. You'll quickly learn how to avoid invalid
operations.
On the other hand, bugs caused by the lack of time zone support are much
harder to prevent, diagnose and fix. Anything that involves scheduled tasks
@ -613,7 +613,7 @@ Troubleshooting
>>> from django.utils import timezone
>>> timezone.activate(pytz.timezone("Asia/Singapore"))
# For this example, we just set the time zone to Singapore, but here's how
# For this example, we set the time zone to Singapore, but here's how
# you would obtain the current time zone in the general case.
>>> current_tz = timezone.get_current_timezone()
# Again, this is the correct way to convert between time zones with pytz.

View file

@ -91,8 +91,8 @@ string::
output = _("Welcome to my site.")
return HttpResponse(output)
Obviously, you could code this without using the alias. This example is
identical to the previous one::
You could code this without using the alias. This example is identical to the
previous one::
from django.http import HttpResponse
from django.utils.translation import gettext
@ -439,8 +439,8 @@ strings before passing them to non-Django code::
requests.post('https://example.com/send', data={'body': str(body)})
If you don't like the long ``gettext_lazy`` name, you can just alias it as
``_`` (underscore), like so::
If you don't like the long ``gettext_lazy`` name, you can alias it as ``_``
(underscore), like so::
from django.db import models
from django.utils.translation import gettext_lazy as _
@ -928,7 +928,7 @@ view <set_language-redirect-view>` for an example of how to display a language
selector using ``{% get_language_info_list %}``.
In addition to :setting:`LANGUAGES` style list of tuples,
``{% get_language_info_list %}`` supports simple lists of language codes.
``{% get_language_info_list %}`` supports lists of language codes.
If you do this in your view:
.. code-block:: python
@ -949,7 +949,7 @@ you can iterate over those languages in the template::
Template filters
~~~~~~~~~~~~~~~~
There are also simple filters available for convenience:
There are also some filters available for convenience:
* ``{{ LANGUAGE_CODE|language_name }}`` ("German")
* ``{{ LANGUAGE_CODE|language_name_local }}`` ("Deutsch")
@ -1048,7 +1048,7 @@ Using the JavaScript translation catalog
.. highlightlang:: javascript
To use the catalog, just pull in the dynamically generated script like this:
To use the catalog, pull in the dynamically generated script like this:
.. code-block:: html+django
@ -1565,9 +1565,9 @@ multiple times::
If you don't have the ``gettext`` utilities installed,
:djadmin:`makemessages` will create empty files. If that's the case, either
install the ``gettext`` utilities or just copy the English message file
install the ``gettext`` utilities or copy the English message file
(``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
point; it's just an empty translation file.
point, which is an empty translation file.
.. admonition:: Working on Windows?
@ -1575,11 +1575,10 @@ multiple times::
:djadmin:`makemessages` works, see :ref:`gettext_on_windows` for more
information.
The format of ``.po`` files is straightforward. Each ``.po`` file contains a
small bit of metadata, such as the translation maintainer's contact
information, but the bulk of the file is a list of **messages** -- simple
mappings between translation strings and the actual translated text for the
particular language.
Each ``.po`` file contains a small bit of metadata, such as the translation
maintainer's contact information, but the bulk of the file is a list of
**messages** -- mappings between translation strings and the actual translated
text for the particular language.
For example, if your Django app contained a translation string for the text
``"Welcome to my site."``, like so::
@ -1693,7 +1692,7 @@ djangojs`` parameter, like this::
django-admin makemessages -d djangojs -l de
This would create or update the message file for JavaScript for German. After
updating message files, just run :djadmin:`django-admin compilemessages
updating message files, run :djadmin:`django-admin compilemessages
<compilemessages>` the same way as you do with normal Django message files.
.. _gettext_on_windows:
@ -1702,9 +1701,9 @@ updating message files, just run :djadmin:`django-admin compilemessages
----------------------
This is only needed for people who either want to extract message IDs or compile
message files (``.po``). Translation work itself just involves editing existing
files of this type, but if you want to create your own message files, or want to
test or compile a changed message file, download `a precompiled binary
message files (``.po``). Translation work itself involves editing existing
files of this type, but if you want to create your own message files, or want
to test or compile a changed message file, download `a precompiled binary
installer <https://mlocati.github.io/articles/gettext-iconv-windows.html>`_.
You may also use ``gettext`` binaries you have obtained elsewhere, so long as
@ -1935,9 +1934,9 @@ way Django does translation:
How Django discovers language preference
----------------------------------------
Once you've prepared your translations -- or, if you just want to use the
translations that come with Django -- you'll just need to activate translation
for your app.
Once you've prepared your translations -- or, if you want to use the
translations that come with Django -- you'll need to activate translation for
your app.
Behind the scenes, Django has a very flexible model of deciding which language
should be used -- installation-wide, for a particular user, or both.
@ -2042,7 +2041,7 @@ Notes:
Once ``LocaleMiddleware`` determines the user's preference, it makes this
preference available as ``request.LANGUAGE_CODE`` for each
:class:`~django.http.HttpRequest`. Feel free to read this value in your view
code. Here's a simple example::
code. Here's an example::
from django.http import HttpResponse
@ -2098,8 +2097,8 @@ of the generic language. For example, untranslated ``pt_BR`` strings use ``pt``
translations.
This way, you can write applications that include their own translations, and
you can override base translations in your project. Or, you can just build
a big project out of several apps and put all translations into one big common
you can override base translations in your project. Or, you can build a big
project out of several apps and put all translations into one big common
message file specific to the project you are composing. The choice is yours.
All message file repositories are structured the same way. They are:

View file

@ -72,10 +72,10 @@ sure a database server is running. Django supports many different database
servers and is officially supported with PostgreSQL_, MariaDB_, MySQL_, Oracle_
and SQLite_.
If you are developing a simple project or something you don't plan to deploy
in a production environment, SQLite is generally the simplest option as it
doesn't require running a separate server. However, SQLite has many differences
from other databases, so if you are working on something substantial, it's
If you are developing a small project or something you don't plan to deploy in
a production environment, SQLite is generally the best option as it doesn't
require running a separate server. However, SQLite has many differences from
other databases, so if you are working on something substantial, it's
recommended to develop with the same database that you plan on using in
production.
@ -107,10 +107,10 @@ If you plan to use Django's ``manage.py migrate`` command to automatically
create database tables for your models (after first installing Django and
creating a project), you'll need to ensure that Django has permission to create
and alter tables in the database you're using; if you plan to manually create
the tables, you can simply grant Django ``SELECT``, ``INSERT``, ``UPDATE`` and
``DELETE`` permissions. After creating a database user with these
permissions, you'll specify the details in your project's settings file,
see :setting:`DATABASES` for details.
the tables, you can grant Django ``SELECT``, ``INSERT``, ``UPDATE`` and
``DELETE`` permissions. After creating a database user with these permissions,
you'll specify the details in your project's settings file, see
:setting:`DATABASES` for details.
If you're using Django's :doc:`testing framework</topics/testing/index>` to test
database queries, Django will need permission to create a test database.
@ -132,8 +132,6 @@ Installation instructions are slightly different depending on whether you're
installing a distribution-specific package, downloading the latest official
release, or fetching the latest development version.
It's easy, no matter which way you choose.
.. _installing-official-release:
Installing an official release with ``pip``
@ -171,7 +169,7 @@ Installing a distribution-specific package
Check the :doc:`distribution specific notes </misc/distributions>` to see if
your platform/distribution provides official Django packages/installers.
Distribution-provided packages will typically allow for automatic installation
of dependencies and easy upgrade paths; however, these packages will rarely
of dependencies and supported upgrade paths; however, these packages will rarely
contain the latest release of Django.
.. _installing-development-version:
@ -221,8 +219,8 @@ latest bug fixes and improvements, follow these instructions:
``django-admin`` utility command available. In other words, you're all
set!
When you want to update your copy of the Django source code, just run the
command ``git pull`` from within the ``django`` directory. When you do this,
Git will automatically download any changes.
When you want to update your copy of the Django source code, run the command
``git pull`` from within the ``django`` directory. When you do this, Git will
download any changes.
.. _Git: https://git-scm.com/

View file

@ -122,7 +122,7 @@ Using logging
Once you have configured your loggers, handlers, filters and
formatters, you need to place logging calls into your code. Using the
logging framework is very simple. Here's an example::
logging framework works like this::
# import the logging library
import logging
@ -239,7 +239,7 @@ The full documentation for :ref:`dictConfig format <logging-config-dictschema>`
is the best source of information about logging configuration dictionaries.
However, to give you a taste of what is possible, here are several examples.
First, here's a simple configuration which writes all logging from the
First, here's a configuration which writes all logging from the
:ref:`django-logger` logger to a local file::
.. code-block:: python
@ -363,8 +363,8 @@ This logging configuration does the following things:
* Defines two formatters:
* ``simple``, that just outputs the log level name (e.g.,
``DEBUG``) and the log message.
* ``simple``, that outputs the log level name (e.g., ``DEBUG``) and the log
message.
The ``format`` string is a normal Python formatting string
describing the details that are to be output on each logging

View file

@ -114,8 +114,8 @@ Django projects without the need for a full database.
Workflow
========
Working with migrations is simple. Make changes to your models - say, add
a field and remove a model - and then run :djadmin:`makemigrations`::
Django can create migrations for you. Make changes to your models - say, add a
field and remove a model - and then run :djadmin:`makemigrations`::
$ python manage.py makemigrations
Migrations for 'books':
@ -173,10 +173,10 @@ Dependencies
============
While migrations are per-app, the tables and relationships implied by
your models are too complex to be created for just one app at a time. When
you make a migration that requires something else to run - for example,
you add a ``ForeignKey`` in your ``books`` app to your ``authors`` app - the
resulting migration will contain a dependency on a migration in ``authors``.
your models are too complex to be created for one app at a time. When you make
a migration that requires something else to run - for example, you add a
``ForeignKey`` in your ``books`` app to your ``authors`` app - the resulting
migration will contain a dependency on a migration in ``authors``.
This means that when you run the migrations, the ``authors`` migration runs
first and creates the table the ``ForeignKey`` references, and then the migration
@ -201,8 +201,8 @@ Migration files
===============
Migrations are stored as an on-disk format, referred to here as
"migration files". These files are actually just normal Python files with
an agreed-upon object layout, written in a declarative style.
"migration files". These files are actually normal Python files with an
agreed-upon object layout, written in a declarative style.
A basic migration file looks like this::
@ -286,9 +286,8 @@ Initial migrations
.. attribute:: Migration.initial
The "initial migrations" for an app are the migrations that create the first
version of that app's tables. Usually an app will have just one initial
migration, but in some cases of complex model interdependencies it may have two
or more.
version of that app's tables. Usually an app will have one initial migration,
but in some cases of complex model interdependencies it may have two or more.
Initial migrations are marked with an ``initial = True`` class attribute on the
migration class. If an ``initial`` class attribute isn't found, a migration
@ -322,13 +321,12 @@ new migrations until it's fixed. When using multiple databases, you can use the
Adding migrations to apps
=========================
Adding migrations to new apps is straightforward - they come preconfigured to
accept migrations, and so just run :djadmin:`makemigrations` once you've made
some changes.
New apps come preconfigured to accept migrations, and so you can add migrations
by running :djadmin:`makemigrations` once you've made some changes.
If your app already has models and database tables, and doesn't have migrations
yet (for example, you created it against a previous Django version), you'll
need to convert it to use migrations; this is a simple process::
need to convert it to use migrations by running::
$ python manage.py makemigrations your_app_label
@ -390,8 +388,8 @@ classes will need to be kept around for as long as there is a migration
referencing them. Any :doc:`custom model fields </howto/custom-model-fields>`
will also need to be kept, since these are imported directly by migrations.
In addition, the base classes of the model are just stored as pointers, so you
must always keep base classes around for as long as there is a migration that
In addition, the base classes of the model are stored as pointers, so you must
always keep base classes around for as long as there is a migration that
contains a reference to them. On the plus side, methods and managers from these
base classes inherit normally, so if you absolutely need access to these you
can opt to move them into a superclass.
@ -492,10 +490,10 @@ second is a :doc:`SchemaEditor </ref/schema-editor>`, which you can use to
manually effect database schema changes (but beware, doing this can confuse
the migration autodetector!)
Let's write a simple migration that populates our new ``name`` field with the
combined values of ``first_name`` and ``last_name`` (we've come to our senses
and realized that not everyone has first and last names). All we
need to do is use the historical model and iterate over the rows::
Let's write a migration that populates our new ``name`` field with the combined
values of ``first_name`` and ``last_name`` (we've come to our senses and
realized that not everyone has first and last names). All we need to do is use
the historical model and iterate over the rows::
from django.db import migrations
@ -517,8 +515,8 @@ need to do is use the historical model and iterate over the rows::
migrations.RunPython(combine_names),
]
Once that's done, we can just run ``python manage.py migrate`` as normal and
the data migration will run in place alongside other migrations.
Once that's done, we can run ``python manage.py migrate`` as normal and the
data migration will run in place alongside other migrations.
You can pass a second callable to
:class:`~django.db.migrations.operations.RunPython` to run whatever logic you
@ -593,18 +591,17 @@ so they can coexist with the old migration files, and Django will intelligently
switch between them depending where you are in the history. If you're still
part-way through the set of migrations that you squashed, it will keep using
them until it hits the end and then switch to the squashed history, while new
installs will just use the new squashed migration and skip all the old ones.
installs will use the new squashed migration and skip all the old ones.
This enables you to squash and not mess up systems currently in production
that aren't fully up-to-date yet. The recommended process is to squash, keeping
the old files, commit and release, wait until all systems are upgraded with
the new release (or if you're a third-party project, just ensure your users
upgrade releases in order without skipping any), and then remove the old files,
commit and do a second release.
the new release (or if you're a third-party project, ensure your users upgrade
releases in order without skipping any), and then remove the old files, commit
and do a second release.
The command that backs all this is :djadmin:`squashmigrations` - just pass
it the app label and migration name you want to squash up to, and it'll get to
work::
The command that backs all this is :djadmin:`squashmigrations` - pass it the
app label and migration name you want to squash up to, and it'll get to work::
$ ./manage.py squashmigrations myapp 0004
Will squash the following migrations:
@ -660,7 +657,7 @@ You must then transition the squashed migration to a normal migration by:
Serializing values
==================
Migrations are just Python files containing the old definitions of your models
Migrations are Python files containing the old definitions of your models
- thus, to write them, Django must take the current state of your models and
serialize them out into a file.

View file

@ -86,7 +86,7 @@ Get things right from the start
-------------------------------
Some work in optimization involves tackling performance shortcomings, but some
of the work can simply be built in to what you'd do anyway, as part of the good
of the work can be built in to what you'd do anyway, as part of the good
practices you should adopt even before you start thinking about improving
performance.
@ -353,7 +353,7 @@ Newer is often - but not always - better
It's fairly rare for a new release of well-maintained software to be less
efficient, but the maintainers can't anticipate every possible use-case - so
while being aware that newer versions are likely to perform better, don't
simply assume that they always will.
assume that they always will.
This is true of Django itself. Successive releases have offered a number of
improvements across the system, but you should still check the real-world

View file

@ -66,10 +66,10 @@ this if you know what you are doing. There are other :ref:`limitations
control.
:ref:`CSRF protection works <how-csrf-works>` by checking for a secret in each
POST request. This ensures that a malicious user cannot simply "replay" a form
POST to your website and have another logged in user unwittingly submit that
form. The malicious user would have to know the secret, which is user specific
(using a cookie).
POST request. This ensures that a malicious user cannot "replay" a form POST to
your website and have another logged in user unwittingly submit that form. The
malicious user would have to know the secret, which is user specific (using a
cookie).
When deployed with :ref:`HTTPS <security-recommendation-ssl>`,
``CsrfViewMiddleware`` will check that the HTTP referer header is set to a

View file

@ -15,7 +15,7 @@ serializer to handle any format (text-based or not).
Serializing data
================
At the highest level, serializing data is a very simple operation::
At the highest level, you can serialize data like this::
from django.core import serializers
data = serializers.serialize("xml", SomeModel.objects.all())
@ -74,7 +74,7 @@ Inherited models
If you have a model that is defined using an :ref:`abstract base class
<abstract-base-classes>`, you don't have to do anything special to serialize
that model. Just call the serializer on the object (or objects) that you want to
that model. Call the serializer on the object (or objects) that you want to
serialize, and the output will be a complete representation of the serialized
object.
@ -105,7 +105,7 @@ serialize the ``Place`` models as well::
Deserializing data
==================
Deserializing data is also a fairly simple operation::
Deserializing data is very similar to serializing it::
for obj in serializers.deserialize("xml", data):
do_something_with(obj)
@ -114,7 +114,7 @@ As you can see, the ``deserialize`` function takes the same format argument as
``serialize``, a string or stream of data, and returns an iterator.
However, here it gets slightly complicated. The objects returned by the
``deserialize`` iterator *aren't* simple Django objects. Instead, they are
``deserialize`` iterator *aren't* regular Django objects. Instead, they are
special ``DeserializedObject`` instances that wrap a created -- but unsaved --
object and any associated relationship data.
@ -136,7 +136,7 @@ something like::
In other words, the usual use is to examine the deserialized objects to make
sure that they are "appropriate" for saving before doing so. Of course, if you
trust your data source you could just save the object and move on.
trust your data source you can instead save the object directly and move on.
The Django object itself can be inspected as ``deserialized_object.object``.
If fields in the serialized data do not exist on a model, a
@ -170,7 +170,7 @@ Identifier Information
XML
---
The basic XML serialization format is quite simple::
The basic XML serialization format looks like this::
<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0">
@ -247,7 +247,7 @@ with three properties: "pk", "model" and "fields". "fields" is again an object
containing each field's name and value as property and property-value
respectively.
Foreign keys just have the PK of the linked object as property value.
Foreign keys have the PK of the linked object as property value.
ManyToMany-relations are serialized for the model that defines them and are
represented as a list of PKs.
@ -313,7 +313,7 @@ again a mapping with the key being name of the field and the value the value::
model: sessions.session
pk: 4b678b301dfd8a4e0dad910de3ae245b
Referential fields are again just represented by the PK or sequence of PKs.
Referential fields are again represented by the PK or sequence of PKs.
.. _topics-serialization-natural-keys:

View file

@ -104,9 +104,8 @@ that's redundant.
Seeing which settings you've changed
------------------------------------
There's an easy way to view which of your settings deviate from the default
settings. The command ``python manage.py diffsettings`` displays differences
between the current settings file and Django's default settings.
The command ``python manage.py diffsettings`` displays differences between the
current settings file and Django's default settings.
For more, see the :djadmin:`diffsettings` documentation.
@ -161,7 +160,7 @@ Creating your own settings
==========================
There's nothing stopping you from creating your own settings, for your own
Django apps. Just follow these guidelines:
Django apps, but follow these guidelines:
* Setting names must be all uppercase.
* Don't reinvent an already-existing setting.
@ -248,7 +247,7 @@ is accessed.
If you set ``DJANGO_SETTINGS_MODULE``, access settings values somehow, *then*
call ``configure()``, Django will raise a ``RuntimeError`` indicating
that settings have already been configured. There is a property just for this
that settings have already been configured. There is a property for this
purpose:
.. attribute: django.conf.settings.configured

View file

@ -138,7 +138,7 @@ Now, our ``my_callback`` function will be called each time a request finishes.
submodule of the application they relate to. Signal receivers are
connected in the :meth:`~django.apps.AppConfig.ready` method of your
application configuration class. If you're using the :func:`receiver`
decorator, simply import the ``signals`` submodule inside
decorator, import the ``signals`` submodule inside
:meth:`~django.apps.AppConfig.ready`.
.. note::

View file

@ -225,7 +225,7 @@ subdirectories as needed.
Do this for your own sanity. Storing all templates in the root level of a
single directory gets messy.
To load a template that's within a subdirectory, just use a slash, like so::
To load a template that's within a subdirectory, use a slash, like so::
get_template('news/story_detail.html')
@ -439,7 +439,7 @@ adds defaults that differ from Jinja2's for a few options:
* Using the result multiple times in each template.
Unless all of these conditions are met, passing a function to the template is
simpler and more in line with the design of Jinja2.
more in line with the design of Jinja2.
The default configuration is purposefully kept to a minimum. If a template is
rendered with a request (e.g. when using :py:func:`~django.shortcuts.render`),
@ -478,10 +478,10 @@ Then you could use the following constructs in Jinja2 templates:
The concepts of tags and filters exist both in the Django template language
and in Jinja2 but they're used differently. Since Jinja2 supports passing
arguments to callables in templates, many features that require a template tag
or filter in Django templates can be achieved simply by calling a function in
Jinja2 templates, as shown in the example above. Jinja2's global namespace
removes the need for template context processors. The Django template language
doesn't have an equivalent of Jinja2 tests.
or filter in Django templates can be achieved by calling a function in Jinja2
templates, as shown in the example above. Jinja2's global namespace removes the
need for template context processors. The Django template language doesn't have
an equivalent of Jinja2 tests.
Custom backends
---------------
@ -667,9 +667,9 @@ Syntax
This is an overview of the Django template language's syntax. For details
see the :doc:`language syntax reference </ref/templates/language>`.
A Django template is simply a text document or a Python string marked-up using
the Django template language. Some constructs are recognized and interpreted
by the template engine. The main ones are variables and tags.
A Django template is a text document or a Python string marked-up using the
Django template language. Some constructs are recognized and interpreted by the
template engine. The main ones are variables and tags.
A template is rendered with a context. Rendering replaces variables with their
values, which are looked up in the context, and executes tags. Everything else
@ -822,8 +822,8 @@ data to be added to the rendering context.
Their main use is to add common data shared by all templates to the context
without repeating code in every view.
Django provides many :ref:`built-in context processors <context-processors>`.
Implementing a custom context processor is as simple as defining a function.
Django provides many :ref:`built-in context processors <context-processors>`,
and you can implement your own additional context processors, too.
.. _Jinja2: http://jinja.pocoo.org/
.. _DEP 182: https://github.com/django/deps/blob/master/final/0182-multiple-template-engines.rst

View file

@ -35,7 +35,7 @@ restricted subset of the test client API:
Example
-------
The following is a simple unit test using the request factory::
The following is a unit test using the request factory::
from django.contrib.auth.models import AnonymousUser, User
from django.test import RequestFactory, TestCase
@ -79,9 +79,8 @@ Projects that support multitenancy or otherwise alter business logic based on
the request's host and use custom host names in tests must include those hosts
in :setting:`ALLOWED_HOSTS`.
The first and simplest option to do so is to add the hosts to your settings
file. For example, the test suite for docs.djangoproject.com includes the
following::
The first option to do so is to add the hosts to your settings file. For
example, the test suite for docs.djangoproject.com includes the following::
from django.test import TestCase

View file

@ -20,8 +20,6 @@ framework and assorted utilities, you can simulate requests, insert test data,
inspect your application's output and generally verify your code is doing what
it should be doing.
The best part is, it's really easy.
The preferred way to write tests in Django is using the :mod:`unittest` module
built in to the Python standard library. This is covered in detail in the
:doc:`overview` document.

View file

@ -661,7 +661,7 @@ More details are in :ref:`explicitly-setting-the-active-language`.
Example
-------
The following is a simple unit test using the test client::
The following is a unit test using the test client::
import unittest
from django.test import Client
@ -702,11 +702,11 @@ Normal Python unit test classes extend a base class of
Hierarchy of Django unit testing classes
Converting a normal :class:`unittest.TestCase` to any of the subclasses is
easy: change the base class of your test from ``unittest.TestCase`` to the
subclass. All of the standard Python unit test functionality will be available,
and it will be augmented with some useful additions as described in each
section below.
You can convert a normal :class:`unittest.TestCase` to any of the subclasses:
change the base class of your test from ``unittest.TestCase`` to the subclass.
All of the standard Python unit test functionality will be available, and it
will be augmented with some useful additions as described in each section
below.
``SimpleTestCase``
------------------
@ -914,9 +914,9 @@ The live server listens on ``localhost`` and binds to port 0 which uses a free
port assigned by the operating system. The server's URL can be accessed with
``self.live_server_url`` during the tests.
To demonstrate how to use ``LiveServerTestCase``, let's write a simple Selenium
test. First of all, you need to install the `selenium package`_ into your
Python path:
To demonstrate how to use ``LiveServerTestCase``, let's write a Selenium test.
First of all, you need to install the `selenium package`_ into your Python
path:
.. console::
@ -1002,10 +1002,10 @@ out the `full reference`_ for more details.
The tricky thing here is that there's really no such thing as a "page load,"
especially in modern Web apps that generate HTML dynamically after the
server generates the initial document. So, simply checking for the presence
of ``<body>`` in the response might not necessarily be appropriate for all
use cases. Please refer to the `Selenium FAQ`_ and
`Selenium documentation`_ for more information.
server generates the initial document. So, checking for the presence of
``<body>`` in the response might not necessarily be appropriate for all use
cases. Please refer to the `Selenium FAQ`_ and `Selenium documentation`_
for more information.
.. _Selenium FAQ: https://web.archive.org/web/20160129132110/http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_WebDriver_fails_to_find_elements_/_Does_not_block_on_page_loa
.. _Selenium documentation: https://www.seleniumhq.org/docs/04_webdriver_advanced.html#explicit-waits
@ -1039,7 +1039,7 @@ This means, instead of instantiating a ``Client`` in each test::
response = client.get('/customer/index/')
self.assertEqual(response.status_code, 200)
...you can just refer to ``self.client``, like so::
...you can refer to ``self.client``, like so::
from django.test import TestCase
@ -1268,9 +1268,9 @@ in the ``with`` block and reset its value to the previous state afterwards.
.. method:: SimpleTestCase.modify_settings()
It can prove unwieldy to redefine settings that contain a list of values. In
practice, adding or removing values is often sufficient. The
:meth:`~django.test.SimpleTestCase.modify_settings` context manager makes it
easy::
practice, adding or removing values is often sufficient. Django provides the
:meth:`~django.test.SimpleTestCase.modify_settings` context manager for easier
settings changes::
from django.test import TestCase
@ -1806,12 +1806,12 @@ Django, such as your machine's mail server, if you're running one.)
.. data:: django.core.mail.outbox
During test running, each outgoing email is saved in
``django.core.mail.outbox``. This is a simple list of all
:class:`~django.core.mail.EmailMessage` instances that have been sent.
The ``outbox`` attribute is a special attribute that is created *only* when
the ``locmem`` email backend is used. It doesn't normally exist as part of the
:mod:`django.core.mail` module and you can't import it directly. The code
below shows how to access this attribute correctly.
``django.core.mail.outbox``. This is a list of all
:class:`~django.core.mail.EmailMessage` instances that have been sent. The
``outbox`` attribute is a special attribute that is created *only* when the
``locmem`` email backend is used. It doesn't normally exist as part of the
:mod:`django.core.mail` module and you can't import it directly. The code below
shows how to access this attribute correctly.
Here's an example test that examines ``django.core.mail.outbox`` for length
and contents::