Refs #34140 -- Corrected rst code-block and various formatting issues in docs.

This commit is contained in:
Joseph Victor Zammit 2023-01-23 21:29:05 +01:00 committed by Mariusz Felisiak
parent c67ea79aa9
commit ba755ca131
57 changed files with 443 additions and 269 deletions

View File

@ -51,7 +51,7 @@ Lookup registration can also be done using a decorator pattern::
@Field.register_lookup
class NotEqualLookup(Lookup):
# ...
...
We can now use ``foo__ne`` for any field ``foo``. You will need to ensure that
this registration happens before you try to create any querysets using it. You

View File

@ -117,7 +117,7 @@ file ``general.log`` (at the project root):
:emphasize-lines: 3-8
LOGGING = {
[...]
# ...
'handlers': {
'file': {
'class': 'logging.FileHandler',
@ -156,7 +156,7 @@ example:
:emphasize-lines: 3-8
LOGGING = {
[...]
# ...
'loggers': {
'': {
'level': 'DEBUG',
@ -195,7 +195,7 @@ formatters named ``verbose`` and ``simple``:
:emphasize-lines: 3-12
LOGGING = {
[...]
# ...
'formatters': {
'verbose': {
'format': '{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}',
@ -226,7 +226,7 @@ dictionary referring to the formatter by name, for example:
'filename': 'general.log',
'formatter': 'verbose',
},
},
}
.. _naming-loggers:
@ -253,7 +253,7 @@ A logger mapping named ``my_app.views`` will capture records from this logger:
:emphasize-lines: 4
LOGGING = {
[...]
# ...
'loggers': {
'my_app.views': {
...
@ -269,7 +269,7 @@ from loggers anywhere within the ``my_app`` namespace (including
:emphasize-lines: 4
LOGGING = {
[...]
# ...
'loggers': {
'my_app': {
...
@ -297,16 +297,16 @@ by a mapping for both ``my_app`` and ``my_app.views``.
To manage this behavior, set the propagation key on the mappings you define::
LOGGING = {
[...]
# ...
'loggers': {
'my_app': {
[...]
# ...
},
'my_app.views': {
[...]
# ...
},
'my_app.views.private': {
[...]
# ...
'propagate': False,
},
},

View File

@ -42,7 +42,7 @@ called ``blog``, which provides the templates ``blog/post.html`` and
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
...
# ...
},
]
@ -77,9 +77,9 @@ First, make sure your template settings are checking inside app directories::
TEMPLATES = [
{
...,
# ...
'APP_DIRS': True,
...
# ...
},
]

View File

@ -199,9 +199,10 @@ Imports
class Example:
# ...
...
* Use convenience imports whenever available. For example, do this::
* Use convenience imports whenever available. For example, do this
::
from django.views import View
@ -236,12 +237,12 @@ View style
Do this::
def my_view(request, foo):
# ...
...
Don't do this::
def my_view(req, foo):
# ...
...
Model style
===========

View File

@ -207,6 +207,7 @@ You can also add a test for the deprecation warning::
msg = 'Expected deprecation message'
with self.assertWarnsMessage(RemovedInDjangoXXWarning, msg):
# invoke deprecated behavior
...
Finally, there are a couple of updates to Django's documentation to make:

View File

@ -163,7 +163,7 @@ this. For a small app like polls, this process isn't too difficult.
1. Add "polls" to your INSTALLED_APPS setting like this::
INSTALLED_APPS = [
...
...,
'polls',
]

View File

@ -115,7 +115,9 @@ and traverses the patterns in order. After finding the match at ``'polls/'``,
it strips off the matching text (``"polls/"``) and sends the remaining text --
``"34/"`` -- to the 'polls.urls' URLconf for further processing. There it
matches ``'<int:question_id>/'``, resulting in a call to the ``detail()`` view
like so::
like so:
.. code-block:: pycon
detail(request=<HttpRequest object>, question_id=34)

View File

@ -171,7 +171,7 @@ tabular way of displaying inline related objects. To use it, change the
:caption: ``polls/admin.py``
class ChoiceInline(admin.TabularInline):
#...
...
With that ``TabularInline`` (instead of ``StackedInline``), the
related objects are displayed in a more compact, table-based format:

View File

@ -76,9 +76,9 @@ Alternatively, :setting:`INSTALLED_APPS` may contain the dotted path to a
configuration class to specify it explicitly::
INSTALLED_APPS = [
...
...,
'polls.apps.PollsAppConfig',
...
...,
]
For application authors

View File

@ -58,9 +58,9 @@ To set the same ``X-Frame-Options`` value for all responses in your site, put
:setting:`MIDDLEWARE`::
MIDDLEWARE = [
...
...,
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
...,
]
This middleware is enabled in the settings file generated by

View File

@ -722,6 +722,8 @@ subclass::
like::
@admin.display(ordering='-first_name')
def colored_first_name(self):
...
The ``ordering`` argument supports query lookups to sort by values on
related models. This example includes an "author first name" column in
@ -752,7 +754,8 @@ subclass::
def full_name(self):
return self.first_name + ' ' + self.last_name
* Elements of ``list_display`` can also be properties::
* Elements of ``list_display`` can also be properties
::
class Person(models.Model):
first_name = models.CharField(max_length=50)
@ -2993,9 +2996,9 @@ returns a site instance.
:caption: ``myproject/settings.py``
INSTALLED_APPS = [
...
# ...
'myproject.apps.MyAdminConfig', # replaces 'django.contrib.admin'
...
# ...
]
.. _multiple-admin-sites:

View File

@ -139,7 +139,7 @@ Geometry Lookups
Geographic queries with geometries take the following general form (assuming
the ``Zipcode`` model used in the :doc:`model-api`):
.. code-block:: pycon
.. code-block:: text
>>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>)
>>> qs = Zipcode.objects.exclude(...)
@ -175,7 +175,7 @@ band index can be specified.
This results in the following general form for lookups involving rasters
(assuming the ``Elevation`` model used in the :doc:`model-api`):
.. code-block:: pycon
.. code-block:: text
>>> qs = Elevation.objects.filter(<field>__<lookup_type>=<parameter>)
>>> qs = Elevation.objects.filter(<field>__<band_index>__<lookup_type>=<parameter>)

View File

@ -1007,15 +1007,15 @@ Coordinate System Objects
>>> proj = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '
>>> wgs84 = SpatialReference(proj) # PROJ string
>>> wgs84 = SpatialReference("""GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0,
AUTHORITY["EPSG","8901"]],
UNIT["degree",0.01745329251994328,
AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4326"]]""") # OGC WKT
... DATUM["WGS_1984",
... SPHEROID["WGS 84",6378137,298.257223563,
... AUTHORITY["EPSG","7030"]],
... AUTHORITY["EPSG","6326"]],
... PRIMEM["Greenwich",0,
... AUTHORITY["EPSG","8901"]],
... UNIT["degree",0.01745329251994328,
... AUTHORITY["EPSG","9122"]],
... AUTHORITY["EPSG","4326"]]""") # OGC WKT
.. method:: __getitem__(target)
@ -1025,7 +1025,7 @@ Coordinate System Objects
.. code-block:: pycon
>>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]')
>>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]'
>>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326
>>> print(srs['GEOGCS'])
WGS 84

View File

@ -702,11 +702,13 @@ Distance Lookups
For an overview on performing distance queries, please refer to
the :ref:`distance queries introduction <distance-queries>`.
Distance lookups take the following form::
Distance lookups take the following form:
<field>__<distance lookup>=(<geometry/raster>, <distance value>[, 'spheroid'])
<field>__<distance lookup>=(<raster>, <band_index>, <distance value>[, 'spheroid'])
<field>__<band_index>__<distance lookup>=(<raster>, <band_index>, <distance value>[, 'spheroid'])
.. code-block:: text
<field>__<distance lookup>=(<geometry/raster>, <distance value>[, "spheroid"])
<field>__<distance lookup>=(<raster>, <band_index>, <distance value>[, "spheroid"])
<field>__<band_index>__<distance lookup>=(<raster>, <band_index>, <distance value>[, "spheroid"])
The value passed into a distance lookup is a tuple; the first two
values are mandatory, and are the geometry to calculate distances to,

View File

@ -822,7 +822,7 @@ Other Properties & Methods
.. code-block:: pycon
>>> if poly_1.area > poly_2.area:
>>> pass
... pass
.. _geos-geometry-collections:

View File

@ -70,9 +70,10 @@ Example
>>> from django.contrib.gis.utils import LayerMapping
>>> from geoapp.models import TestGeo
>>> mapping = {'name' : 'str', # The 'name' model field maps to the 'str' layer field.
'poly' : 'POLYGON', # For geometry fields use OGC name.
} # The mapping is a dictionary
>>> mapping = {
... 'name': 'str', # The 'name' model field maps to the 'str' layer field.
... 'poly': 'POLYGON', # For geometry fields use OGC name.
... } # The mapping is a dictionary
>>> lm = LayerMapping(TestGeo, 'test_poly.shp', mapping)
>>> lm.save(verbose=True) # Save the layermap, imports the data.
Saved: Name: 1

View File

@ -575,7 +575,6 @@ Here's a sample configuration which uses a MySQL option file::
}
}
.. code-block:: ini
# my.cnf
@ -1017,14 +1016,14 @@ using RAC or pluggable databases without ``tnsnames.ora``, for example.
Example of an Easy Connect string::
'NAME': 'localhost:1521/orclpdb1',
'NAME': 'localhost:1521/orclpdb1'
Example of a full DSN string::
'NAME': (
'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))'
'(CONNECT_DATA=(SERVICE_NAME=orclpdb1)))'
),
)
Threaded option
---------------
@ -1035,7 +1034,7 @@ the ``threaded`` option of your Oracle database configuration to ``True``::
'OPTIONS': {
'threaded': True,
},
}
Failure to do this may result in crashes and other odd behavior.
@ -1051,7 +1050,7 @@ The ``RETURNING INTO`` clause can be disabled by setting the
'OPTIONS': {
'use_returning_into': False,
},
}
In this case, the Oracle backend will use a separate ``SELECT`` query to
retrieve ``AutoField`` values.
@ -1160,7 +1159,7 @@ file::
DATABASES = {
'default': {
'ENGINE': 'mydbengine',
...
# ...
},
}

View File

@ -1429,7 +1429,7 @@ need to bind the file data containing the mugshot image:
... 'message': 'Hi there',
... 'sender': 'foo@example.com',
... 'cc_myself': True}
>>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', <file data>)}
>>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', b"file data")}
>>> f = ContactFormWithMugshot(data, file_data)
In practice, you will usually specify ``request.FILES`` as the source

View File

@ -746,7 +746,7 @@ For each field, we describe the default widget used if you don't specify
>>> from django.core.files.uploadedfile import SimpleUploadedFile
>>> class ImageForm(forms.Form):
... img = forms.ImageField()
>>> file_data = {'img': SimpleUploadedFile('test.png', <file data>)}
>>> file_data = {'img': SimpleUploadedFile('test.png', b"file data")}
>>> form = ImageForm({}, file_data)
# Pillow closes the underlying file descriptor.
>>> form.is_valid()

View File

@ -228,17 +228,21 @@ logger, but only to the ``django.security`` logger.
To silence a particular type of ``SuspiciousOperation``, you can override that
specific logger following this example::
'handlers': {
'null': {
'class': 'logging.NullHandler',
LOGGING = {
# ...
'handlers': {
'null': {
'class': 'logging.NullHandler',
},
},
},
'loggers': {
'django.security.DisallowedHost': {
'handlers': ['null'],
'propagate': False,
'loggers': {
'django.security.DisallowedHost': {
'handlers': ['null'],
'propagate': False,
},
},
},
# ...
}
Other ``django.security`` loggers not based on ``SuspiciousOperation`` are:
@ -286,7 +290,7 @@ Python logging module <python:logging.handlers>`.
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
},
},
}
Be aware of the :ref:`security implications of logging
<logging-security-implications>` when using the ``AdminEmailHandler``.
@ -301,7 +305,7 @@ Python logging module <python:logging.handlers>`.
'class': 'django.utils.log.AdminEmailHandler',
'email_backend': 'django.core.mail.backends.filebased.EmailBackend',
},
},
}
By default, an instance of the email backend specified in
:setting:`EMAIL_BACKEND` will be used.
@ -318,7 +322,7 @@ Python logging module <python:logging.handlers>`.
'include_html': True,
'reporter_class': 'somepackage.error_reporter.CustomErrorReporter',
},
},
}
.. method:: send_mail(subject, message, *args, **kwargs)
@ -354,19 +358,23 @@ logging module.
and then add it to your logging config::
'filters': {
'skip_unreadable_posts': {
'()': 'django.utils.log.CallbackFilter',
'callback': skip_unreadable_post,
LOGGING = {
# ...
'filters': {
'skip_unreadable_posts': {
'()': 'django.utils.log.CallbackFilter',
'callback': skip_unreadable_post,
},
},
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['skip_unreadable_posts'],
'class': 'django.utils.log.AdminEmailHandler',
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['skip_unreadable_posts'],
'class': 'django.utils.log.AdminEmailHandler',
},
},
},
# ...
}
.. class:: RequireDebugFalse()
@ -376,18 +384,22 @@ logging module.
configuration to ensure that the :class:`AdminEmailHandler` only sends
error emails to admins when :setting:`DEBUG` is ``False``::
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
LOGGING = {
# ...
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
},
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
},
},
},
# ...
}
.. class:: RequireDebugTrue()

View File

@ -1885,7 +1885,9 @@ more frequently.
.. class:: PercentRank(*expressions, **extra)
Computes the relative rank of the rows in the frame clause. This computation is
equivalent to evaluating::
equivalent to evaluating:
.. code-block:: text
(rank - 1) / (total rows - 1)

View File

@ -21,20 +21,20 @@ constants, variables, and even other expressions.
Some examples
=============
.. code-block:: python
.. code-block:: pycon
from django.db.models import Count, F, Value
from django.db.models.functions import Length, Upper
from django.db.models.lookups import GreaterThan
>>> from django.db.models import Count, F, Value
>>> from django.db.models.functions import Length, Upper
>>> from django.db.models.lookups import GreaterThan
# Find companies that have more employees than chairs.
Company.objects.filter(num_employees__gt=F('num_chairs'))
>>> Company.objects.filter(num_employees__gt=F('num_chairs'))
# Find companies that have at least twice as many employees
# as chairs. Both the querysets below are equivalent.
Company.objects.filter(num_employees__gt=F('num_chairs') * 2)
Company.objects.filter(
num_employees__gt=F('num_chairs') + F('num_chairs'))
>>> Company.objects.filter(num_employees__gt=F('num_chairs') * 2)
>>> Company.objects.filter(
... num_employees__gt=F('num_chairs') + F('num_chairs'))
# How many chairs are needed for each company to seat all employees?
>>> company = Company.objects.filter(
@ -813,12 +813,12 @@ the same studio in the same genre and release year:
>>> from django.db.models import Avg, F, Window
>>> Movie.objects.annotate(
>>> avg_rating=Window(
>>> expression=Avg('rating'),
>>> partition_by=[F('studio'), F('genre')],
>>> order_by='released__year',
>>> ),
>>> )
... avg_rating=Window(
... expression=Avg('rating'),
... partition_by=[F('studio'), F('genre')],
... order_by='released__year',
... ),
... )
This allows you to check if a movie is rated better or worse than its peers.
@ -833,20 +833,20 @@ to reduce repetition:
>>> from django.db.models import Avg, F, Max, Min, Window
>>> window = {
>>> 'partition_by': [F('studio'), F('genre')],
>>> 'order_by': 'released__year',
>>> }
... 'partition_by': [F('studio'), F('genre')],
... 'order_by': 'released__year',
... }
>>> Movie.objects.annotate(
>>> avg_rating=Window(
>>> expression=Avg('rating'), **window,
>>> ),
>>> best=Window(
>>> expression=Max('rating'), **window,
>>> ),
>>> worst=Window(
>>> expression=Min('rating'), **window,
>>> ),
>>> )
... avg_rating=Window(
... expression=Avg('rating'), **window,
... ),
... best=Window(
... expression=Max('rating'), **window,
... ),
... worst=Window(
... expression=Min('rating'), **window,
... ),
... )
Filtering against window functions is supported as long as lookups are not
disjunctive (not using ``OR`` or ``XOR`` as a connector) and against a queryset
@ -860,13 +860,13 @@ from groups to be included:
.. code-block:: pycon
>>> qs = Movie.objects.annotate(
>>> category_rank=Window(
>>> Rank(), partition_by='category', order_by='-rating'
>>> ),
>>> scenes_count=Count('actors'),
>>> ).filter(
>>> Q(category_rank__lte=3) | Q(title__contains='Batman')
>>> )
... category_rank=Window(
... Rank(), partition_by='category', order_by='-rating'
... ),
... scenes_count=Count('actors'),
... ).filter(
... Q(category_rank__lte=3) | Q(title__contains='Batman')
... )
>>> list(qs)
NotImplementedError: Heterogeneous disjunctive predicates against window functions
are not implemented when performing conditional aggregation.
@ -945,13 +945,13 @@ with the average rating of a movie's two prior and two following peers:
>>> from django.db.models import Avg, F, RowRange, Window
>>> Movie.objects.annotate(
>>> avg_rating=Window(
>>> expression=Avg('rating'),
>>> partition_by=[F('studio'), F('genre')],
>>> order_by='released__year',
>>> frame=RowRange(start=-2, end=2),
>>> ),
>>> )
... avg_rating=Window(
... expression=Avg('rating'),
... partition_by=[F('studio'), F('genre')],
... order_by='released__year',
... frame=RowRange(start=-2, end=2),
... ),
... )
If the database supports it, you can specify the start and end points based on
values of an expression in the partition. If the ``released`` field of the
@ -963,13 +963,13 @@ released between twelve months before and twelve months after the each movie:
>>> from django.db.models import Avg, F, ValueRange, Window
>>> Movie.objects.annotate(
>>> avg_rating=Window(
>>> expression=Avg('rating'),
>>> partition_by=[F('studio'), F('genre')],
>>> order_by='released__year',
>>> frame=ValueRange(start=-12, end=12),
>>> ),
>>> )
... avg_rating=Window(
... expression=Avg('rating'),
... partition_by=[F('studio'), F('genre')],
... order_by='released__year',
... frame=ValueRange(start=-12, end=12),
... ),
... )
.. currentmodule:: django.db.models

View File

@ -24,7 +24,8 @@ Related objects reference
In the above example, the methods below will be available on
the manager ``blog.entry_set``.
* Both sides of a :class:`~django.db.models.ManyToManyField` relation::
* Both sides of a :class:`~django.db.models.ManyToManyField` relation
::
class Topping(models.Model):
# ...

View File

@ -499,7 +499,7 @@ Use of both ``and`` and ``or`` clauses within the same tag is allowed, with
will be interpreted like:
.. code-block:: python
.. code-block:: pycon
if (athlete_list and coach_list) or cheerleader_list
@ -1118,14 +1118,16 @@ Example usage:
This example would return this HTML::
<h1>José Mourinho</h1>
<p class="odd">Thibaut Courtois</p>
<p class="even">John Terry</p>
<p class="odd">Eden Hazard</p>
.. code-block:: html
<h1>Carlo Ancelotti</h1>
<p class="odd">Manuel Neuer</p>
<p class="even">Thomas Müller</p>
<h1>Gareth</h1>
<p class="odd">Harry</p>
<p class="even">John</p>
<p class="odd">Nick</p>
<h1>John</h1>
<p class="odd">Andrea</p>
<p class="even">Melissa</p>
Notice how the first block ends with ``class="odd"`` and the new one starts
with ``class="odd"``. Without the ``{% resetcycle %}`` tag, the second block
@ -1264,6 +1266,8 @@ such as this:
...then, in a template, you can create a link to this view like this::
.. code-block:: html+django
{% url 'app-views-client' client.id %}
The template tag will output the string ``/clients/client/123/``.

View File

@ -539,14 +539,14 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004
from django.utils.functional import keep_lazy, keep_lazy_text
def fancy_utility_function(s, ...):
def fancy_utility_function(s, *args, **kwargs):
# Do some conversion on string 's'
...
fancy_utility_function = keep_lazy(str)(fancy_utility_function)
# Or more succinctly:
@keep_lazy(str)
def fancy_utility_function(s, ...):
def fancy_utility_function(s, *args, **kwargs):
...
The ``keep_lazy()`` decorator takes a number of extra arguments (``*args``)
@ -571,12 +571,12 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004
# Our previous example was:
@keep_lazy(str)
def fancy_utility_function(s, ...):
def fancy_utility_function(s, *args, **kwargs):
...
# Which can be rewritten as:
@keep_lazy_text
def fancy_utility_function(s, ...):
def fancy_utility_function(s, *args, **kwargs):
...
``django.utils.html``

View File

@ -36,12 +36,16 @@ differences as a result of this change.
However, **users on 64-bit platforms may experience some problems** using the
``reset`` management command. Prior to this change, 64-bit platforms
would generate a 64-bit, 16 character digest in the constraint name; for
example::
example:
.. code-block:: sql
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_5e8f10c132091d1e FOREIGN KEY ...
Following this change, all platforms, regardless of word size, will generate a
32-bit, 8 character digest in the constraint name; for example::
32-bit, 8 character digest in the constraint name; for example:
.. code-block:: sql
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_32091d1e FOREIGN KEY ...

View File

@ -545,14 +545,18 @@ Database backend API
``select_related()`` prohibits non-relational fields for nested relations
-------------------------------------------------------------------------
Django 1.8 added validation for non-relational fields in ``select_related()``::
Django 1.8 added validation for non-relational fields in ``select_related()``:
.. code-block:: pycon
>>> Book.objects.select_related('title')
Traceback (most recent call last):
...
FieldError: Non-relational field given in select_related: 'title'
But it didn't prohibit nested non-relation fields as it does now::
But it didn't prohibit nested non-relation fields as it does now:
.. code-block:: pycon
>>> Book.objects.select_related('author__name')
Traceback (most recent call last):
@ -620,6 +624,8 @@ disable Django's logging configuration or override it with your own, you'll
need to add the appropriate logging configuration if you want to see that
output::
LOGGING = {
# ...
'formatters': {
'django.server': {
'()': 'django.utils.log.ServerFormatter',
@ -639,7 +645,8 @@ output::
'level': 'INFO',
'propagate': False,
}
}
},
}
``auth.CustomUser`` and ``auth.ExtensionUser`` test models were removed
-----------------------------------------------------------------------
@ -725,7 +732,7 @@ custom lookup for it. For example::
class MyFieldExact(Exact):
def get_prep_lookup(self):
# do_custom_stuff_for_myfield
....
...
MyField.register_lookup(MyFieldExact)
@ -931,13 +938,17 @@ Features deprecated in 1.10
Direct assignment to a reverse foreign key or many-to-many relation
-------------------------------------------------------------------
Instead of assigning related objects using direct assignment::
Instead of assigning related objects using direct assignment:
.. code-block:: pycon
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
Use the :meth:`~django.db.models.fields.related.RelatedManager.set` method
added in Django 1.9::
added in Django 1.9:
.. code-block:: pycon
>>> e.related_set.set([obj1, obj2, obj3])
@ -1022,12 +1033,16 @@ Assume the following models::
In older versions, :attr:`~django.db.models.Options.default_related_name`
couldn't be used as a query lookup. This is fixed and support for the old
lookup name is deprecated. For example, since ``default_related_name`` is set
in model ``Bar``, instead of using the model name ``bar`` as the lookup::
in model ``Bar``, instead of using the model name ``bar`` as the lookup:
.. code-block:: pycon
>>> bar = Bar.objects.get(pk=1)
>>> Foo.objects.get(bar=bar)
use the default_related_name ``bars``::
use the default_related_name ``bars``:
.. code-block:: pycon
>>> Foo.objects.get(bars=bar)

View File

@ -453,42 +453,42 @@ several functions to support conversion of Python values into
database-compatible values. A custom field might look something like::
class CustomModelField(models.Field):
# ...
...
def db_type(self):
# ...
...
def get_db_prep_save(self, value):
# ...
...
def get_db_prep_value(self, value):
# ...
...
def get_db_prep_lookup(self, lookup_type, value):
# ...
...
In 1.2, these three methods have undergone a change in prototype, and
two extra methods have been introduced::
class CustomModelField(models.Field):
# ...
...
def db_type(self, connection):
# ...
...
def get_prep_value(self, value):
# ...
...
def get_prep_lookup(self, lookup_type, value):
# ...
...
def get_db_prep_save(self, value, connection):
# ...
...
def get_db_prep_value(self, value, connection, prepared=False):
# ...
...
def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
# ...
...
These changes are required to support multiple databases --
``db_type`` and ``get_db_prep_*`` can no longer make any assumptions
@ -537,21 +537,29 @@ You may also need to update your templates if you were relying on the
implementation of Django's template tags *not* being thread safe. The
:ttag:`cycle` tag is the most likely to be affected in this way,
especially when used in conjunction with the :ttag:`include` tag.
Consider the following template fragment::
Consider the following template fragment:
.. code-block:: html+django
{% for object in object_list %}
{% include "subtemplate.html" %}
{% endfor %}
with a ``subtemplate.html`` that reads::
with a ``subtemplate.html`` that reads:
.. code-block:: html+django
{% cycle 'even' 'odd' %}
Using the non-thread-safe, pre-Django 1.2 renderer, this would output::
Using the non-thread-safe, pre-Django 1.2 renderer, this would output:
.. code-block:: text
even odd even odd ...
Using the thread-safe Django 1.2 renderer, you will instead get::
Using the thread-safe Django 1.2 renderer, you will instead get:
.. code-block:: text
even even even even ...
@ -1133,14 +1141,18 @@ is using a supported spatial database backend.
differs across spatial databases, the ``SpatialRefSys`` and
``GeometryColumns`` models can no longer be associated with
the ``gis`` application name. Thus, no models will be returned
when using the ``get_models`` method in the following example::
when using the ``get_models`` method in the following example:
.. code-block:: pycon
>>> from django.db.models import get_app, get_models
>>> get_models(get_app('gis'))
[]
To get the correct ``SpatialRefSys`` and ``GeometryColumns``
for your spatial database use the methods provided by the spatial backend::
for your spatial database use the methods provided by the spatial backend:
.. code-block:: pycon
>>> from django.db import connections
>>> SpatialRefSys = connections['my_spatialite'].ops.spatial_ref_sys()

View File

@ -20,7 +20,9 @@ as was reported to us recently. The Host header parsing in Django 1.3.3 and
Django 1.4.1 -- specifically, ``django.http.HttpRequest.get_host()`` -- was
incorrectly handling username/password information in the header. Thus, for
example, the following Host header would be accepted by Django when running on
``validsite.com``::
``validsite.com``:
.. code-block:: text
Host: validsite.com:random@evilsite.com

View File

@ -141,7 +141,7 @@ Users of Python 2.5 and above may now use transaction management functions as
context managers. For example::
with transaction.autocommit():
# ...
...
Configurable delete-cascade
---------------------------
@ -419,7 +419,9 @@ If you have an existing project that is using the database session
backend, you don't have to do anything to accommodate this change.
However, you may get a significant performance boost if you manually
add the new index to the session table. The SQL that will add the
index can be found by running the ``sqlindexes`` admin command::
index can be found by running the ``sqlindexes`` admin command:
.. code-block:: shell
python manage.py sqlindexes sessions
@ -476,14 +478,18 @@ passed empty dictionary. This was inconsistent with behavior in other parts of
the framework. Starting with 1.3 if you pass in empty dictionary the
``FormSet`` will raise a ``ValidationError``.
For example with a ``FormSet``::
For example with a ``FormSet``:
.. code-block:: pycon
>>> class ArticleForm(Form):
... title = CharField()
... pub_date = DateField()
>>> ArticleFormSet = formset_factory(ArticleForm)
the following code will raise a ``ValidationError``::
the following code will raise a ``ValidationError``:
.. code-block:: pycon
>>> ArticleFormSet({})
Traceback (most recent call last):
@ -491,7 +497,9 @@ the following code will raise a ``ValidationError``::
ValidationError: [u'ManagementForm data is missing or has been tampered with']
if you need to instantiate an empty ``FormSet``, don't pass in the data or use
``None``::
``None``:
.. code-block:: pycon
>>> formset = ArticleFormSet()
>>> formset = ArticleFormSet(data=None)
@ -502,7 +510,9 @@ Callables in templates
Previously, a callable in a template would only be called automatically as part
of the variable resolution process if it was retrieved via attribute
lookup. This was an inconsistency that could result in confusing and unhelpful
behavior::
behavior:
.. code-block:: pycon
>>> Template("{{ user.get_full_name }}").render(Context({'user': user}))
u'Joe Bloggs'
@ -720,12 +730,16 @@ Changes to ``url`` and ``ssi``
------------------------------
Most template tags will allow you to pass in either constants or
variables as arguments -- for example::
variables as arguments -- for example:
.. code-block:: html+django
{% extends "base.html" %}
allows you to specify a base template as a constant, but if you have a
context variable ``templ`` that contains the value ``base.html``::
context variable ``templ`` that contains the value ``base.html``:
.. code-block:: html+django
{% extends templ %}
@ -741,11 +755,15 @@ accident. Django 1.3 adds a new template library -- ``future`` -- that
provides alternate implementations of the ``url`` and ``ssi``
template tags. This ``future`` library implement behavior that makes
the handling of the first argument consistent with the handling of all
other variables. So, an existing template that contains::
other variables. So, an existing template that contains:
.. code-block:: html+django
{% url sample %}
should be replaced with::
should be replaced with:
.. code-block:: html+django
{% load url from future %}
{% url 'sample' %}
@ -840,7 +858,9 @@ Rationale for this decision:
generate spurious error messages when the project directory is added
to the Python path (``manage.py runserver`` does this) and then it
clashes with the equally named standard library module, this is a
typical warning message::
typical warning message:
.. code-block:: pytb
/usr/lib/python2.6/gettext.py:49: ImportWarning: Not importing directory '/path/to/project/locale': missing __init__.py.
import locale, copy, os, re, struct, sys

View File

@ -20,7 +20,9 @@ as was reported to us recently. The Host header parsing in Django 1.3.3 and
Django 1.4.1 -- specifically, ``django.http.HttpRequest.get_host()`` -- was
incorrectly handling username/password information in the header. Thus, for
example, the following Host header would be accepted by Django when running on
``validsite.com``::
``validsite.com``:
.. code-block:: text
Host: validsite.com:random@evilsite.com

View File

@ -152,7 +152,9 @@ using the project name prefix (e.g. ``myproject.settings``, ``ROOT_URLCONF =
directory up, so it is outside the project package rather than adjacent to
``settings.py`` and ``urls.py``.
For instance, with the following layout::
For instance, with the following layout:
.. code-block:: text
manage.py
mysite/
@ -168,7 +170,9 @@ but not ``settings``, ``urls``, or ``myapp`` as top-level modules.
Anything imported as a top-level module can be placed adjacent to the new
``manage.py``. For instance, to decouple ``myapp`` from the project module and
import it as just ``myapp``, place it outside the ``mysite/`` directory::
import it as just ``myapp``, place it outside the ``mysite/`` directory:
.. code-block:: text
manage.py
myapp/
@ -191,12 +195,16 @@ now have a ``--template`` option for specifying a path or URL to a custom app
or project template.
For example, Django will use the ``/path/to/my_project_template`` directory
when you run the following command::
when you run the following command:
.. code-block:: shell
django-admin.py startproject --template=/path/to/my_project_template myproject
You can also now provide a destination directory as the second
argument to both :djadmin:`startapp` and :djadmin:`startproject`::
argument to both :djadmin:`startapp` and :djadmin:`startproject`:
.. code-block:: shell
django-admin.py startapp myapp /path/to/new/app
django-admin.py startproject myproject /path/to/new/project
@ -1136,7 +1144,9 @@ Development Server Multithreading
The development server is now is multithreaded by default. Use the
:option:`runserver --nothreading` option to disable the use of threading in the
development server::
development server:
.. code-block:: shell
django-admin.py runserver --nothreading
@ -1199,18 +1209,21 @@ To increase the flexibility of error logging for requests, the
separate filter attached to :class:`django.utils.log.AdminEmailHandler` to
prevent admin error emails in ``DEBUG`` mode::
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
LOGGING = {
# ...
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
}
If your project was created prior to this change, your :setting:`LOGGING`
setting will not include this new filter. In order to maintain

View File

@ -155,7 +155,9 @@ Caching of related model instances
----------------------------------
When traversing relations, the ORM will avoid re-fetching objects that were
previously loaded. For example, with the tutorial's models::
previously loaded. For example, with the tutorial's models:
.. code-block:: pycon
>>> first_poll = Poll.objects.all()[0]
>>> first_choice = first_poll.choice_set.all()[0]
@ -403,7 +405,9 @@ Context in year and month archive class-based views
provide a ``date_list`` sorted in ascending order in the context, like their
function-based predecessors, but it actually was in descending order. In 1.5,
the documented order was restored. You may want to add (or remove) the
``reversed`` keyword when you're iterating on ``date_list`` in a template::
``reversed`` keyword when you're iterating on ``date_list`` in a template:
.. code-block:: html+django
{% for date in date_list reversed %}

View File

@ -463,11 +463,14 @@ explicitly import the User model in your test module::
@override_settings(AUTH_USER_MODEL='auth.CustomUser')
class CustomUserFeatureTests(TestCase):
def test_something(self):
# Test code here ...
# Test code here
...
This import forces the custom user model to be registered. Without this import,
the test will be unable to swap in the custom user model, and you will get an
error reporting::
error reporting:
.. code-block:: pytb
ImproperlyConfigured: AUTH_USER_MODEL refers to model 'auth.CustomUser' that has not been installed
@ -1010,11 +1013,15 @@ Django 1.6 starts a process to correct this inconsistency. The ``future``
template library provides alternate implementations of :ttag:`cycle` and
:ttag:`firstof` that autoescape their inputs. If you're using these tags,
you're encouraged to include the following line at the top of your templates to
enable the new behavior::
enable the new behavior:
.. code-block:: html+django
{% load cycle from future %}
or::
or:
.. code-block:: html+django
{% load firstof from future %}

View File

@ -1009,7 +1009,9 @@ Standalone scripts
If you're using Django in a plain Python script — rather than a management
command — and you rely on the :envvar:`DJANGO_SETTINGS_MODULE` environment
variable, you must now explicitly initialize Django at the beginning of your
script with::
script with:
.. code-block:: pycon
>>> import django
>>> django.setup()
@ -1134,13 +1136,13 @@ method::
# Old pattern:
try:
# ...
...
except ValidationError as e:
self._errors = e.update_error_dict(self._errors)
# New pattern:
try:
# ...
...
except ValidationError as e:
self.add_error(None, e)
@ -1150,7 +1152,7 @@ wasn't available before Django 1.7, but you can use the following
workaround to convert any ``list`` into ``ErrorList``::
try:
# ...
...
except ValidationError as e:
self._errors = e.update_error_dict(self._errors)
@ -1195,8 +1197,8 @@ manager will *not* be reset. This was necessary to resolve an inconsistency in
the way routing information cascaded over joins. See :ticket:`13724` for more
details.
pytz may be required
--------------------
``pytz`` may be required
------------------------
If your project handles datetimes before 1970 or after 2037 and Django raises
a :exc:`ValueError` when encountering them, you will have to install pytz_. You

View File

@ -696,7 +696,9 @@ Assigning unsaved objects to relations raises an error
.. note::
To more easily allow in-memory usage of models, this change was reverted in
Django 1.8.4 and replaced with a check during ``model.save()``. For example::
Django 1.8.4 and replaced with a check during ``model.save()``. For example:
.. code-block:: pycon
>>> book = Book.objects.create(name="Django")
>>> book.author = Author(name="John")
@ -713,7 +715,9 @@ Assigning unsaved objects to a :class:`~django.db.models.ForeignKey`,
:class:`~django.db.models.OneToOneField` now raises a :exc:`ValueError`.
Previously, the assignment of an unsaved object would be silently ignored.
For example::
For example:
.. code-block:: pycon
>>> book = Book.objects.create(name="Django")
>>> book.author = Author(name="John")
@ -724,7 +728,9 @@ For example::
>>> book.author
>>>
Now, an error will be raised to prevent data loss::
Now, an error will be raised to prevent data loss:
.. code-block:: pycon
>>> book.author = Author(name="john")
Traceback (most recent call last):
@ -790,7 +796,9 @@ Querying for model lookups now checks if the object passed is of correct type
and raises a :exc:`ValueError` if not. Previously, Django didn't care if the
object was of correct type; it just used the object's related field attribute
(e.g. ``id``) for the lookup. Now, an error is raised to prevent incorrect
lookups::
lookups:
.. code-block:: pycon
>>> book = Book.objects.create(name="Django")
>>> book = Book.objects.filter(author=book)
@ -802,14 +810,18 @@ lookups::
--------------------------------------------
``select_related()`` now validates that the given fields actually exist.
Previously, nonexistent fields were silently ignored. Now, an error is raised::
Previously, nonexistent fields were silently ignored. Now, an error is raised:
.. code-block:: pycon
>>> book = Book.objects.select_related('nonexistent_field')
Traceback (most recent call last):
...
FieldError: Invalid field name(s) given in select_related: 'nonexistent_field'
The validation also makes sure that the given field is relational::
The validation also makes sure that the given field is relational:
.. code-block:: pycon
>>> book = Book.objects.select_related('name')
Traceback (most recent call last):
@ -966,7 +978,9 @@ returns the relationship as ``django.db.models.fields.related.ManyToOneRel``
is set to the target of the relationship instead of the source. The source
model is accessible on the ``related_model`` attribute instead.
Consider this example from the tutorial in Django 1.8::
Consider this example from the tutorial in Django 1.8:
.. code-block:: pycon
>>> p = Poll.objects.get(pk=1)
>>> p._meta.get_all_related_objects()
@ -976,7 +990,9 @@ Consider this example from the tutorial in Django 1.8::
>>> p._meta.get_all_related_objects()[0].related_model
<class 'polls.models.Choice'>
and compare it to the behavior on older versions::
and compare it to the behavior on older versions:
.. code-block:: pycon
>>> p._meta.get_all_related_objects()
[<RelatedObject: polls:choice related to poll>]

View File

@ -1018,7 +1018,9 @@ to 2.1.4. jQuery 2.x has the same API as jQuery 1.x, but does not support
Internet Explorer 6, 7, or 8, allowing for better performance and a smaller
file size. If you need to support IE8 and must also use the latest version of
Django, you can override the admin's copy of jQuery with your own by creating
a Django application with this structure::
a Django application with this structure:
.. code-block:: text
app/static/admin/js/vendor/
jquery.js
@ -1029,7 +1031,9 @@ a Django application with this structure::
``SyntaxError`` when installing Django setuptools 5.5.x
-------------------------------------------------------
When installing Django 1.9 or 1.9.1 with setuptools 5.5.x, you'll see::
When installing Django 1.9 or 1.9.1 with setuptools 5.5.x, you'll see:
.. code-block:: shell
Compiling django/conf/app_template/apps.py ...
File "django/conf/app_template/apps.py", line 4
@ -1313,7 +1317,9 @@ the included URLconf sets an application namespace.
``current_app`` parameter to ``contrib.auth`` views
---------------------------------------------------
All views in ``django.contrib.auth.views`` have the following structure::
All views in ``django.contrib.auth.views`` have the following structure:
.. code-block:: text
def view(request, ..., current_app=None, ...):

View File

@ -454,7 +454,9 @@ If you wish to keep this restriction in the admin when editing users, set
Calling ``QuerySet.reverse()`` or ``last()`` on a sliced queryset leads to
unexpected results due to the slice being applied after reordering. This is
now prohibited, e.g.::
now prohibited, e.g.:
.. code-block:: pycon
>>> Model.objects.all()[:2].reverse()
Traceback (most recent call last):

View File

@ -392,7 +392,9 @@ existing row will result in an ``IntegrityError``.
In order to update an existing model for a specific primary key value, use the
:meth:`~django.db.models.query.QuerySet.update_or_create` method or
``QuerySet.filter(pk=…).update(…)`` instead. For example::
``QuerySet.filter(pk=…).update(…)`` instead. For example:
.. code-block:: pycon
>>> MyModel.objects.update_or_create(pk=existing_pk, defaults={'name': 'new name'})
>>> MyModel.objects.filter(pk=existing_pk).update(name='new name')

View File

@ -705,8 +705,8 @@ Miscellaneous
``SimpleTestCase.assertFormError()`` and ``assertFormsetError()`` is
deprecated. Use::
assertFormError(response.context['form_name'], )
assertFormsetError(response.context['formset_name'], )
assertFormError(response.context['form_name'], ...)
assertFormsetError(response.context['formset_name'], ...)
or pass the form/formset object directly instead.

View File

@ -91,11 +91,11 @@ Detailed notes can be found in :ref:`async-queries`, but in short:
Django also supports some asynchronous model methods that use the database::
async def make_book(...):
async def make_book(*args, **kwargs):
book = Book(...)
await book.asave(using="secondary")
async def make_book_with_tags(tags, ...):
async def make_book_with_tags(tags, *args, **kwargs):
book = await Book.objects.acreate(...)
await book.tags.aset(tags)
@ -227,13 +227,13 @@ as either a direct wrapper or a decorator::
from asgiref.sync import async_to_sync
async def get_data(...):
async def get_data():
...
sync_get_data = async_to_sync(get_data)
@async_to_sync
async def get_other_data(...):
async def get_other_data():
...
The async function is run in the event loop for the current thread, if one is
@ -264,7 +264,7 @@ as either a direct wrapper or a decorator::
async_function = sync_to_async(sensitive_sync_function, thread_sensitive=True)
@sync_to_async
def sync_function(...):
def sync_function():
...
Threadlocals and contextvars values are preserved across the boundary in both

View File

@ -134,8 +134,10 @@ Authenticating users
user = authenticate(username='john', password='secret')
if user is not None:
# A backend authenticated the credentials
...
else:
# No backend authenticated the credentials
...
``request`` is an optional :class:`~django.http.HttpRequest` which is
passed on the ``authenticate()`` method of the authentication backends.
@ -950,7 +952,9 @@ in your own URLconf, for example::
path('accounts/', include('django.contrib.auth.urls')),
]
This will include the following URL patterns::
This will include the following URL patterns:
.. code-block:: text
accounts/login/ [name='login']
accounts/logout/ [name='logout']

View File

@ -24,7 +24,9 @@ How Django stores passwords
Django provides a flexible password storage system and uses PBKDF2 by default.
The :attr:`~django.contrib.auth.models.User.password` attribute of a
:class:`~django.contrib.auth.models.User` object is a string in this format::
:class:`~django.contrib.auth.models.User` object is a string in this format:
.. code-block:: text
<algorithm>$<iterations>$<salt>$<hash>
@ -215,7 +217,8 @@ parameter (use the ``rounds`` parameter when subclassing a bcrypt hasher). For
example, to increase the number of iterations used by the default PBKDF2
algorithm:
#. Create a subclass of ``django.contrib.auth.hashers.PBKDF2PasswordHasher``::
#. Create a subclass of ``django.contrib.auth.hashers.PBKDF2PasswordHasher``
::
from django.contrib.auth.hashers import PBKDF2PasswordHasher

View File

@ -18,7 +18,9 @@ That's where caching comes in.
To cache something is to save the result of an expensive calculation so that
you don't have to perform the calculation next time. Here's some pseudocode
explaining how this would work for a dynamically generated web page::
explaining how this would work for a dynamically generated web page:
.. code-block:: text
given a URL, try finding that page in the cache
if the page is in the cache:

View File

@ -150,7 +150,7 @@ this would lead to incorrect behavior.
@etag(etag_func)
@last_modified(last_modified_func)
def my_view(request):
# ...
...
# End of bad code.

View File

@ -74,9 +74,9 @@ p2 doesn't have an associated restaurant:
>>> from django.core.exceptions import ObjectDoesNotExist
>>> try:
>>> p2.restaurant
>>> except ObjectDoesNotExist:
>>> print("There is no restaurant here.")
... p2.restaurant
... except ObjectDoesNotExist:
... print("There is no restaurant here.")
There is no restaurant here.
You can also use ``hasattr`` to avoid the need for exception catching:

View File

@ -675,7 +675,9 @@ Field name restrictions
Django places some restrictions on model field names:
#. A field name cannot be a Python reserved word, because that would result
in a Python syntax error. For example::
in a Python syntax error. For example:
.. code-block:: text
class Example(models.Model):
pass = models.IntegerField() # 'pass' is a reserved word!
@ -1221,7 +1223,9 @@ subclass with a :class:`~django.db.models.ManyToManyField`::
class Supplier(Place):
customers = models.ManyToManyField(Place)
This results in the error::
This results in the error:
.. code-block:: pytb
Reverse query name for 'Supplier.customers' clashes with reverse query
name for 'Supplier.place_ptr'.

View File

@ -1067,7 +1067,7 @@ query for SQL ``NULL``, use :lookup:`isnull`:
<Dog: Archie>
>>> Dog.objects.filter(data=None)
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data=Value(None, JSONField())
>>> Dog.objects.filter(data=Value(None, JSONField()))
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data__isnull=True)
<QuerySet [<Dog: Max>]>
@ -1356,7 +1356,9 @@ For example, this statement yields a single ``Q`` object that represents the
Q(question__startswith='Who') | Q(question__startswith='What')
This is equivalent to the following SQL ``WHERE`` clause::
This is equivalent to the following SQL ``WHERE`` clause:
.. code-block: sql
WHERE question LIKE 'Who%' OR question LIKE 'What%'

View File

@ -309,7 +309,8 @@ alias::
from django.db import connections
with connections['my_db_alias'].cursor() as cursor:
# Your code here...
# Your code here
...
By default, the Python DB API will return results without their field names,
which means you end up with a ``list`` of values, rather than a ``dict``. At a

View File

@ -111,7 +111,7 @@ requirements::
css = {
'screen': ['pretty.css'],
'tv,projector': ['lo_res.css'],
'print': ['newspaper.css],
'print': ['newspaper.css'],
}
If this last CSS definition were to be rendered, it would become the following HTML:
@ -280,7 +280,7 @@ outputting the complete HTML ``<script>`` or ``<link>`` tag content:
>>> from django.utils.html import html_safe
>>>
>>> @html_safe
>>> class JSPath:
... class JSPath:
... def __str__(self):
... return '<script src="https://example.org/asset.js" rel="stylesheet">'

View File

@ -778,7 +778,9 @@ keyword arguments, or the corresponding attributes on the ``ModelForm`` inner
``Meta`` class. Please see the ``ModelForm`` :ref:`modelforms-selecting-fields`
documentation.
... or enable localization for specific fields::
... or enable localization for specific fields:
.. code-block:: pycon
>>> Form = modelform_factory(Author, form=AuthorForm, localized_fields=["birth_date"])

View File

@ -127,13 +127,15 @@ You can use the :func:`redirect` function in a number of ways.
...
return redirect('some-view-name', foo='bar')
#. By passing a hardcoded URL to redirect to::
#. By passing a hardcoded URL to redirect to:
::
def my_view(request):
...
return redirect('/some/url/')
This also works with full URLs::
This also works with full URLs:
::
def my_view(request):
...

View File

@ -865,7 +865,9 @@ Secondly, you can include an object that contains embedded namespace data. If
you ``include()`` a list of :func:`~django.urls.path` or
:func:`~django.urls.re_path` instances, the URLs contained in that object
will be added to the global namespace. However, you can also ``include()`` a
2-tuple containing::
2-tuple containing:
.. code-block:: text
(<list of path()/re_path() instances>, <application namespace>)

View File

@ -262,7 +262,9 @@ In a case like this, consider something like the following::
}
You would get an error when running :djadmin:`django-admin
compilemessages <compilemessages>`::
compilemessages <compilemessages>`:
.. code-block: pytb
a format specification for argument 'name', as in 'msgstr[0]', doesn't exist in 'msgid'
@ -1094,7 +1096,9 @@ interface within your Python code::
~~~~~~~~~~~~
The ``ngettext`` function provides an interface to pluralize words and
phrases::
phrases:
.. code-block:: javascript
const objectCount = 1 // or 0, or 2, or 3, ...
const string = ngettext(
@ -1113,7 +1117,9 @@ function supports both positional and named interpolation:
* Positional interpolation: ``obj`` contains a JavaScript Array object
whose elements values are then sequentially interpolated in their
corresponding ``fmt`` placeholders in the same order they appear.
For example::
For example:
.. code-block:: javascript
const formats = ngettext(
'There is %s object. Remaining: %s',
@ -1125,7 +1131,9 @@ function supports both positional and named interpolation:
* Named interpolation: This mode is selected by passing the optional
boolean ``named`` parameter as ``true``. ``obj`` contains a JavaScript
object or associative array. For example::
object or associative array. For example:
.. code-block:: javascript
const data = {
count: 10,
@ -1149,7 +1157,9 @@ to produce proper pluralizations).
~~~~~~~~~~~~~~
The ``get_format`` function has access to the configured i18n formatting
settings and can retrieve the format string for a given setting name::
settings and can retrieve the format string for a given setting name:
.. code-block:: javascript
document.write(get_format('DATE_FORMAT'));
// 'N j, Y'
@ -1199,7 +1209,9 @@ translated word::
The ``npgettext`` function also behaves like the Python variant
(:func:`~django.utils.translation.npgettext()`), providing a **pluralized**
contextually translated word::
contextually translated word:
.. code-block:: javascript
document.write(npgettext('group', 'party', 1));
// party
@ -1211,7 +1223,9 @@ contextually translated word::
The ``pluralidx`` function works in a similar way to the :tfilter:`pluralize`
template filter, determining if a given ``count`` should use a plural form of
a word or not::
a word or not:
.. code-block:: javascript
document.write(pluralidx(0));
// true

View File

@ -245,7 +245,7 @@ JSON in the following way::
"model": "sessions.session",
"fields": {
"expire_date": "2013-01-16T08:16:59.844Z",
...
# ...
}
}
]

View File

@ -125,6 +125,7 @@ In your Django apps, use settings by importing the object
if settings.DEBUG:
# Do something
...
Note that ``django.conf.settings`` isn't a module -- it's an object. So
importing individual settings is not possible::

View File

@ -248,7 +248,9 @@ Use the ``django.test.Client`` class to make requests.
>>> c = Client()
>>> c.post('/login/', {'name': 'fred', 'passwd': 'secret'})
...will result in the evaluation of a POST request to this URL::
...will result in the evaluation of a POST request to this URL:
.. code-block:: text
/login/