diff --git a/docs/faq/admin.txt b/docs/faq/admin.txt index f1c6f61ebab..1e96def9a9b 100644 --- a/docs/faq/admin.txt +++ b/docs/faq/admin.txt @@ -78,9 +78,9 @@ modules to the page via the model's class Admin :ref:`js parameter pointing to JavaScript modules that will be included within the admin form via a `` 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) diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index d8b137f6246..56ab59fda25 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -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 `, 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 ` -or just send additional POST data. Formsets `don't yet provide functionality +or send additional POST data. Formsets `don't yet provide functionality `_ for an "edit only" view that prevents creation of new instances. diff --git a/docs/topics/http/file-uploads.txt b/docs/topics/http/file-uploads.txt index 21a6f06853e..534582cbf6e 100644 --- a/docs/topics/http/file-uploads.txt +++ b/docs/topics/http/file-uploads.txt @@ -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 ``
`` 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 ` to the file -field in the model:: +If you are constructing an object manually, you can assign the file object from +:attr:`request.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)] diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt index 757e60c3418..5921ba6625f 100644 --- a/docs/topics/http/sessions.txt +++ b/docs/topics/http/sessions.txt @@ -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: diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt index ed7257d8473..4283d6ebe16 100644 --- a/docs/topics/http/urls.txt +++ b/docs/topics/http/urls.txt @@ -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 `). 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 `. -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 `. 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: diff --git a/docs/topics/http/views.txt b/docs/topics/http/views.txt index baacd233b5f..30761926767 100644 --- a/docs/topics/http/views.txt +++ b/docs/topics/http/views.txt @@ -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 ` -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`:: diff --git a/docs/topics/i18n/formatting.txt b/docs/topics/i18n/formatting.txt index 4a0ce6d3e84..3dbb10f2dc6 100644 --- a/docs/topics/i18n/formatting.txt +++ b/docs/topics/i18n/formatting.txt @@ -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', diff --git a/docs/topics/i18n/index.txt b/docs/topics/i18n/index.txt index 5aad6590335..a85d309bfcc 100644 --- a/docs/topics/i18n/index.txt +++ b/docs/topics/i18n/index.txt @@ -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 =========== diff --git a/docs/topics/i18n/timezones.txt b/docs/topics/i18n/timezones.txt index 86fd8b50621..c8a586a603d 100644 --- a/docs/topics/i18n/timezones.txt +++ b/docs/topics/i18n/timezones.txt @@ -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 `. 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. diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 7432c7b3ffd..f9bb27b6b78 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -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 ` 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 ` 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 `_. 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: diff --git a/docs/topics/install.txt b/docs/topics/install.txt index 3f58f5102ee..c48364bcd7c 100644 --- a/docs/topics/install.txt +++ b/docs/topics/install.txt @@ -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` 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 ` 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/ diff --git a/docs/topics/logging.txt b/docs/topics/logging.txt index ba73234fc1a..7403bece628 100644 --- a/docs/topics/logging.txt +++ b/docs/topics/logging.txt @@ -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 ` 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 diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index 9f3260faa94..d7fa7fdd8a4 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -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 ` 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 `, 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. diff --git a/docs/topics/performance.txt b/docs/topics/performance.txt index 4ccf158241e..70fcff6e482 100644 --- a/docs/topics/performance.txt +++ b/docs/topics/performance.txt @@ -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 diff --git a/docs/topics/security.txt b/docs/topics/security.txt index 549b473988e..862b2de2582 100644 --- a/docs/topics/security.txt +++ b/docs/topics/security.txt @@ -66,10 +66,10 @@ this if you know what you are doing. There are other :ref:`limitations control. :ref:`CSRF protection 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 `, ``CsrfViewMiddleware`` will check that the HTTP referer header is set to a diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt index 11d07bf301a..a9bab470a2b 100644 --- a/docs/topics/serialization.txt +++ b/docs/topics/serialization.txt @@ -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 `, 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:: @@ -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: diff --git a/docs/topics/settings.txt b/docs/topics/settings.txt index def574546fd..7a420b6777a 100644 --- a/docs/topics/settings.txt +++ b/docs/topics/settings.txt @@ -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 diff --git a/docs/topics/signals.txt b/docs/topics/signals.txt index 80a92d7a9c4..817867a4ae9 100644 --- a/docs/topics/signals.txt +++ b/docs/topics/signals.txt @@ -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:: diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index 41c7f587454..8382be82b41 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -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 `. -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 `. -Implementing a custom context processor is as simple as defining a function. +Django provides many :ref:`built-in 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 diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt index 2e4171d376a..48006d7b73c 100644 --- a/docs/topics/testing/advanced.txt +++ b/docs/topics/testing/advanced.txt @@ -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 diff --git a/docs/topics/testing/index.txt b/docs/topics/testing/index.txt index e8cab96277e..65f970b0ae7 100644 --- a/docs/topics/testing/index.txt +++ b/docs/topics/testing/index.txt @@ -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. diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index 31c62383e02..e74e3fb21bb 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -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 ```` 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 + ```` 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::