diff options
| author | Carlton Gibson <carlton.gibson@noumenal.es> | 2023-02-09 16:48:46 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-02-10 21:12:06 +0100 |
| commit | b784768eef75afb32f6d2ce7166551a528bce0ec (patch) | |
| tree | a375a57a50f1766538ea8a62ec49bda352d7f2b9 /docs/topics | |
| parent | 4a89aa25c91e520c247aee428782274dcf10ffd0 (diff) | |
[4.2.x] Refs #34140 -- Applied rst code-block to non-Python examples.
Thanks to J.V. Zammit, Paolo Melchiorre, and Mariusz Felisiak for
reviews.
Backport of 534ac4829764f317cf2fbc4a18354fcc998c1425 from main.
Diffstat (limited to 'docs/topics')
36 files changed, 1249 insertions, 448 deletions
diff --git a/docs/topics/async.txt b/docs/topics/async.txt index 39ca864655..132d7f5460 100644 --- a/docs/topics/async.txt +++ b/docs/topics/async.txt @@ -168,14 +168,18 @@ running your Django code. For example, Jupyter_ notebooks and IPython_ interactive shells both transparently provide an active event loop so that it is easier to interact with asynchronous APIs. -If you're using an IPython shell, you can disable this event loop by running:: +If you're using an IPython shell, you can disable this event loop by running: + +.. code-block:: shell %autoawait off as a command at the IPython prompt. This will allow you to run synchronous code without generating :exc:`~django.core.exceptions.SynchronousOnlyOperation` errors; however, you also won't be able to ``await`` asynchronous APIs. To turn -the event loop back on, run:: +the event loop back on, run: + +.. code-block:: shell %autoawait on diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index 9c0a256d25..84e8577c0c 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -323,7 +323,9 @@ you might create an Employee model:: Assuming an existing Employee Fred Smith who has both a User and Employee model, you can access the related information using Django's standard related -model conventions:: +model conventions: + +.. code-block:: pycon >>> u = User.objects.get(username='fsmith') >>> freds_department = u.employee.department diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 038f2b8eaf..f9980d2847 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -46,7 +46,9 @@ Creating users -------------- The most direct way to create users is to use the included -:meth:`~django.contrib.auth.models.UserManager.create_user` helper function:: +:meth:`~django.contrib.auth.models.UserManager.create_user` helper function: + +.. code-block:: pycon >>> from django.contrib.auth.models import User >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword') @@ -65,7 +67,9 @@ interactively <auth-admin>`. Creating superusers ------------------- -Create superusers using the :djadmin:`createsuperuser` command:: +Create superusers using the :djadmin:`createsuperuser` command: + +.. console:: $ python manage.py createsuperuser --username=joe --email=joe@example.com @@ -330,6 +334,8 @@ inherit the permissions of the concrete model they subclass:: proxy = True permissions = [('can_deliver_pizzas', 'Can deliver pizzas')] +.. code-block:: pycon + >>> # Fetch the content type for the proxy model. >>> content_type = ContentType.objects.get_for_model(Student, for_concrete_model=False) >>> student_permissions = Permission.objects.filter(content_type=content_type) @@ -1728,13 +1734,17 @@ template-friendly proxy of permissions. Evaluating a single-attribute lookup of ``{{ perms }}`` as a boolean is a proxy to :meth:`User.has_module_perms() <django.contrib.auth.models.User.has_module_perms>`. For example, to check if -the logged-in user has any permissions in the ``foo`` app:: +the logged-in user has any permissions in the ``foo`` app: + +.. code-block:: html+django {% if perms.foo %} Evaluating a two-level-attribute lookup as a boolean is a proxy to :meth:`User.has_perm() <django.contrib.auth.models.User.has_perm>`. For example, -to check if the logged-in user has the permission ``foo.add_vote``:: +to check if the logged-in user has the permission ``foo.add_vote``: + +.. code-block:: html+django {% if perms.foo.add_vote %} diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt index 6db9950c04..4cf644307c 100644 --- a/docs/topics/cache.txt +++ b/docs/topics/cache.txt @@ -264,7 +264,9 @@ Creating the cache table ~~~~~~~~~~~~~~~~~~~~~~~~ Before using the database cache, you must create the cache table with this -command:: +command: + +.. code-block:: shell python manage.py createcachetable @@ -840,8 +842,6 @@ a cached item, for example: The low-level cache API ======================= -.. highlight:: python - Sometimes, caching an entire rendered page doesn't gain you very much and is, in fact, inconvenient overkill. @@ -884,7 +884,9 @@ Accessing the cache .. data:: django.core.cache.cache As a shortcut, the default cache is available as - ``django.core.cache.cache``:: + ``django.core.cache.cache``: + + .. code-block:: pycon >>> from django.core.cache import cache @@ -916,14 +918,18 @@ It's the number of seconds the value should be stored in the cache. Passing in ``None`` for ``timeout`` will cache the value forever. A ``timeout`` of ``0`` won't cache the value. -If the object doesn't exist in the cache, ``cache.get()`` returns ``None``:: +If the object doesn't exist in the cache, ``cache.get()`` returns ``None``: + +.. code-block:: pycon >>> # Wait 30 seconds for 'my_key' to expire... >>> cache.get('my_key') None If you need to determine whether the object exists in the cache and you have -stored a literal value ``None``, use a sentinel object as the default:: +stored a literal value ``None``, use a sentinel object as the default: + +.. code-block:: pycon >>> sentinel = object() >>> cache.get('my_key', sentinel) is sentinel @@ -933,7 +939,9 @@ stored a literal value ``None``, use a sentinel object as the default:: True ``cache.get()`` can take a ``default`` argument. This specifies which value to -return if the object doesn't exist in the cache:: +return if the object doesn't exist in the cache: + +.. code-block:: pycon >>> cache.get('my_key', 'has expired') 'has expired' @@ -942,7 +950,9 @@ return if the object doesn't exist in the cache:: To add a key only if it doesn't already exist, use the ``add()`` method. It takes the same parameters as ``set()``, but it will not attempt to -update the cache if the key specified is already present:: +update the cache if the key specified is already present: + +.. code-block:: pycon >>> cache.set('add_key', 'Initial value') >>> cache.add('add_key', 'New value') @@ -958,13 +968,17 @@ check the return value. It will return ``True`` if the value was stored, If you want to get a key's value or set a value if the key isn't in the cache, there is the ``get_or_set()`` method. It takes the same parameters as ``get()`` but the default is set as the new cache value for that key, rather than -returned:: +returned: + +.. code-block:: pycon >>> cache.get('my_new_key') # returns None >>> cache.get_or_set('my_new_key', 'my new value', 100) 'my new value' -You can also pass any callable as a *default* value:: +You can also pass any callable as a *default* value: + +.. code-block:: pycon >>> import datetime >>> cache.get_or_set('some-timestamp-key', datetime.datetime.now) @@ -974,7 +988,9 @@ You can also pass any callable as a *default* value:: There's also a ``get_many()`` interface that only hits the cache once. ``get_many()`` returns a dictionary with all the keys you asked for that -actually exist in the cache (and haven't expired):: +actually exist in the cache (and haven't expired): + +.. code-block:: pycon >>> cache.set('a', 1) >>> cache.set('b', 2) @@ -985,7 +1001,9 @@ actually exist in the cache (and haven't expired):: .. method:: cache.set_many(dict, timeout) To set multiple values more efficiently, use ``set_many()`` to pass a dictionary -of key-value pairs:: +of key-value pairs: + +.. code-block:: pycon >>> cache.set_many({'a': 1, 'b': 2, 'c': 3}) >>> cache.get_many(['a', 'b', 'c']) @@ -999,7 +1017,9 @@ failed to be inserted. .. method:: cache.delete(key, version=None) You can delete keys explicitly with ``delete()`` to clear the cache for a -particular object:: +particular object: + +.. code-block:: pycon >>> cache.delete('a') True @@ -1010,7 +1030,9 @@ otherwise. .. method:: cache.delete_many(keys, version=None) If you want to clear a bunch of keys at once, ``delete_many()`` can take a list -of keys to be cleared:: +of keys to be cleared: + +.. code-block:: pycon >>> cache.delete_many(['a', 'b', 'c']) @@ -1018,14 +1040,18 @@ of keys to be cleared:: Finally, if you want to delete all the keys in the cache, use ``cache.clear()``. Be careful with this; ``clear()`` will remove *everything* -from the cache, not just the keys set by your application. :: +from the cache, not just the keys set by your application. : + +.. code-block:: pycon >>> cache.clear() .. method:: cache.touch(key, timeout=DEFAULT_TIMEOUT, version=None) ``cache.touch()`` sets a new expiration for a key. For example, to update a key -to expire 10 seconds from now:: +to expire 10 seconds from now: + +.. code-block:: pycon >>> cache.touch('a', 10) True @@ -1044,7 +1070,9 @@ You can also increment or decrement a key that already exists using the value will be incremented or decremented by 1. Other increment/decrement values can be specified by providing an argument to the increment/decrement call. A ValueError will be raised if you attempt to increment or decrement a -nonexistent cache key.:: +nonexistent cache key: + +.. code-block:: pycon >>> cache.set('num', 1) >>> cache.incr('num') @@ -1120,7 +1148,9 @@ prefix and the user-provided cache key to obtain the final cache key. By default, any key request will automatically include the site default cache key version. However, the primitive cache functions all include a ``version`` argument, so you can specify a particular cache -key version to set or get. For example:: +key version to set or get. For example: + +.. code-block:: pycon >>> # Set version 2 of a cache key >>> cache.set('my_key', 'hello world!', version=2) @@ -1134,7 +1164,9 @@ key version to set or get. For example:: The version of a specific key can be incremented and decremented using the ``incr_version()`` and ``decr_version()`` methods. This enables specific keys to be bumped to a new version, leaving other -keys unaffected. Continuing our previous example:: +keys unaffected. Continuing our previous example: + +.. code-block:: pycon >>> # Increment the version of 'my_key' >>> cache.incr_version('my_key') @@ -1218,7 +1250,9 @@ yet support asynchronous caching. It will be coming in a future release. ``django.core.cache.backends.base.BaseCache`` has async variants of :ref:`all base methods <cache-basic-interface>`. By convention, the asynchronous versions of all methods are prefixed with ``a``. By default, the arguments for both -variants are the same:: +variants are the same: + +.. code-block:: pycon >>> await cache.aset('num', 1) >>> await cache.ahas_key('num') diff --git a/docs/topics/db/aggregation.txt b/docs/topics/db/aggregation.txt index d871c548e2..d0004a2bff 100644 --- a/docs/topics/db/aggregation.txt +++ b/docs/topics/db/aggregation.txt @@ -44,7 +44,9 @@ Cheat sheet =========== In a hurry? Here's how to do common aggregate queries, assuming the models -above:: +above: + +.. code-block:: pycon # Total number of books. >>> Book.objects.count() @@ -102,19 +104,25 @@ Generating aggregates over a ``QuerySet`` Django provides two ways to generate aggregates. The first way is to generate summary values over an entire ``QuerySet``. For example, say you wanted to calculate the average price of all books available for sale. Django's query -syntax provides a means for describing the set of all books:: +syntax provides a means for describing the set of all books: + +.. code-block:: pycon >>> Book.objects.all() What we need is a way to calculate summary values over the objects that belong to this ``QuerySet``. This is done by appending an ``aggregate()`` -clause onto the ``QuerySet``:: +clause onto the ``QuerySet``: + +.. code-block:: pycon >>> from django.db.models import Avg >>> Book.objects.all().aggregate(Avg('price')) {'price__avg': 34.35} -The ``all()`` is redundant in this example, so this could be simplified to:: +The ``all()`` is redundant in this example, so this could be simplified to: + +.. code-block:: pycon >>> Book.objects.aggregate(Avg('price')) {'price__avg': 34.35} @@ -129,14 +137,18 @@ returns a dictionary of name-value pairs. The name is an identifier for the aggregate value; the value is the computed aggregate. The name is automatically generated from the name of the field and the aggregate function. If you want to manually specify a name for the aggregate value, you can do so -by providing that name when you specify the aggregate clause:: +by providing that name when you specify the aggregate clause: + +.. code-block:: pycon >>> Book.objects.aggregate(average_price=Avg('price')) {'average_price': 34.35} If you want to generate more than one aggregate, you add another argument to the ``aggregate()`` clause. So, if we also wanted to know the maximum and -minimum price of all books, we would issue the query:: +minimum price of all books, we would issue the query: + +.. code-block:: pycon >>> from django.db.models import Avg, Max, Min >>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price')) @@ -159,7 +171,9 @@ specified values. The syntax for these annotations is identical to that used for the :meth:`~.QuerySet.aggregate` clause. Each argument to ``annotate()`` describes an aggregate that is to be calculated. For example, to annotate books with the -number of authors:: +number of authors: + +.. code-block:: pycon # Build an annotated queryset >>> from django.db.models import Count @@ -178,7 +192,9 @@ number of authors:: As with ``aggregate()``, the name for the annotation is automatically derived from the name of the aggregate function and the name of the field being aggregated. You can override this default name by providing an alias when you -specify the annotation:: +specify the annotation: + +.. code-block:: pycon >>> q = Book.objects.annotate(num_authors=Count('authors')) >>> q[0].num_authors @@ -239,7 +255,9 @@ filters. Django will then handle any table joins that are required to retrieve and aggregate the related value. For example, to find the price range of books offered in each store, -you could use the annotation:: +you could use the annotation: + +.. code-block:: pycon >>> from django.db.models import Max, Min >>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price')) @@ -250,13 +268,17 @@ price field of the book model to produce a minimum and maximum value. The same rules apply to the ``aggregate()`` clause. If you wanted to know the lowest and highest price of any book that is available for sale -in any of the stores, you could use the aggregate:: +in any of the stores, you could use the aggregate: + +.. code-block:: pycon >>> Store.objects.aggregate(min_price=Min('books__price'), max_price=Max('books__price')) Join chains can be as deep as you require. For example, to extract the age of the youngest author of any book available for sale, you could -issue the query:: +issue the query: + +.. code-block:: pycon >>> Store.objects.aggregate(youngest_age=Min('books__authors__age')) @@ -270,7 +292,9 @@ of related models and double-underscores are used here too. For example, we can ask for all publishers, annotated with their respective total book stock counters (note how we use ``'book'`` to specify the -``Publisher`` -> ``Book`` reverse foreign key hop):: +``Publisher`` -> ``Book`` reverse foreign key hop): + +.. code-block:: pycon >>> from django.db.models import Avg, Count, Min, Sum >>> Publisher.objects.annotate(Count('book')) @@ -278,7 +302,9 @@ total book stock counters (note how we use ``'book'`` to specify the (Every ``Publisher`` in the resulting ``QuerySet`` will have an extra attribute called ``book__count``.) -We can also ask for the oldest book of any of those managed by every publisher:: +We can also ask for the oldest book of any of those managed by every publisher: + +.. code-block:: pycon >>> Publisher.objects.aggregate(oldest_pubdate=Min('book__pubdate')) @@ -288,7 +314,9 @@ such alias were specified, it would be the rather long ``'book__pubdate__min'``. This doesn't apply just to foreign keys. It also works with many-to-many relations. For example, we can ask for every author, annotated with the total number of pages considering all the books the author has (co-)authored (note how we -use ``'book'`` to specify the ``Author`` -> ``Book`` reverse many-to-many hop):: +use ``'book'`` to specify the ``Author`` -> ``Book`` reverse many-to-many hop): + +.. code-block:: pycon >>> Author.objects.annotate(total_pages=Sum('book__pages')) @@ -297,7 +325,9 @@ called ``total_pages``. If no such alias were specified, it would be the rather long ``book__pages__sum``.) Or ask for the average rating of all the books written by author(s) we have on -file:: +file: + +.. code-block:: pycon >>> Author.objects.aggregate(average_rating=Avg('book__rating')) @@ -317,7 +347,9 @@ constraining the objects that are considered for aggregation. When used with an ``annotate()`` clause, a filter has the effect of constraining the objects for which an annotation is calculated. For example, you can generate an annotated list of all books that have a title starting -with "Django" using the query:: +with "Django" using the query: + +.. code-block:: pycon >>> from django.db.models import Avg, Count >>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors')) @@ -325,7 +357,9 @@ with "Django" using the query:: When used with an ``aggregate()`` clause, a filter has the effect of constraining the objects over which the aggregate is calculated. For example, you can generate the average price of all books with a -title that starts with "Django" using the query:: +title that starts with "Django" using the query: + +.. code-block:: pycon >>> Book.objects.filter(name__startswith="Django").aggregate(Avg('price')) @@ -339,7 +373,9 @@ used in ``filter()`` and ``exclude()`` clauses in the same way as any other model field. For example, to generate a list of books that have more than one author, -you can issue the query:: +you can issue the query: + +.. code-block:: pycon >>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=1) @@ -348,7 +384,9 @@ based upon that annotation. If you need two annotations with two separate filters you can use the ``filter`` argument with any aggregate. For example, to generate a list of -authors with a count of highly rated books:: +authors with a count of highly rated books: + +.. code-block:: pycon >>> highly_rated = Count('book', filter=Q(book__rating__gte=7)) >>> Author.objects.annotate(num_books=Count('book'), highly_rated_books=highly_rated) @@ -381,7 +419,9 @@ Given: * Publisher B has two books with ratings 1 and 4. * Publisher C has one book with rating 1. -Here's an example with the ``Count`` aggregate:: +Here's an example with the ``Count`` aggregate: + +.. code-block:: pycon >>> a, b = Publisher.objects.annotate(num_books=Count('book', distinct=True)).filter(book__rating__gt=3.0) >>> a, a.num_books @@ -406,7 +446,9 @@ The second query counts the number of books that have a rating exceeding 3.0 for each publisher. The filter precedes the annotation, so the filter constrains the objects considered when calculating the annotation. -Here's another example with the ``Avg`` aggregate:: +Here's another example with the ``Avg`` aggregate: + +.. code-block:: pycon >>> a, b = Publisher.objects.annotate(avg_rating=Avg('book__rating')).filter(book__rating__gt=3.0) >>> a, a.avg_rating @@ -437,7 +479,9 @@ define an ``order_by()`` clause, the aggregates you provide can reference any alias defined as part of an ``annotate()`` clause in the query. For example, to order a ``QuerySet`` of books by the number of authors -that have contributed to the book, you could use the following query:: +that have contributed to the book, you could use the following query: + +.. code-block:: pycon >>> Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors') @@ -462,7 +506,9 @@ rating of books written by each author: This will return one result for each author in the database, annotated with their average book rating. -However, the result will be slightly different if you use a ``values()`` clause:: +However, the result will be slightly different if you use a ``values()`` clause: + +.. code-block:: pycon >>> Author.objects.values('name').annotate(average_rating=Avg('book__rating')) @@ -486,7 +532,9 @@ the ``values()`` clause only constrains the fields that are generated on output. For example, if we reverse the order of the ``values()`` and ``annotate()`` -clause from our previous example:: +clause from our previous example: + +.. code-block:: pycon >>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating') @@ -563,7 +611,9 @@ any alias defined as part of an ``annotate()`` clause in the query. For example, if you wanted to calculate the average number of authors per book you first annotate the set of books with the author count, then -aggregate that author count, referencing the annotation field:: +aggregate that author count, referencing the annotation field: + +.. code-block:: pycon >>> from django.db.models import Avg, Count >>> Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors')) diff --git a/docs/topics/db/examples/many_to_many.txt b/docs/topics/db/examples/many_to_many.txt index f53f3c131a..e47069c200 100644 --- a/docs/topics/db/examples/many_to_many.txt +++ b/docs/topics/db/examples/many_to_many.txt @@ -2,8 +2,6 @@ Many-to-many relationships ========================== -.. highlight:: pycon - To define a many-to-many relationship, use :class:`~django.db.models.ManyToManyField`. @@ -36,7 +34,9 @@ objects, and a ``Publication`` has multiple ``Article`` objects: What follows are examples of operations that can be performed using the Python API facilities. -Create a few ``Publications``:: +Create a few ``Publications``: + +.. code-block:: pycon >>> p1 = Publication(title='The Python Journal') >>> p1.save() @@ -45,11 +45,15 @@ Create a few ``Publications``:: >>> p3 = Publication(title='Science Weekly') >>> p3.save() -Create an ``Article``:: +Create an ``Article``: + +.. code-block:: pycon >>> a1 = Article(headline='Django lets you build web apps easily') -You can't associate it with a ``Publication`` until it's been saved:: +You can't associate it with a ``Publication`` until it's been saved: + +.. code-block:: pycon >>> a1.publications.add(p1) Traceback (most recent call last): @@ -57,26 +61,35 @@ You can't associate it with a ``Publication`` until it's been saved:: ValueError: "<Article: Django lets you build web apps easily>" needs to have a value for field "id" before this many-to-many relationship can be used. Save it! -:: + +.. code-block:: pycon >>> a1.save() -Associate the ``Article`` with a ``Publication``:: +Associate the ``Article`` with a ``Publication``: + +.. code-block:: pycon >>> a1.publications.add(p1) -Create another ``Article``, and set it to appear in the ``Publications``:: +Create another ``Article``, and set it to appear in the ``Publications``: + +.. code-block:: pycon >>> a2 = Article(headline='NASA uses Python') >>> a2.save() >>> a2.publications.add(p1, p2) >>> a2.publications.add(p3) -Adding a second time is OK, it will not duplicate the relation:: +Adding a second time is OK, it will not duplicate the relation: + +.. code-block:: pycon >>> a2.publications.add(p3) -Adding an object of the wrong type raises :exc:`TypeError`:: +Adding an object of the wrong type raises :exc:`TypeError`: + +.. code-block:: pycon >>> a2.publications.add(a1) Traceback (most recent call last): @@ -84,18 +97,24 @@ Adding an object of the wrong type raises :exc:`TypeError`:: TypeError: 'Publication' instance expected Create and add a ``Publication`` to an ``Article`` in one step using -:meth:`~django.db.models.fields.related.RelatedManager.create`:: +:meth:`~django.db.models.fields.related.RelatedManager.create`: + +.. code-block:: pycon >>> new_publication = a2.publications.create(title='Highlights for Children') -``Article`` objects have access to their related ``Publication`` objects:: +``Article`` objects have access to their related ``Publication`` objects: + +.. code-block:: pycon >>> a1.publications.all() <QuerySet [<Publication: The Python Journal>]> >>> a2.publications.all() <QuerySet [<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]> -``Publication`` objects have access to their related ``Article`` objects:: +``Publication`` objects have access to their related ``Article`` objects: + +.. code-block:: pycon >>> p2.article_set.all() <QuerySet [<Article: NASA uses Python>]> @@ -105,7 +124,9 @@ Create and add a ``Publication`` to an ``Article`` in one step using <QuerySet [<Article: NASA uses Python>]> Many-to-many relationships can be queried using :ref:`lookups across -relationships <lookups-that-span-relationships>`:: +relationships <lookups-that-span-relationships>`: + +.. code-block:: pycon >>> Article.objects.filter(publications__id=1) <QuerySet [<Article: Django lets you build web apps easily>, <Article: NASA uses Python>]> @@ -123,7 +144,9 @@ relationships <lookups-that-span-relationships>`:: <QuerySet [<Article: NASA uses Python>]> The :meth:`~django.db.models.query.QuerySet.count` function respects -:meth:`~django.db.models.query.QuerySet.distinct` as well:: +:meth:`~django.db.models.query.QuerySet.distinct` as well: + +.. code-block:: pycon >>> Article.objects.filter(publications__title__startswith="Science").count() 2 @@ -137,7 +160,9 @@ The :meth:`~django.db.models.query.QuerySet.count` function respects <QuerySet [<Article: Django lets you build web apps easily>, <Article: NASA uses Python>]> Reverse m2m queries are supported (i.e., starting at the table that doesn't have -a :class:`~django.db.models.ManyToManyField`):: +a :class:`~django.db.models.ManyToManyField`): + +.. code-block:: pycon >>> Publication.objects.filter(id=1) <QuerySet [<Publication: The Python Journal>]> @@ -162,12 +187,16 @@ a :class:`~django.db.models.ManyToManyField`):: <QuerySet [<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]> Excluding a related item works as you would expect, too (although the SQL -involved is a little complex):: +involved is a little complex): + +.. code-block:: pycon >>> Article.objects.exclude(publications=p2) <QuerySet [<Article: Django lets you build web apps easily>]> -If we delete a ``Publication``, its ``Articles`` won't be able to access it:: +If we delete a ``Publication``, its ``Articles`` won't be able to access it: + +.. code-block:: pycon >>> p1.delete() >>> Publication.objects.all() @@ -176,7 +205,9 @@ If we delete a ``Publication``, its ``Articles`` won't be able to access it:: >>> a1.publications.all() <QuerySet []> -If we delete an ``Article``, its ``Publications`` won't be able to access it:: +If we delete an ``Article``, its ``Publications`` won't be able to access it: + +.. code-block:: pycon >>> a2.delete() >>> Article.objects.all() @@ -184,7 +215,9 @@ If we delete an ``Article``, its ``Publications`` won't be able to access it:: >>> p2.article_set.all() <QuerySet []> -Adding via the 'other' end of an m2m:: +Adding via the 'other' end of an m2m: + +.. code-block:: pycon >>> a4 = Article(headline='NASA finds intelligent life on Earth') >>> a4.save() @@ -194,7 +227,9 @@ Adding via the 'other' end of an m2m:: >>> a4.publications.all() <QuerySet [<Publication: Science News>]> -Adding via the other end using keywords:: +Adding via the other end using keywords: + +.. code-block:: pycon >>> new_article = p2.article_set.create(headline='Oxygen-free diet works wonders') >>> p2.article_set.all() @@ -203,7 +238,9 @@ Adding via the other end using keywords:: >>> a5.publications.all() <QuerySet [<Publication: Science News>]> -Removing ``Publication`` from an ``Article``:: +Removing ``Publication`` from an ``Article``: + +.. code-block:: pycon >>> a4.publications.remove(p2) >>> p2.article_set.all() @@ -211,7 +248,9 @@ Removing ``Publication`` from an ``Article``:: >>> a4.publications.all() <QuerySet []> -And from the other end:: +And from the other end: + +.. code-block:: pycon >>> p2.article_set.remove(a5) >>> p2.article_set.all() @@ -219,7 +258,9 @@ And from the other end:: >>> a5.publications.all() <QuerySet []> -Relation sets can be set:: +Relation sets can be set: + +.. code-block:: pycon >>> a4.publications.all() <QuerySet [<Publication: Science News>]> @@ -227,13 +268,17 @@ Relation sets can be set:: >>> a4.publications.all() <QuerySet [<Publication: Science Weekly>]> -Relation sets can be cleared:: +Relation sets can be cleared: + +.. code-block:: pycon >>> p2.article_set.clear() >>> p2.article_set.all() <QuerySet []> -And you can clear from the other end:: +And you can clear from the other end: + +.. code-block:: pycon >>> p2.article_set.add(a4, a5) >>> p2.article_set.all() @@ -246,7 +291,9 @@ And you can clear from the other end:: >>> p2.article_set.all() <QuerySet [<Article: Oxygen-free diet works wonders>]> -Recreate the ``Article`` and ``Publication`` we have deleted:: +Recreate the ``Article`` and ``Publication`` we have deleted: + +.. code-block:: pycon >>> p1 = Publication(title='The Python Journal') >>> p1.save() @@ -255,7 +302,9 @@ Recreate the ``Article`` and ``Publication`` we have deleted:: >>> a2.publications.add(p1, p2, p3) Bulk delete some ``Publications`` - references to deleted publications should -go:: +go: + +.. code-block:: pycon >>> Publication.objects.filter(title__startswith='Science').delete() >>> Publication.objects.all() @@ -265,7 +314,9 @@ go:: >>> a2.publications.all() <QuerySet [<Publication: The Python Journal>]> -Bulk delete some articles - references to deleted objects should go:: +Bulk delete some articles - references to deleted objects should go: + +.. code-block:: pycon >>> q = Article.objects.filter(headline__startswith='Django') >>> print(q) @@ -274,7 +325,9 @@ Bulk delete some articles - references to deleted objects should go:: After the :meth:`~django.db.models.query.QuerySet.delete`, the :class:`~django.db.models.query.QuerySet` cache needs to be cleared, and the -referenced objects should be gone:: +referenced objects should be gone: + +.. code-block:: pycon >>> print(q) <QuerySet []> diff --git a/docs/topics/db/examples/many_to_one.txt b/docs/topics/db/examples/many_to_one.txt index 20e489397c..f1311989ce 100644 --- a/docs/topics/db/examples/many_to_one.txt +++ b/docs/topics/db/examples/many_to_one.txt @@ -31,9 +31,9 @@ objects, but an ``Article`` can only have one ``Reporter`` object:: What follows are examples of operations that can be performed using the Python API facilities. -.. highlight:: pycon +Create a few Reporters: -Create a few Reporters:: +.. code-block:: pycon >>> r = Reporter(first_name='John', last_name='Smith', email='john@example.com') >>> r.save() @@ -41,7 +41,9 @@ Create a few Reporters:: >>> r2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com') >>> r2.save() -Create an Article:: +Create an Article: + +.. code-block:: pycon >>> from datetime import date >>> a = Article(id=None, headline="This is a test", pub_date=date(2005, 7, 27), reporter=r) @@ -55,7 +57,9 @@ Create an Article:: Note that you must save an object before it can be assigned to a foreign key relationship. For example, creating an ``Article`` with unsaved ``Reporter`` -raises ``ValueError``:: +raises ``ValueError``: + +.. code-block:: pycon >>> r3 = Reporter(first_name='John', last_name='Smith', email='john@example.com') >>> Article.objects.create(headline="This is a test", pub_date=date(2005, 7, 27), reporter=r3) @@ -63,11 +67,15 @@ raises ``ValueError``:: ... ValueError: save() prohibited to prevent data loss due to unsaved related object 'reporter'. -Article objects have access to their related Reporter objects:: +Article objects have access to their related Reporter objects: + +.. code-block:: pycon >>> r = a.reporter -Create an Article via the Reporter object:: +Create an Article via the Reporter object: + +.. code-block:: pycon >>> new_article = r.article_set.create(headline="John's second story", pub_date=date(2005, 7, 29)) >>> new_article @@ -77,7 +85,9 @@ Create an Article via the Reporter object:: >>> new_article.reporter.id 1 -Create a new article:: +Create a new article: + +.. code-block:: pycon >>> new_article2 = Article.objects.create(headline="Paul's story", pub_date=date(2006, 1, 17), reporter=r) >>> new_article2.reporter @@ -87,7 +97,9 @@ Create a new article:: >>> r.article_set.all() <QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]> -Add the same article to a different article set - check that it moves:: +Add the same article to a different article set - check that it moves: + +.. code-block:: pycon >>> r2.article_set.add(new_article2) >>> new_article2.reporter.id @@ -95,7 +107,9 @@ Add the same article to a different article set - check that it moves:: >>> new_article2.reporter <Reporter: Paul Jones> -Adding an object of the wrong type raises TypeError:: +Adding an object of the wrong type raises TypeError: + +.. code-block:: pycon >>> r.article_set.add(r2) Traceback (most recent call last): @@ -118,7 +132,9 @@ Note that in the last example the article has moved from John to Paul. Related managers support field lookups as well. The API automatically follows relationships as far as you need. Use double underscores to separate relationships. -This works as many levels deep as you want. There's no limit. For example:: +This works as many levels deep as you want. There's no limit. For example: + +.. code-block:: pycon >>> r.article_set.filter(headline__startswith='This') <QuerySet [<Article: This is a test>]> @@ -127,19 +143,25 @@ This works as many levels deep as you want. There's no limit. For example:: >>> Article.objects.filter(reporter__first_name='John') <QuerySet [<Article: John's second story>, <Article: This is a test>]> -Exact match is implied here:: +Exact match is implied here: + +.. code-block:: pycon >>> Article.objects.filter(reporter__first_name='John') <QuerySet [<Article: John's second story>, <Article: This is a test>]> Query twice over the related field. This translates to an AND condition in the -WHERE clause:: +WHERE clause: + +.. code-block:: pycon >>> Article.objects.filter(reporter__first_name='John', reporter__last_name='Smith') <QuerySet [<Article: John's second story>, <Article: This is a test>]> For the related lookup you can supply a primary key value or pass the related -object explicitly:: +object explicitly: + +.. code-block:: pycon >>> Article.objects.filter(reporter__pk=1) <QuerySet [<Article: John's second story>, <Article: This is a test>]> @@ -153,12 +175,16 @@ object explicitly:: >>> Article.objects.filter(reporter__in=[r,r2]).distinct() <QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]> -You can also use a queryset instead of a literal list of instances:: +You can also use a queryset instead of a literal list of instances: + +.. code-block:: pycon >>> Article.objects.filter(reporter__in=Reporter.objects.filter(first_name='John')).distinct() <QuerySet [<Article: John's second story>, <Article: This is a test>]> -Querying in the opposite direction:: +Querying in the opposite direction: + +.. code-block:: pycon >>> Reporter.objects.filter(article__pk=1) <QuerySet [<Reporter: John Smith>]> @@ -172,14 +198,18 @@ Querying in the opposite direction:: >>> Reporter.objects.filter(article__headline__startswith='This').distinct() <QuerySet [<Reporter: John Smith>]> -Counting in the opposite direction works in conjunction with ``distinct()``:: +Counting in the opposite direction works in conjunction with ``distinct()``: + +.. code-block:: pycon >>> Reporter.objects.filter(article__headline__startswith='This').count() 3 >>> Reporter.objects.filter(article__headline__startswith='This').distinct().count() 1 -Queries can go round in circles:: +Queries can go round in circles: + +.. code-block:: pycon >>> Reporter.objects.filter(article__reporter__first_name__startswith='John') <QuerySet [<Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>]> @@ -190,7 +220,9 @@ Queries can go round in circles:: If you delete a reporter, their articles will be deleted (assuming that the ForeignKey was defined with :attr:`django.db.models.ForeignKey.on_delete` set to -``CASCADE``, which is the default):: +``CASCADE``, which is the default): + +.. code-block:: pycon >>> Article.objects.all() <QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]> @@ -202,7 +234,9 @@ ForeignKey was defined with :attr:`django.db.models.ForeignKey.on_delete` set to >>> Reporter.objects.order_by('first_name') <QuerySet [<Reporter: John Smith>]> -You can delete using a JOIN in the query:: +You can delete using a JOIN in the query: + +.. code-block:: pycon >>> Reporter.objects.filter(article__headline__startswith='This').delete() >>> Reporter.objects.all() diff --git a/docs/topics/db/examples/one_to_one.txt b/docs/topics/db/examples/one_to_one.txt index 92f5e9ce40..1a21993a06 100644 --- a/docs/topics/db/examples/one_to_one.txt +++ b/docs/topics/db/examples/one_to_one.txt @@ -38,31 +38,39 @@ In this example, a ``Place`` optionally can be a ``Restaurant``:: What follows are examples of operations that can be performed using the Python API facilities. -.. highlight:: pycon +Create a couple of Places: -Create a couple of Places:: +.. code-block:: pycon >>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton') >>> p1.save() >>> p2 = Place(name='Ace Hardware', address='1013 N. Ashland') >>> p2.save() -Create a Restaurant. Pass the "parent" object as this object's primary key:: +Create a Restaurant. Pass the "parent" object as this object's primary key: + +.. code-block:: pycon >>> r = Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False) >>> r.save() -A Restaurant can access its place:: +A Restaurant can access its place: + +.. code-block:: pycon >>> r.place <Place: Demon Dogs the place> -A Place can access its restaurant, if available:: +A Place can access its restaurant, if available: + +.. code-block:: pycon >>> p1.restaurant <Restaurant: Demon Dogs the restaurant> -p2 doesn't have an associated restaurant:: +p2 doesn't have an associated restaurant: + +.. code-block:: pycon >>> from django.core.exceptions import ObjectDoesNotExist >>> try: @@ -71,13 +79,17 @@ p2 doesn't have an associated restaurant:: >>> print("There is no restaurant here.") There is no restaurant here. -You can also use ``hasattr`` to avoid the need for exception catching:: +You can also use ``hasattr`` to avoid the need for exception catching: + +.. code-block:: pycon >>> hasattr(p2, 'restaurant') False Set the place using assignment notation. Because place is the primary key on -Restaurant, the save will create a new restaurant:: +Restaurant, the save will create a new restaurant: + +.. code-block:: pycon >>> r.place = p2 >>> r.save() @@ -86,7 +98,9 @@ Restaurant, the save will create a new restaurant:: >>> r.place <Place: Ace Hardware the place> -Set the place back again, using assignment in the reverse direction:: +Set the place back again, using assignment in the reverse direction: + +.. code-block:: pycon >>> p1.restaurant = r >>> p1.restaurant @@ -94,7 +108,9 @@ Set the place back again, using assignment in the reverse direction:: Note that you must save an object before it can be assigned to a one-to-one relationship. For example, creating a ``Restaurant`` with unsaved ``Place`` -raises ``ValueError``:: +raises ``ValueError``: + +.. code-block:: pycon >>> p3 = Place(name='Demon Dogs', address='944 W. Fullerton') >>> Restaurant.objects.create(place=p3, serves_hot_dogs=True, serves_pizza=False) @@ -104,18 +120,24 @@ raises ``ValueError``:: Restaurant.objects.all() returns the Restaurants, not the Places. Note that there are two restaurants - Ace Hardware the Restaurant was created in the call -to r.place = p2:: +to r.place = p2: + +.. code-block:: pycon >>> Restaurant.objects.all() <QuerySet [<Restaurant: Demon Dogs the restaurant>, <Restaurant: Ace Hardware the restaurant>]> Place.objects.all() returns all Places, regardless of whether they have -Restaurants:: +Restaurants: + +.. code-block:: pycon >>> Place.objects.order_by('name') <QuerySet [<Place: Ace Hardware the place>, <Place: Demon Dogs the place>]> -You can query the models using :ref:`lookups across relationships <lookups-that-span-relationships>`:: +You can query the models using :ref:`lookups across relationships <lookups-that-span-relationships>`: + +.. code-block:: pycon >>> Restaurant.objects.get(place=p1) <Restaurant: Demon Dogs the restaurant> @@ -126,7 +148,9 @@ You can query the models using :ref:`lookups across relationships <lookups-that- >>> Restaurant.objects.exclude(place__address__contains="Ashland") <QuerySet [<Restaurant: Demon Dogs the restaurant>]> -This also works in reverse:: +This also works in reverse: + +.. code-block:: pycon >>> Place.objects.get(pk=1) <Place: Demon Dogs the place> @@ -140,20 +164,26 @@ This also works in reverse:: If you delete a place, its restaurant will be deleted (assuming that the ``OneToOneField`` was defined with :attr:`~django.db.models.ForeignKey.on_delete` set to ``CASCADE``, which is the -default):: +default): + +.. code-block:: pycon >>> p2.delete() (2, {'one_to_one.Restaurant': 1, 'one_to_one.Place': 1}) >>> Restaurant.objects.all() <QuerySet [<Restaurant: Demon Dogs the restaurant>]> -Add a Waiter to the Restaurant:: +Add a Waiter to the Restaurant: + +.. code-block:: pycon >>> w = r.waiter_set.create(name='Joe') >>> w <Waiter: Joe the waiter at Demon Dogs the restaurant> -Query the waiters:: +Query the waiters: + +.. code-block:: pycon >>> Waiter.objects.filter(restaurant__place=p1) <QuerySet [<Waiter: Joe the waiter at Demon Dogs the restaurant>]> diff --git a/docs/topics/db/fixtures.txt b/docs/topics/db/fixtures.txt index b1425adc13..629c6c9a85 100644 --- a/docs/topics/db/fixtures.txt +++ b/docs/topics/db/fixtures.txt @@ -43,7 +43,9 @@ Django will load any and all fixtures it finds in these locations that match the provided fixture names. If the named fixture has a file extension, only fixtures of that type -will be loaded. For example:: +will be loaded. For example: + +.. code-block:: shell django-admin loaddata mydata.json @@ -52,7 +54,9 @@ must correspond to the registered name of a :ref:`serializer <serialization-formats>` (e.g., ``json`` or ``xml``). If you omit the extensions, Django will search all available fixture types -for a matching fixture. For example:: +for a matching fixture. For example: + +.. code-block:: shell django-admin loaddata mydata @@ -61,7 +65,9 @@ directory contained ``mydata.json``, that fixture would be loaded as a JSON fixture. The fixtures that are named can include directory components. These -directories will be included in the search path. For example:: +directories will be included in the search path. For example: + +.. code-block:: shell django-admin loaddata foo/bar/mydata.json @@ -124,7 +130,9 @@ Compressed fixtures =================== Fixtures may be compressed in ``zip``, ``gz``, ``bz2``, ``lzma``, or ``xz`` -format. For example:: +format. For example: + +.. code-block:: shell django-admin loaddata mydata.json diff --git a/docs/topics/db/managers.txt b/docs/topics/db/managers.txt index 0a94ce7f52..f576b01ea2 100644 --- a/docs/topics/db/managers.txt +++ b/docs/topics/db/managers.txt @@ -425,7 +425,9 @@ Implementation concerns Whatever features you add to your custom ``Manager``, it must be possible to make a shallow copy of a ``Manager`` instance; i.e., the -following code must work:: +following code must work: + +.. code-block:: pycon >>> import copy >>> manager = MyManager() diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 2f8a5551ff..43a34bbe28 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -189,7 +189,7 @@ ones: name = models.CharField(max_length=60) shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES) - :: + .. code-block:: pycon >>> p = Person(name="Fred Flintstone", shirt_size="L") >>> p.save() @@ -503,7 +503,9 @@ There are a few restrictions on the intermediate model: Now that you have set up your :class:`~django.db.models.ManyToManyField` to use your intermediary model (``Membership``, in this case), you're ready to start creating some many-to-many relationships. You do this by creating instances of -the intermediate model:: +the intermediate model: + +.. code-block:: pycon >>> ringo = Person.objects.create(name="Ringo Starr") >>> paul = Person.objects.create(name="Paul McCartney") @@ -526,7 +528,9 @@ You can also use :meth:`~django.db.models.fields.related.RelatedManager.add`, :meth:`~django.db.models.fields.related.RelatedManager.create`, or :meth:`~django.db.models.fields.related.RelatedManager.set` to create relationships, as long as you specify ``through_defaults`` for any required -fields:: +fields: + +.. code-block:: pycon >>> beatles.members.add(john, through_defaults={'date_joined': date(1960, 8, 1)}) >>> beatles.members.create(name="George Harrison", through_defaults={'date_joined': date(1960, 8, 1)}) @@ -537,7 +541,9 @@ You may prefer to create instances of the intermediate model directly. If the custom through table defined by the intermediate model does not enforce uniqueness on the ``(model1, model2)`` pair, allowing multiple values, the :meth:`~django.db.models.fields.related.RelatedManager.remove` call will -remove all intermediate model instances:: +remove all intermediate model instances: + +.. code-block:: pycon >>> Membership.objects.create(person=ringo, group=beatles, ... date_joined=date(1968, 9, 4), @@ -550,7 +556,9 @@ remove all intermediate model instances:: <QuerySet [<Person: Paul McCartney>]> The :meth:`~django.db.models.fields.related.RelatedManager.clear` -method can be used to remove all many-to-many relationships for an instance:: +method can be used to remove all many-to-many relationships for an instance: + +.. code-block:: pycon >>> # Beatles have broken up >>> beatles.members.clear() @@ -560,13 +568,17 @@ method can be used to remove all many-to-many relationships for an instance:: Once you have established the many-to-many relationships, you can issue queries. Just as with normal many-to-many relationships, you can query using -the attributes of the many-to-many-related model:: +the attributes of the many-to-many-related model: + +.. code-block:: pycon # Find all the groups with a member whose name starts with 'Paul' >>> Group.objects.filter(members__name__startswith='Paul') <QuerySet [<Group: The Beatles>]> -As you are using an intermediate model, you can also query on its attributes:: +As you are using an intermediate model, you can also query on its attributes: + +.. code-block:: pycon # Find all the members of the Beatles that joined after 1 Jan 1961 >>> Person.objects.filter( @@ -575,7 +587,9 @@ As you are using an intermediate model, you can also query on its attributes:: <QuerySet [<Person: Ringo Starr]> If you need to access a membership's information you may do so by directly -querying the ``Membership`` model:: +querying the ``Membership`` model: + +.. code-block:: pycon >>> ringos_membership = Membership.objects.get(group=beatles, person=ringo) >>> ringos_membership.date_joined @@ -585,7 +599,9 @@ querying the ``Membership`` model:: Another way to access the same information is by querying the :ref:`many-to-many reverse relationship<m2m-reverse-relationships>` from a -``Person`` object:: +``Person`` object: + +.. code-block:: pycon >>> ringos_membership = ringo.membership_set.get(group=beatles) >>> ringos_membership.date_joined @@ -1120,14 +1136,18 @@ For example:: All of the fields of ``Place`` will also be available in ``Restaurant``, although the data will reside in a different database table. So these are both -possible:: +possible: + +.. code-block:: pycon >>> Place.objects.filter(name="Bob's Cafe") >>> Restaurant.objects.filter(name="Bob's Cafe") If you have a ``Place`` that is also a ``Restaurant``, you can get from the ``Place`` object to the ``Restaurant`` object by using the lowercase version of -the model name:: +the model name: + +.. code-block:: pycon >>> p = Place.objects.get(id=12) # If p is a Restaurant object, this will give the child class: @@ -1264,7 +1284,9 @@ For example, suppose you want to add a method to the ``Person`` model. You can d The ``MyPerson`` class operates on the same database table as its parent ``Person`` class. In particular, any new instances of ``Person`` will also be -accessible through ``MyPerson``, and vice-versa:: +accessible through ``MyPerson``, and vice-versa: + +.. code-block:: pycon >>> p = Person.objects.create(first_name="foobar") >>> MyPerson.objects.get(first_name="foobar") diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt index 6a5314603c..697addb539 100644 --- a/docs/topics/db/multi-db.txt +++ b/docs/topics/db/multi-db.txt @@ -85,7 +85,9 @@ The :djadmin:`migrate` management command operates on one database at a time. By default, it operates on the ``default`` database, but by providing the :option:`--database <migrate --database>` option, you can tell it to synchronize a different database. So, to synchronize all models onto -all databases in the first example above, you would need to call:: +all databases in the first example above, you would need to call: + +.. code-block:: shell $ ./manage.py migrate $ ./manage.py migrate --database=users @@ -97,7 +99,9 @@ constraining the availability of particular models. If, as in the second example above, you've left the ``default`` database empty, you must provide a database name each time you run :djadmin:`migrate`. Omitting -the database name would raise an error. For the second example:: +the database name would raise an error. For the second example: + +.. code-block:: shell $ ./manage.py migrate --database=users $ ./manage.py migrate --database=customers @@ -405,7 +409,9 @@ catch-all nature of the PrimaryReplicaRouter implementation would mean that all models would be available on all databases. With this setup installed, and all databases migrated as per -:ref:`synchronizing_multiple_databases`, lets run some Django code:: +:ref:`synchronizing_multiple_databases`, lets run some Django code: + +.. code-block:: pycon >>> # This retrieval will be performed on the 'auth_db' database >>> fred = User.objects.get(username='fred') @@ -453,7 +459,9 @@ You can select the database for a ``QuerySet`` at any point in the ``QuerySet`` that uses the specified database. ``using()`` takes a single argument: the alias of the database on -which you want to run the query. For example:: +which you want to run the query. For example: + +.. code-block:: pycon >>> # This will run on the 'default' database. >>> Author.objects.all() @@ -471,7 +479,9 @@ Use the ``using`` keyword to ``Model.save()`` to specify to which database the data should be saved. For example, to save an object to the ``legacy_users`` database, you'd -use this:: +use this: + +.. code-block:: pycon >>> my_object.save(using='legacy_users') @@ -486,7 +496,9 @@ use ``save(using=...)`` as a way to migrate the instance to a new database. However, if you don't take appropriate steps, this could have some unexpected consequences. -Consider the following example:: +Consider the following example: + +.. code-block:: pycon >>> p = Person(name='Fred') >>> p.save(using='first') # (statement 1) @@ -510,7 +522,9 @@ will be overridden when ``p`` is saved. You can avoid this in two ways. First, you can clear the primary key of the instance. If an object has no primary key, Django will treat it as a new object, avoiding any loss of data on the ``second`` -database:: +database: + +.. code-block:: pycon >>> p = Person(name='Fred') >>> p.save(using='first') @@ -518,7 +532,9 @@ database:: >>> p.save(using='second') # Write a completely new object. The second option is to use the ``force_insert`` option to ``save()`` -to ensure that Django does an SQL ``INSERT``:: +to ensure that Django does an SQL ``INSERT``: + +.. code-block:: pycon >>> p = Person(name='Fred') >>> p.save(using='first') @@ -534,7 +550,9 @@ Selecting a database to delete from By default, a call to delete an existing object will be executed on the same database that was used to retrieve the object in the first -place:: +place: + +.. code-block:: pycon >>> u = User.objects.using('legacy_users').get(username='fred') >>> u.delete() # will delete from the `legacy_users` database @@ -544,7 +562,9 @@ To specify the database from which a model will be deleted, pass a argument works just like the ``using`` keyword argument to ``save()``. For example, if you're migrating a user from the ``legacy_users`` -database to the ``new_users`` database, you might use these commands:: +database to the ``new_users`` database, you might use these commands: + +.. code-block:: pycon >>> user_obj.save(using='new_users') >>> user_obj.delete(using='legacy_users') diff --git a/docs/topics/db/optimization.txt b/docs/topics/db/optimization.txt index ca04c8fd55..54d79f1b84 100644 --- a/docs/topics/db/optimization.txt +++ b/docs/topics/db/optimization.txt @@ -82,13 +82,17 @@ Understand cached attributes As well as caching of the whole ``QuerySet``, there is caching of the result of attributes on ORM objects. In general, attributes that are not callable will be cached. For example, assuming the :ref:`example blog models -<queryset-model-example>`:: +<queryset-model-example>`: + +.. code-block:: pycon >>> entry = Entry.objects.get(id=1) >>> entry.blog # Blog object is retrieved at this point >>> entry.blog # cached version, no DB access -But in general, callable attributes cause DB lookups every time:: +But in general, callable attributes cause DB lookups every time: + +.. code-block:: pycon >>> entry = Entry.objects.get(id=1) >>> entry.authors.all() # query performed @@ -164,18 +168,24 @@ First, the query will be quicker because of the underlying database index. Also, the query could run much slower if multiple objects match the lookup; having a unique constraint on the column guarantees this will never happen. -So using the :ref:`example blog models <queryset-model-example>`:: +So using the :ref:`example blog models <queryset-model-example>`: + +.. code-block:: pycon >>> entry = Entry.objects.get(id=10) will be quicker than: +.. code-block:: pycon + >>> entry = Entry.objects.get(headline="News Item Title") because ``id`` is indexed by the database and is guaranteed to be unique. Doing the following is potentially quite slow: +.. code-block:: pycon + >>> entry = Entry.objects.get(headline__startswith="News") First of all, ``headline`` is not indexed, which will make the underlying diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt index 977e287c53..43bdd79966 100644 --- a/docs/topics/db/queries.txt +++ b/docs/topics/db/queries.txt @@ -59,7 +59,9 @@ class represents a particular record in the database table. To create an object, instantiate it using keyword arguments to the model class, then call :meth:`~django.db.models.Model.save` to save it to the database. -Assuming models live in a file ``mysite/blog/models.py``, here's an example:: +Assuming models live in a file ``mysite/blog/models.py``, here's an example: + +.. code-block:: pycon >>> from blog.models import Blog >>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') @@ -86,7 +88,9 @@ To save changes to an object that's already in the database, use :meth:`~django.db.models.Model.save`. Given a ``Blog`` instance ``b5`` that has already been saved to the database, -this example changes its name and updates its record in the database:: +this example changes its name and updates its record in the database: + +.. code-block:: pycon >>> b5.name = 'New name' >>> b5.save() @@ -101,7 +105,9 @@ Updating a :class:`~django.db.models.ForeignKey` field works exactly the same way as saving a normal field -- assign an object of the right type to the field in question. This example updates the ``blog`` attribute of an ``Entry`` instance ``entry``, assuming appropriate instances of ``Entry`` and ``Blog`` -are already saved to the database (so we can retrieve them below):: +are already saved to the database (so we can retrieve them below): + +.. code-block:: pycon >>> from blog.models import Blog, Entry >>> entry = Entry.objects.get(pk=1) @@ -113,7 +119,9 @@ Updating a :class:`~django.db.models.ManyToManyField` works a little differently -- use the :meth:`~django.db.models.fields.related.RelatedManager.add` method on the field to add a record to the relation. This example adds the ``Author`` instance -``joe`` to the ``entry`` object:: +``joe`` to the ``entry`` object: + +.. code-block:: pycon >>> from blog.models import Author >>> joe = Author.objects.create(name="Joe") @@ -121,7 +129,9 @@ to add a record to the relation. This example adds the ``Author`` instance To add multiple records to a :class:`~django.db.models.ManyToManyField` in one go, include multiple arguments in the call to -:meth:`~django.db.models.fields.related.RelatedManager.add`, like this:: +:meth:`~django.db.models.fields.related.RelatedManager.add`, like this: + +.. code-block:: pycon >>> john = Author.objects.create(name="John") >>> paul = Author.objects.create(name="Paul") @@ -150,7 +160,9 @@ You get a :class:`~django.db.models.query.QuerySet` by using your model's :class:`~django.db.models.Manager`. Each model has at least one :class:`~django.db.models.Manager`, and it's called :attr:`~django.db.models.Model.objects` by default. Access it directly via the -model class, like so:: +model class, like so: + +.. code-block:: pycon >>> Blog.objects <django.db.models.manager.Manager object at ...> @@ -176,7 +188,9 @@ Retrieving all objects The simplest way to retrieve objects from a table is to get all of them. To do this, use the :meth:`~django.db.models.query.QuerySet.all` method on a -:class:`~django.db.models.Manager`:: +:class:`~django.db.models.Manager`: + +.. code-block:: pycon >>> all_entries = Entry.objects.all() @@ -223,7 +237,9 @@ Chaining filters The result of refining a :class:`~django.db.models.query.QuerySet` is itself a :class:`~django.db.models.query.QuerySet`, so it's possible to chain -refinements together. For example:: +refinements together. For example: + +.. code-block:: pycon >>> Entry.objects.filter( ... headline__startswith='What' @@ -250,7 +266,9 @@ the previous :class:`~django.db.models.query.QuerySet`. Each refinement creates a separate and distinct :class:`~django.db.models.query.QuerySet` that can be stored, used and reused. -Example:: +Example: + +.. code-block:: pycon >>> q1 = Entry.objects.filter(headline__startswith="What") >>> q2 = q1.exclude(pub_date__gte=datetime.date.today()) @@ -274,7 +292,9 @@ refinement process. :class:`~django.db.models.query.QuerySet` doesn't involve any database activity. You can stack filters together all day long, and Django won't actually run the query until the :class:`~django.db.models.query.QuerySet` is -*evaluated*. Take a look at this example:: +*evaluated*. Take a look at this example: + +.. code-block:: pycon >>> q = Entry.objects.filter(headline__startswith="What") >>> q = q.filter(pub_date__lte=datetime.date.today()) @@ -301,7 +321,9 @@ the query - in this case, it will be a If you know there is only one object that matches your query, you can use the :meth:`~django.db.models.query.QuerySet.get` method on a -:class:`~django.db.models.Manager` which returns the object directly:: +:class:`~django.db.models.Manager` which returns the object directly: + +.. code-block:: pycon >>> one_entry = Entry.objects.get(pk=1) @@ -345,11 +367,15 @@ Use a subset of Python's array-slicing syntax to limit your :class:`~django.db.models.query.QuerySet` to a certain number of results. This is the equivalent of SQL's ``LIMIT`` and ``OFFSET`` clauses. -For example, this returns the first 5 objects (``LIMIT 5``):: +For example, this returns the first 5 objects (``LIMIT 5``): + +.. code-block:: pycon >>> Entry.objects.all()[:5] -This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``):: +This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``): + +.. code-block:: pycon >>> Entry.objects.all()[5:10] @@ -359,7 +385,9 @@ Generally, slicing a :class:`~django.db.models.query.QuerySet` returns a new :class:`~django.db.models.query.QuerySet` -- it doesn't evaluate the query. An exception is if you use the "step" parameter of Python slice syntax. For example, this would actually execute the query in order to return a list of -every *second* object of the first 10:: +every *second* object of the first 10: + +.. code-block:: pycon >>> Entry.objects.all()[:10:2] @@ -369,11 +397,15 @@ ambiguous nature of how that might work. To retrieve a *single* object rather than a list (e.g. ``SELECT foo FROM bar LIMIT 1``), use an index instead of a slice. For example, this returns the first ``Entry`` in the database, after ordering -entries alphabetically by headline:: +entries alphabetically by headline: + +.. code-block:: pycon >>> Entry.objects.order_by('headline')[0] -This is roughly equivalent to:: +This is roughly equivalent to: + +.. code-block:: pycon >>> Entry.objects.order_by('headline')[0:1].get() @@ -393,7 +425,9 @@ methods :meth:`~django.db.models.query.QuerySet.filter`, :meth:`~django.db.models.query.QuerySet.get`. Basic lookups keyword arguments take the form ``field__lookuptype=value``. -(That's a double-underscore). For example:: +(That's a double-underscore). For example: + +.. code-block:: pycon >>> Entry.objects.filter(pub_date__lte='2006-01-01') @@ -426,7 +460,9 @@ a taste of what's available, here's some of the more common lookups you'll probably use: :lookup:`exact` - An "exact" match. For example:: + An "exact" match. For example: + + .. code-block:: pycon >>> Entry.objects.get(headline__exact="Cat bites dog") @@ -440,7 +476,9 @@ probably use: doesn't contain a double underscore -- the lookup type is assumed to be ``exact``. - For example, the following two statements are equivalent:: + For example, the following two statements are equivalent: + + .. code-block:: pycon >>> Blog.objects.get(id__exact=14) # Explicit form >>> Blog.objects.get(id=14) # __exact is implied @@ -448,7 +486,9 @@ probably use: This is for convenience, because ``exact`` lookups are the common case. :lookup:`iexact` - A case-insensitive match. So, the query:: + A case-insensitive match. So, the query: + + .. code-block:: pycon >>> Blog.objects.get(name__iexact="beatles blog") @@ -491,7 +531,9 @@ across models, separated by double underscores, until you get to the field you want. This example retrieves all ``Entry`` objects with a ``Blog`` whose ``name`` -is ``'Beatles Blog'``:: +is ``'Beatles Blog'``: + +.. code-block:: pycon >>> Entry.objects.filter(blog__name='Beatles Blog') @@ -502,7 +544,9 @@ It works backwards, too. While it :attr:`can be customized relationship in a lookup using the lowercase name of the model. This example retrieves all ``Blog`` objects which have at least one ``Entry`` -whose ``headline`` contains ``'Lennon'``:: +whose ``headline`` contains ``'Lennon'``: + +.. code-block:: pycon >>> Blog.objects.filter(entry__headline__contains='Lennon') @@ -649,7 +693,9 @@ of two different fields on the same model instance. For example, to find a list of all blog entries that have had more comments than pingbacks, we construct an ``F()`` object to reference the pingback count, -and use that ``F()`` object in the query:: +and use that ``F()`` object in the query: + +.. code-block:: pycon >>> from django.db.models import F >>> Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks')) @@ -657,13 +703,17 @@ and use that ``F()`` object in the query:: Django supports the use of addition, subtraction, multiplication, division, modulo, and power arithmetic with ``F()`` objects, both with constants and with other ``F()`` objects. To find all the blog entries with more than -*twice* as many comments as pingbacks, we modify the query:: +*twice* as many comments as pingbacks, we modify the query: + +.. code-block:: pycon >>> Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks') * 2) To find all the entries where the rating of the entry is less than the sum of the pingback count and comment count, we would issue the -query:: +query: + +.. code-block:: pycon >>> Entry.objects.filter(rating__lt=F('number_of_comments') + F('number_of_pingbacks')) @@ -671,19 +721,25 @@ You can also use the double underscore notation to span relationships in an ``F()`` object. An ``F()`` object with a double underscore will introduce any joins needed to access the related object. For example, to retrieve all the entries where the author's name is the same as the blog name, we could -issue the query:: +issue the query: + +.. code-block:: pycon >>> Entry.objects.filter(authors__name=F('blog__name')) For date and date/time fields, you can add or subtract a :class:`~datetime.timedelta` object. The following would return all entries -that were modified more than 3 days after they were published:: +that were modified more than 3 days after they were published: + +.. code-block:: pycon >>> from datetime import timedelta >>> Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3)) The ``F()`` objects support bitwise operations by ``.bitand()``, ``.bitor()``, -``.bitxor()``, ``.bitrightshift()``, and ``.bitleftshift()``. For example:: +``.bitxor()``, ``.bitrightshift()``, and ``.bitleftshift()``. For example: + +.. code-block:: pycon >>> F('somefield').bitand(16) @@ -699,18 +755,24 @@ Expressions can reference transforms Django supports using transforms in expressions. For example, to find all ``Entry`` objects published in the same year as they -were last modified:: +were last modified: + +.. code-block:: pycon >>> from django.db.models import F >>> Entry.objects.filter(pub_date__year=F('mod_date__year')) -To find the earliest year an entry was published, we can issue the query:: +To find the earliest year an entry was published, we can issue the query: + +.. code-block:: pycon >>> from django.db.models import Min >>> Entry.objects.aggregate(first_published_year=Min('pub_date__year')) This example finds the value of the highest rated entry and the total number -of comments on all entries for each year:: +of comments on all entries for each year: + +.. code-block:: pycon >>> from django.db.models import OuterRef, Subquery, Sum >>> Entry.objects.values('pub_date__year').annotate( @@ -729,14 +791,18 @@ For convenience, Django provides a ``pk`` lookup shortcut, which stands for "primary key". In the example ``Blog`` model, the primary key is the ``id`` field, so these -three statements are equivalent:: +three statements are equivalent: + +.. code-block:: pycon >>> Blog.objects.get(id__exact=14) # Explicit form >>> Blog.objects.get(id=14) # __exact is implied >>> Blog.objects.get(pk=14) # pk implies id__exact The use of ``pk`` isn't limited to ``__exact`` queries -- any query term -can be combined with ``pk`` to perform a query on the primary key of a model:: +can be combined with ``pk`` to perform a query on the primary key of a model: + +.. code-block:: pycon # Get blogs entries with id 1, 4 and 7 >>> Blog.objects.filter(pk__in=[1,4,7]) @@ -745,7 +811,9 @@ can be combined with ``pk`` to perform a query on the primary key of a model:: >>> Blog.objects.filter(pk__gt=14) ``pk`` lookups also work across joins. For example, these three statements are -equivalent:: +equivalent: + +.. code-block:: pycon >>> Entry.objects.filter(blog__id__exact=3) # Explicit form >>> Entry.objects.filter(blog__id=3) # __exact is implied @@ -763,7 +831,9 @@ underscore signifies a single-character wildcard.) This means things should work intuitively, so the abstraction doesn't leak. For example, to retrieve all the entries that contain a percent sign, use the -percent sign as any other character:: +percent sign as any other character: + +.. code-block:: pycon >>> Entry.objects.filter(headline__contains='%') @@ -798,7 +868,9 @@ results. Keep this caching behavior in mind, because it may bite you if you don't use your :class:`~django.db.models.query.QuerySet`\s correctly. For example, the following will create two :class:`~django.db.models.query.QuerySet`\s, evaluate -them, and throw them away:: +them, and throw them away: + +.. code-block:: pycon >>> print([e.headline for e in Entry.objects.all()]) >>> print([e.pub_date for e in Entry.objects.all()]) @@ -809,7 +881,9 @@ the same database records, because an ``Entry`` may have been added or deleted in the split second between the two requests. To avoid this problem, save the :class:`~django.db.models.query.QuerySet` and -reuse it:: +reuse it: + +.. code-block:: pycon >>> queryset = Entry.objects.all() >>> print([p.headline for p in queryset]) # Evaluate the query set. @@ -825,14 +899,18 @@ returned by the subsequent query are not cached. Specifically, this means that index will not populate the cache. For example, repeatedly getting a certain index in a queryset object will query -the database each time:: +the database each time: + +.. code-block:: pycon >>> queryset = Entry.objects.all() >>> print(queryset[5]) # Queries the database >>> print(queryset[5]) # Queries the database again However, if the entire queryset has already been evaluated, the cache will be -checked instead:: +checked instead: + +.. code-block:: pycon >>> queryset = Entry.objects.all() >>> [entry for entry in queryset] # Queries the database @@ -840,7 +918,9 @@ checked instead:: >>> print(queryset[5]) # Uses cache Here are some examples of other actions that will result in the entire queryset -being evaluated and therefore populate the cache:: +being evaluated and therefore populate the cache: + +.. code-block:: pycon >>> [entry for entry in queryset] >>> bool(queryset) @@ -983,7 +1063,9 @@ is inside a :py:class:`list` or :py:class:`dict`, it will always be interpreted as JSON ``null``. When querying, ``None`` value will always be interpreted as JSON ``null``. To -query for SQL ``NULL``, use :lookup:`isnull`:: +query for SQL ``NULL``, use :lookup:`isnull`: + +.. code-block:: pycon >>> Dog.objects.create(name='Max', data=None) # SQL NULL. <Dog: Max> @@ -1023,7 +1105,9 @@ Unless you are sure you wish to work with SQL ``NULL`` values, consider setting Key, index, and path transforms ------------------------------- -To query based on a given dictionary key, use that key as the lookup name:: +To query based on a given dictionary key, use that key as the lookup name: + +.. code-block:: pycon >>> Dog.objects.create(name='Rufus', data={ ... 'breed': 'labrador', @@ -1040,13 +1124,17 @@ To query based on a given dictionary key, use that key as the lookup name:: >>> Dog.objects.filter(data__breed='collie') <QuerySet [<Dog: Meg>]> -Multiple keys can be chained together to form a path lookup:: +Multiple keys can be chained together to form a path lookup: + +.. code-block:: pycon >>> Dog.objects.filter(data__owner__name='Bob') <QuerySet [<Dog: Rufus>]> If the key is an integer, it will be interpreted as an index transform in an -array:: +array: + +.. code-block:: pycon >>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy') <QuerySet [<Dog: Rufus>]> @@ -1054,7 +1142,9 @@ array:: If the key you wish to query by clashes with the name of another lookup, use the :lookup:`contains <jsonfield.contains>` lookup instead. -To query for missing keys, use the ``isnull`` lookup:: +To query for missing keys, use the ``isnull`` lookup: + +.. code-block:: pycon >>> Dog.objects.create(name='Shep', data={'breed': 'collie'}) <Dog: Shep> @@ -1083,7 +1173,9 @@ To query for missing keys, use the ``isnull`` lookup:: :class:`~django.db.models.JSONField`. You can use the double underscore notation in ``lookup`` to chain dictionary key and index transforms. - For example:: + For example: + + .. code-block:: pycon >>> from django.db.models.fields.json import KT >>> Dog.objects.create(name="Shep", data={ @@ -1150,7 +1242,9 @@ Containment and key lookups The :lookup:`contains` lookup is overridden on ``JSONField``. The returned objects are those where the given ``dict`` of key-value pairs are all -contained in the top-level of the field. For example:: +contained in the top-level of the field. For example: + +.. code-block:: pycon >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'}) <Dog: Rufus> @@ -1174,7 +1268,9 @@ contained in the top-level of the field. For example:: This is the inverse of the :lookup:`contains <jsonfield.contains>` lookup - the objects returned will be those where the key-value pairs on the object are a -subset of those in the value passed. For example:: +subset of those in the value passed. For example: + +.. code-block:: pycon >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'}) <Dog: Rufus> @@ -1197,7 +1293,9 @@ subset of those in the value passed. For example:: ~~~~~~~~~~~ Returns objects where the given key is in the top-level of the data. For -example:: +example: + +.. code-block:: pycon >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'}) <Dog: Rufus> @@ -1212,7 +1310,9 @@ example:: ~~~~~~~~~~~~ Returns objects where all of the given keys are in the top-level of the data. -For example:: +For example: + +.. code-block:: pycon >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'}) <Dog: Rufus> @@ -1227,7 +1327,9 @@ For example:: ~~~~~~~~~~~~~~~~ Returns objects where any of the given keys are in the top-level of the data. -For example:: +For example: + +.. code-block:: pycon >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'}) <Dog: Rufus> @@ -1330,14 +1432,18 @@ To compare two model instances, use the standard Python comparison operator, the double equals sign: ``==``. Behind the scenes, that compares the primary key values of two models. -Using the ``Entry`` example above, the following two statements are equivalent:: +Using the ``Entry`` example above, the following two statements are equivalent: + +.. code-block:: pycon >>> some_entry == other_entry >>> some_entry.id == other_entry.id If a model's primary key isn't called ``id``, no problem. Comparisons will always use the primary key, whatever it's called. For example, if a model's -primary key field is called ``name``, these two statements are equivalent:: +primary key field is called ``name``, these two statements are equivalent: + +.. code-block:: pycon >>> some_obj == other_obj >>> some_obj.name == other_obj.name @@ -1350,7 +1456,9 @@ Deleting objects The delete method, conveniently, is named :meth:`~django.db.models.Model.delete`. This method immediately deletes the object and returns the number of objects deleted and a dictionary with -the number of deletions per object type. Example:: +the number of deletions per object type. Example: + +.. code-block:: pycon >>> e.delete() (1, {'blog.Entry': 1}) @@ -1361,7 +1469,9 @@ You can also delete objects in bulk. Every members of that :class:`~django.db.models.query.QuerySet`. For example, this deletes all ``Entry`` objects with a ``pub_date`` year of -2005:: +2005: + +.. code-block:: pycon >>> Entry.objects.filter(pub_date__year=2005).delete() (5, {'webapp.Entry': 5}) @@ -1470,7 +1580,9 @@ a :class:`~django.db.models.query.QuerySet`. You can do this with the You can only set non-relation fields and :class:`~django.db.models.ForeignKey` fields using this method. To update a non-relation field, provide the new value as a constant. To update :class:`~django.db.models.ForeignKey` fields, set the -new value to be the new model instance you want to point to. For example:: +new value to be the new model instance you want to point to. For example: + +.. code-block:: pycon >>> b = Blog.objects.get(pk=1) @@ -1483,7 +1595,9 @@ some rows already have the new value). The only restriction on the :class:`~django.db.models.query.QuerySet` being updated is that it can only access one database table: the model's main table. You can filter based on related fields, but you can only update columns in the model's main -table. Example:: +table. Example: + +.. code-block:: pycon >>> b = Blog.objects.get(pk=1) @@ -1507,14 +1621,18 @@ them and call :meth:`~django.db.models.Model.save`:: Calls to update can also use :class:`F expressions <django.db.models.F>` to update one field based on the value of another field in the model. This is especially useful for incrementing counters based upon their current value. For -example, to increment the pingback count for every entry in the blog:: +example, to increment the pingback count for every entry in the blog: + +.. code-block:: pycon >>> Entry.objects.update(number_of_pingbacks=F('number_of_pingbacks') + 1) However, unlike ``F()`` objects in filter and exclude clauses, you can't introduce joins when you use ``F()`` objects in an update -- you can only reference fields local to the model being updated. If you attempt to introduce -a join with an ``F()`` object, a ``FieldError`` will be raised:: +a join with an ``F()`` object, a ``FieldError`` will be raised: + +.. code-block:: pycon # This will raise a FieldError >>> Entry.objects.update(headline=F('blog__name')) @@ -1555,14 +1673,18 @@ Forward If a model has a :class:`~django.db.models.ForeignKey`, instances of that model will have access to the related (foreign) object via an attribute of the model. -Example:: +Example: + +.. code-block:: pycon >>> e = Entry.objects.get(id=2) >>> e.blog # Returns the related Blog object. You can get and set via a foreign-key attribute. As you may expect, changes to the foreign key aren't saved to the database until you call -:meth:`~django.db.models.Model.save`. Example:: +:meth:`~django.db.models.Model.save`. Example: + +.. code-block:: pycon >>> e = Entry.objects.get(id=2) >>> e.blog = some_blog @@ -1570,7 +1692,9 @@ the foreign key aren't saved to the database until you call If a :class:`~django.db.models.ForeignKey` field has ``null=True`` set (i.e., it allows ``NULL`` values), you can assign ``None`` to remove the relation. -Example:: +Example: + +.. code-block:: pycon >>> e = Entry.objects.get(id=2) >>> e.blog = None @@ -1578,7 +1702,9 @@ Example:: Forward access to one-to-many relationships is cached the first time the related object is accessed. Subsequent accesses to the foreign key on the same -object instance are cached. Example:: +object instance are cached. Example: + +.. code-block:: pycon >>> e = Entry.objects.get(id=2) >>> print(e.blog) # Hits the database to retrieve the associated Blog. @@ -1586,7 +1712,9 @@ object instance are cached. Example:: Note that the :meth:`~django.db.models.query.QuerySet.select_related` :class:`~django.db.models.query.QuerySet` method recursively prepopulates the -cache of all one-to-many relationships ahead of time. Example:: +cache of all one-to-many relationships ahead of time. Example: + +.. code-block:: pycon >>> e = Entry.objects.select_related().get(id=2) >>> print(e.blog) # Doesn't hit the database; uses cached version. @@ -1605,7 +1733,9 @@ source model name, lowercased. This :class:`~django.db.models.Manager` returns ``QuerySets``, which can be filtered and manipulated as described in the "Retrieving objects" section above. -Example:: +Example: + +.. code-block:: pycon >>> b = Blog.objects.get(id=1) >>> b.entry_set.all() # Returns all Entry objects related to Blog. @@ -1618,7 +1748,9 @@ You can override the ``FOO_set`` name by setting the :attr:`~django.db.models.ForeignKey.related_name` parameter in the :class:`~django.db.models.ForeignKey` definition. For example, if the ``Entry`` model was altered to ``blog = ForeignKey(Blog, on_delete=models.CASCADE, -related_name='entries')``, the above example code would look like this:: +related_name='entries')``, the above example code would look like this: + +.. code-block:: pycon >>> b = Blog.objects.get(id=1) >>> b.entries.all() # Returns all Entry objects related to Blog. diff --git a/docs/topics/db/search.txt b/docs/topics/db/search.txt index 1c4ccca81e..f3c7d24a2f 100644 --- a/docs/topics/db/search.txt +++ b/docs/topics/db/search.txt @@ -17,7 +17,9 @@ Standard textual queries ------------------------ Text-based fields have a selection of matching operations. For example, you may -wish to allow lookup up an author like so:: +wish to allow lookup up an author like so: + +.. code-block:: pycon >>> Author.objects.filter(name__contains='Terry') [<Author: Terry Gilliam>, <Author: Terry Jones>] @@ -47,7 +49,9 @@ demonstrate the kind of functionality databases may have. In the above example, we determined that a case insensitive lookup would be more useful. When dealing with non-English names, a further improvement is to -use :lookup:`unaccented comparison <unaccent>`:: +use :lookup:`unaccented comparison <unaccent>`: + +.. code-block:: pycon >>> Author.objects.filter(name__unaccent__icontains='Helen') [<Author: Helen Mirren>, <Author: Helena Bonham Carter>, <Author: Hélène Joy>] @@ -58,7 +62,9 @@ will pick up ``Helena`` or ``Hélène``, but not the reverse. Another option would be to use a :lookup:`trigram_similar` comparison, which compares sequences of letters. -For example:: +For example: + +.. code-block:: pycon >>> Author.objects.filter(name__unaccent__lower__trigram_similar='Hélène') [<Author: Helen Mirren>, <Author: Hélène Joy>] @@ -110,12 +116,16 @@ as categorization. The :mod:`django.contrib.postgres` module provides some helpers to make these queries. For example, a query might select all the blog entries which mention -"cheese":: +"cheese": + +.. code-block:: pycon >>> Entry.objects.filter(body_text__search='cheese') [<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>] -You can also filter on a combination of fields and on related models:: +You can also filter on a combination of fields and on related models: + +.. code-block:: pycon >>> Entry.objects.annotate( ... search=SearchVector('blog__tagline', 'body_text'), diff --git a/docs/topics/db/sql.txt b/docs/topics/db/sql.txt index 93f7724774..6a76d5b0c8 100644 --- a/docs/topics/db/sql.txt +++ b/docs/topics/db/sql.txt @@ -56,7 +56,9 @@ This is best illustrated with an example. Suppose you have the following model:: last_name = models.CharField(...) birth_date = models.DateField(...) -You could then execute custom SQL like so:: +You could then execute custom SQL like so: + +.. code-block:: pycon >>> for p in Person.objects.raw('SELECT * FROM myapp_person'): ... print(p) @@ -104,7 +106,9 @@ Mapping query fields to model fields ``raw()`` automatically maps fields in the query to fields on the model. The order of fields in your query doesn't matter. In other words, both -of the following queries work identically:: +of the following queries work identically: + +.. code-block:: pycon >>> Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person') ... @@ -113,7 +117,9 @@ of the following queries work identically:: Matching is done by name. This means that you can use SQL's ``AS`` clauses to map fields in the query to model fields. So if you had some other table that -had ``Person`` data in it, you could easily map it into ``Person`` instances:: +had ``Person`` data in it, you could easily map it into ``Person`` instances: + +.. code-block:: pycon >>> Person.objects.raw('''SELECT first AS first_name, ... last AS last_name, @@ -126,7 +132,9 @@ As long as the names match, the model instances will be created correctly. Alternatively, you can map fields in the query to model fields using the ``translations`` argument to ``raw()``. This is a dictionary mapping names of fields in the query to names of fields on the model. For example, the above -query could also be written:: +query could also be written: + +.. code-block:: pycon >>> name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'} >>> Person.objects.raw('SELECT * FROM some_other_table', translations=name_map) @@ -135,26 +143,34 @@ Index lookups ------------- ``raw()`` supports indexing, so if you need only the first result you can -write:: +write: + +.. code-block:: pycon >>> first_person = Person.objects.raw('SELECT * FROM myapp_person')[0] However, the indexing and slicing are not performed at the database level. If you have a large number of ``Person`` objects in your database, it is more -efficient to limit the query at the SQL level:: +efficient to limit the query at the SQL level: + +.. code-block:: pycon >>> first_person = Person.objects.raw('SELECT * FROM myapp_person LIMIT 1')[0] Deferring model fields ---------------------- -Fields may also be left out:: +Fields may also be left out: + +.. code-block:: pycon >>> people = Person.objects.raw('SELECT id, first_name FROM myapp_person') The ``Person`` objects returned by this query will be deferred model instances (see :meth:`~django.db.models.query.QuerySet.defer()`). This means that the -fields that are omitted from the query will be loaded on demand. For example:: +fields that are omitted from the query will be loaded on demand. For example: + +.. code-block:: pycon >>> for p in Person.objects.raw('SELECT id, first_name FROM myapp_person'): ... print(p.first_name, # This will be retrieved by the original query @@ -179,7 +195,9 @@ Adding annotations You can also execute queries containing fields that aren't defined on the model. For example, we could use `PostgreSQL's age() function`__ to get a list -of people with their ages calculated by the database:: +of people with their ages calculated by the database: + +.. code-block:: pycon >>> people = Person.objects.raw('SELECT *, age(birth_date) AS age FROM myapp_person') >>> for p in people: @@ -197,7 +215,9 @@ Passing parameters into ``raw()`` --------------------------------- If you need to perform parameterized queries, you can use the ``params`` -argument to ``raw()``:: +argument to ``raw()``: + +.. code-block:: pycon >>> lname = 'Doe' >>> Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname]) @@ -218,13 +238,17 @@ replaced with parameters from the ``params`` argument. **Do not use string formatting on raw queries or quote placeholders in your SQL strings!** - It's tempting to write the above query as:: + It's tempting to write the above query as: + + .. code-block:: pycon >>> query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname >>> Person.objects.raw(query) You might also think you should write your query like this (with quotes - around ``%s``):: + around ``%s``): + + .. code-block:: pycon >>> query = "SELECT * FROM myapp_person WHERE last_name = '%s'" @@ -313,7 +337,9 @@ immutable and accessible by field names or indices, which might be useful:: nt_result = namedtuple('Result', [col[0] for col in desc]) return [nt_result(*row) for row in cursor.fetchall()] -Here is an example of the difference between the three:: +Here is an example of the difference between the three: + +.. code-block:: pycon >>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2") >>> cursor.fetchall() diff --git a/docs/topics/email.txt b/docs/topics/email.txt index 2005bbd19b..5a0a3e6c22 100644 --- a/docs/topics/email.txt +++ b/docs/topics/email.txt @@ -672,7 +672,9 @@ to a file that can be inspected at your leisure. Another approach is to use a "dumb" SMTP server that receives the emails locally and displays them to the terminal, but does not actually send -anything. The `aiosmtpd`_ package provides a way to accomplish this:: +anything. The `aiosmtpd`_ package provides a way to accomplish this: + +.. code-block:: shell python -m pip install aiosmtpd diff --git a/docs/topics/files.txt b/docs/topics/files.txt index ad0dcffdd1..2c31a61dfc 100644 --- a/docs/topics/files.txt +++ b/docs/topics/files.txt @@ -36,7 +36,9 @@ store a photo:: specs = models.FileField(upload_to='specs') Any ``Car`` instance will have a ``photo`` attribute that you can use to get at -the details of the attached photo:: +the details of the attached photo: + +.. code-block:: pycon >>> car = Car.objects.get(name="57 Chevy") >>> car.photo @@ -59,7 +61,9 @@ it has all the methods and attributes described below. For example, you can change the file name by setting the file's :attr:`~django.core.files.File.name` to a path relative to the file storage's location (:setting:`MEDIA_ROOT` if you are using the default -:class:`~django.core.files.storage.FileSystemStorage`):: +:class:`~django.core.files.storage.FileSystemStorage`): + +.. code-block:: pycon >>> import os >>> from django.conf import settings @@ -74,7 +78,9 @@ location (:setting:`MEDIA_ROOT` if you are using the default >>> car.photo.path == new_path True -To save an existing file on disk to a :class:`~django.db.models.FileField`:: +To save an existing file on disk to a :class:`~django.db.models.FileField`: + +.. code-block:: pycon >>> from pathlib import Path >>> from django.core.files import File @@ -89,7 +95,9 @@ To save an existing file on disk to a :class:`~django.db.models.FileField`:: While :class:`~django.db.models.ImageField` non-image data attributes, such as ``height``, ``width``, and ``size`` are available on the instance, the underlying image data cannot be used without reopening the image. For - example:: + example: + + .. code-block:: pycon >>> from PIL import Image >>> car = Car.objects.get(name='57 Chevy') @@ -115,7 +123,9 @@ Most of the time you'll use a ``File`` that Django's given you (i.e. a file attached to a model as above, or perhaps an uploaded file). If you need to construct a ``File`` yourself, the easiest way is to create one -using a Python built-in ``file`` object:: +using a Python built-in ``file`` object: + +.. code-block:: pycon >>> from django.core.files import File @@ -127,7 +137,9 @@ Now you can use any of the documented attributes and methods of the :class:`~django.core.files.File` class. Be aware that files created in this way are not automatically closed. -The following approach may be used to close files automatically:: +The following approach may be used to close files automatically: + +.. code-block:: pycon >>> from django.core.files import File @@ -144,7 +156,9 @@ The following approach may be used to close files automatically:: Closing files is especially important when accessing file fields in a loop over a large number of objects. If files are not manually closed after accessing them, the risk of running out of file descriptors may arise. This -may lead to the following error:: +may lead to the following error: + +.. code-block:: pytb OSError: [Errno 24] Too many open files @@ -171,7 +185,9 @@ Storage objects Though most of the time you'll want to use a ``File`` object (which delegates to the proper storage for that file), you can use file storage systems directly. You can create an instance of some custom file storage class, or -- often more -useful -- you can use the global default storage system:: +useful -- you can use the global default storage system: + +.. code-block:: pycon >>> from django.core.files.base import ContentFile >>> from django.core.files.storage import default_storage diff --git a/docs/topics/forms/formsets.txt b/docs/topics/forms/formsets.txt index 1624c380a1..47506e8eca 100644 --- a/docs/topics/forms/formsets.txt +++ b/docs/topics/forms/formsets.txt @@ -8,7 +8,9 @@ Formsets A formset is a layer of abstraction to work with multiple forms on the same page. It can be best compared to a data grid. Let's say you have the following -form:: +form: + +.. code-block:: pycon >>> from django import forms >>> class ArticleForm(forms.Form): @@ -16,14 +18,18 @@ form:: ... pub_date = forms.DateField() You might want to allow the user to create several articles at once. To create -a formset out of an ``ArticleForm`` you would do:: +a formset out of an ``ArticleForm`` you would do: + +.. code-block:: pycon >>> from django.forms import formset_factory >>> ArticleFormSet = formset_factory(ArticleForm) You now have created a formset class named ``ArticleFormSet``. Instantiating the formset gives you the ability to iterate over the forms -in the formset and display them as you would with a regular form:: +in the formset and display them as you would with a regular form: + +.. code-block:: pycon >>> formset = ArticleFormSet() >>> for form in formset: @@ -34,7 +40,9 @@ in the formset and display them as you would with a regular form:: As you can see it only displayed one empty form. The number of empty forms that is displayed is controlled by the ``extra`` parameter. By default, :func:`~django.forms.formsets.formset_factory` defines one extra form; the -following example will create a formset class to display two blank forms:: +following example will create a formset class to display two blank forms: + +.. code-block:: pycon >>> ArticleFormSet = formset_factory(ArticleForm, extra=2) @@ -55,7 +63,9 @@ Initial data is what drives the main usability of a formset. As shown above you can define the number of extra forms. What this means is that you are telling the formset how many additional forms to show in addition to the number of forms it generates from the initial data. Let's take a look at an -example:: +example: + +.. code-block:: pycon >>> import datetime >>> from django.forms import formset_factory @@ -94,7 +104,9 @@ Limiting the maximum number of forms ==================================== The ``max_num`` parameter to :func:`~django.forms.formsets.formset_factory` -gives you the ability to limit the number of forms the formset will display:: +gives you the ability to limit the number of forms the formset will display: + +.. code-block:: pycon >>> from django.forms import formset_factory >>> from myapp.forms import ArticleForm @@ -133,7 +145,9 @@ Limiting the maximum number of instantiated forms The ``absolute_max`` parameter to :func:`.formset_factory` allows limiting the number of forms that can be instantiated when supplying ``POST`` data. This -protects against memory exhaustion attacks using forged ``POST`` requests:: +protects against memory exhaustion attacks using forged ``POST`` requests: + +.. code-block:: pycon >>> from django.forms.formsets import formset_factory >>> from myapp.forms import ArticleForm @@ -160,7 +174,9 @@ Formset validation Validation with a formset is almost identical to a regular ``Form``. There is an ``is_valid`` method on the formset to provide a convenient way to validate -all forms in the formset:: +all forms in the formset: + +.. code-block:: pycon >>> from django.forms import formset_factory >>> from myapp.forms import ArticleForm @@ -175,7 +191,9 @@ all forms in the formset:: We passed in no data to the formset which is resulting in a valid form. The formset is smart enough to ignore extra forms that were not changed. If we -provide an invalid article:: +provide an invalid article: + +.. code-block:: pycon >>> data = { ... 'form-TOTAL_FORMS': '2', @@ -203,7 +221,9 @@ validation may be incorrect when adding and deleting forms. .. method:: BaseFormSet.total_error_count() To check how many errors there are in the formset, we can use the -``total_error_count`` method:: +``total_error_count`` method: + +.. code-block:: pycon >>> # Using the previous example >>> formset.errors @@ -214,7 +234,9 @@ To check how many errors there are in the formset, we can use the 1 We can also check if form data differs from the initial data (i.e. the form was -sent without any data):: +sent without any data): + +.. code-block:: pycon >>> data = { ... 'form-TOTAL_FORMS': '1', @@ -235,7 +257,9 @@ You may have noticed the additional data (``form-TOTAL_FORMS``, ``form-INITIAL_FORMS``) that was required in the formset's data above. This data is required for the ``ManagementForm``. This form is used by the formset to manage the collection of forms contained in the formset. If you don't -provide this management data, the formset will be invalid:: +provide this management data, the formset will be invalid: + +.. code-block:: pycon >>> data = { ... 'form-0-title': 'Test', @@ -301,7 +325,9 @@ you want to override. Error message keys include ``'too_few_forms'``, respectively. For example, here is the default error message when the -management form is missing:: +management form is missing: + +.. code-block:: pycon >>> formset = ArticleFormSet({}) >>> formset.is_valid() @@ -309,7 +335,9 @@ management form is missing:: >>> formset.non_form_errors() ['ManagementForm data is missing or has been tampered with. Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS. You may need to file a bug report if the issue persists.'] -And here is a custom error message:: +And here is a custom error message: + +.. code-block:: pycon >>> formset = ArticleFormSet({}, error_messages={'missing_management_form': 'Sorry, something went wrong.'}) >>> formset.is_valid() @@ -325,7 +353,9 @@ Custom formset validation ------------------------- A formset has a ``clean`` method similar to the one on a ``Form`` class. This -is where you define your own validation that works at the formset level:: +is where you define your own validation that works at the formset level: + +.. code-block:: pycon >>> from django.core.exceptions import ValidationError >>> from django.forms import BaseFormSet @@ -479,7 +509,9 @@ formsets and deletion of forms from a formset. Default: ``False`` -Lets you create a formset with the ability to order:: +Lets you create a formset with the ability to order: + +.. code-block:: pycon >>> from django.forms import formset_factory >>> from myapp.forms import ArticleForm @@ -503,7 +535,9 @@ Lets you create a formset with the ability to order:: This adds an additional field to each form. This new field is named ``ORDER`` and is an ``forms.IntegerField``. For the forms that came from the initial data it automatically assigned them a numeric value. Let's look at what will -happen when the user changes these values:: +happen when the user changes these values: + +.. code-block:: pycon >>> data = { ... 'form-TOTAL_FORMS': '3', @@ -545,7 +579,9 @@ control the widget used with Default: :class:`~django.forms.NumberInput` Set ``ordering_widget`` to specify the widget class to be used with -``can_order``:: +``can_order``: + +.. code-block:: pycon >>> from django.forms import BaseFormSet, formset_factory >>> from myapp.forms import ArticleForm @@ -560,7 +596,9 @@ Set ``ordering_widget`` to specify the widget class to be used with .. method:: BaseFormSet.get_ordering_widget() Override ``get_ordering_widget()`` if you need to provide a widget instance for -use with ``can_order``:: +use with ``can_order``: + +.. code-block:: pycon >>> from django.forms import BaseFormSet, formset_factory >>> from myapp.forms import ArticleForm @@ -577,7 +615,9 @@ use with ``can_order``:: Default: ``False`` -Lets you create a formset with the ability to select forms for deletion:: +Lets you create a formset with the ability to select forms for deletion: + +.. code-block:: pycon >>> from django.forms import formset_factory >>> from myapp.forms import ArticleForm @@ -600,7 +640,9 @@ Lets you create a formset with the ability to select forms for deletion:: Similar to ``can_order`` this adds a new field to each form named ``DELETE`` and is a ``forms.BooleanField``. When data comes through marking any of the -delete fields you can access them with ``deleted_forms``:: +delete fields you can access them with ``deleted_forms``: + +.. code-block:: pycon >>> data = { ... 'form-TOTAL_FORMS': '3', @@ -631,7 +673,9 @@ If you call ``formset.save(commit=False)``, objects will not be deleted automatically. You'll need to call ``delete()`` on each of the :attr:`formset.deleted_objects <django.forms.models.BaseModelFormSet.deleted_objects>` to actually delete -them:: +them: + +.. code-block:: pycon >>> instances = formset.save(commit=False) >>> for obj in formset.deleted_objects: @@ -655,7 +699,9 @@ control the widget used with Default: :class:`~django.forms.CheckboxInput` Set ``deletion_widget`` to specify the widget class to be used with -``can_delete``:: +``can_delete``: + +.. code-block:: pycon >>> from django.forms import BaseFormSet, formset_factory >>> from myapp.forms import ArticleForm @@ -670,7 +716,9 @@ Set ``deletion_widget`` to specify the widget class to be used with .. method:: BaseFormSet.get_deletion_widget() Override ``get_deletion_widget()`` if you need to provide a widget instance for -use with ``can_delete``:: +use with ``can_delete``: + +.. code-block:: pycon >>> from django.forms import BaseFormSet, formset_factory >>> from myapp.forms import ArticleForm @@ -696,7 +744,9 @@ Adding additional fields to a formset If you need to add additional fields to the formset this can be easily accomplished. The formset base class provides an ``add_fields`` method. You can override this method to add your own fields or even redefine the default -fields/attributes of the order and deletion fields:: +fields/attributes of the order and deletion fields: + +.. code-block:: pycon >>> from django.forms import BaseFormSet >>> from django.forms import formset_factory @@ -720,7 +770,9 @@ Passing custom parameters to formset forms ========================================== Sometimes your form class takes custom parameters, like ``MyArticleForm``. -You can pass this parameter when instantiating the formset:: +You can pass this parameter when instantiating the formset: + +.. code-block:: pycon >>> from django.forms import BaseFormSet >>> from django.forms import formset_factory @@ -737,7 +789,9 @@ You can pass this parameter when instantiating the formset:: The ``form_kwargs`` may also depend on the specific form instance. The formset base class provides a ``get_form_kwargs`` method. The method takes a single argument - the index of the form in the formset. The index is ``None`` for the -:ref:`empty_form`:: +:ref:`empty_form`: + +.. code-block:: pycon >>> from django.forms import BaseFormSet >>> from django.forms import formset_factory diff --git a/docs/topics/forms/index.txt b/docs/topics/forms/index.txt index 464c6b86cb..e753a0a74c 100644 --- a/docs/topics/forms/index.txt +++ b/docs/topics/forms/index.txt @@ -748,7 +748,9 @@ Useful attributes on ``{{ field }}`` include: ``{{ field.label_tag }}`` The field's label wrapped in the appropriate HTML ``<label>`` tag. This includes the form's :attr:`~django.forms.Form.label_suffix`. For example, - the default ``label_suffix`` is a colon:: + the default ``label_suffix`` is a colon: + + .. code-block:: html+django <label for="id_email">Email address:</label> diff --git a/docs/topics/forms/media.txt b/docs/topics/forms/media.txt index 801d233244..750f7daa5e 100644 --- a/docs/topics/forms/media.txt +++ b/docs/topics/forms/media.txt @@ -67,7 +67,9 @@ to include the CSS file ``pretty.css``, and the JavaScript files This static definition is converted at runtime into a widget property named ``media``. The list of assets for a ``CalendarWidget`` instance -can be retrieved through this property:: +can be retrieved through this property: + +.. code-block:: pycon >>> w = CalendarWidget() >>> print(w.media) @@ -112,7 +114,9 @@ requirements:: 'print': ['newspaper.css], } -If this last CSS definition were to be rendered, it would become the following HTML:: +If this last CSS definition were to be rendered, it would become the following HTML: + +.. code-block:: html+django <link href="http://static.example.com/pretty.css" media="screen" rel="stylesheet"> <link href="http://static.example.com/lo_res.css" media="tv,projector" rel="stylesheet"> @@ -139,7 +143,9 @@ By default, any object using a static ``Media`` definition will inherit all the assets associated with the parent widget. This occurs regardless of how the parent defines its own requirements. For example, if we were to extend our basic Calendar widget from the -example above:: +example above: + +.. code-block:: pycon >>> class FancyCalendarWidget(CalendarWidget): ... class Media: @@ -158,7 +164,9 @@ example above:: The FancyCalendar widget inherits all the assets from its parent widget. If you don't want ``Media`` to be inherited in this way, add -an ``extend=False`` declaration to the ``Media`` declaration:: +an ``extend=False`` declaration to the ``Media`` declaration: + +.. code-block:: pycon >>> class FancyCalendarWidget(CalendarWidget): ... class Media: @@ -224,7 +232,9 @@ To find the appropriate prefix to use, Django will check if the :setting:`STATIC_URL` setting is not ``None`` and automatically fall back to using :setting:`MEDIA_URL`. For example, if the :setting:`MEDIA_URL` for your site was ``'http://uploads.example.com/'`` and :setting:`STATIC_URL` -was ``None``:: +was ``None``: + +.. code-block:: pycon >>> from django import forms >>> class CalendarWidget(forms.TextInput): @@ -240,7 +250,9 @@ was ``None``:: <script src="http://uploads.example.com/animations.js"></script> <script src="http://othersite.com/actions.js"></script> -But if :setting:`STATIC_URL` is ``'http://static.example.com/'``:: +But if :setting:`STATIC_URL` is ``'http://static.example.com/'``: + +.. code-block:: pycon >>> w = CalendarWidget() >>> print(w.media) @@ -249,7 +261,9 @@ But if :setting:`STATIC_URL` is ``'http://static.example.com/'``:: <script src="http://othersite.com/actions.js"></script> Or if :mod:`~django.contrib.staticfiles` is configured using the -:class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage`:: +:class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage`: + +.. code-block:: pycon >>> w = CalendarWidget() >>> print(w.media) @@ -265,7 +279,9 @@ Paths as objects Asset paths may also be given as hashable objects implementing an ``__html__()`` method. The ``__html__()`` method is typically added using the :func:`~django.utils.html.html_safe` decorator. The object is responsible for -outputting the complete HTML ``<script>`` or ``<link>`` tag content:: +outputting the complete HTML ``<script>`` or ``<link>`` tag content: + +.. code-block:: pycon >>> from django import forms >>> from django.utils.html import html_safe @@ -294,7 +310,9 @@ Subsets of assets ----------------- If you only want files of a particular type, you can use the subscript -operator to filter out a medium of interest. For example:: +operator to filter out a medium of interest. For example: + +.. code-block:: pycon >>> w = CalendarWidget() >>> print(w.media) @@ -313,7 +331,9 @@ Combining ``Media`` objects ``Media`` objects can also be added together. When two ``Media`` objects are added, the resulting ``Media`` object contains the union of the assets -specified by both:: +specified by both: + +.. code-block:: pycon >>> from django import forms >>> class CalendarWidget(forms.TextInput): @@ -345,7 +365,9 @@ example, you may have a script that depends on jQuery. Therefore, combining ``Media`` objects attempts to preserve the relative order in which assets are defined in each ``Media`` class. -For example:: +For example: + +.. code-block:: pycon >>> from django import forms >>> class CalendarWidget(forms.TextInput): @@ -377,7 +399,9 @@ are exactly the same. Regardless of whether you define a ``media`` declaration, *all* Form objects have a ``media`` property. The default value for this property is the result of adding the ``media`` definitions for all widgets that -are part of the form:: +are part of the form: + +.. code-block:: pycon >>> from django import forms >>> class ContactForm(forms.Form): @@ -392,7 +416,9 @@ are part of the form:: <script src="http://static.example.com/whizbang.js"></script> If you want to associate additional assets with a form -- for example, -CSS for form layout -- add a ``Media`` declaration to the form:: +CSS for form layout -- add a ``Media`` declaration to the form: + +.. code-block:: pycon >>> class ContactForm(forms.Form): ... date = DateField(widget=CalendarWidget) diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index 349162abd1..9ef7ee3f68 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -17,7 +17,9 @@ you've already defined the fields in your model. For this reason, Django provides a helper class that lets you create a ``Form`` class from a Django model. -For example:: +For example: + +.. code-block:: pycon >>> from django.forms import ModelForm >>> from myapp.models import Article @@ -320,7 +322,9 @@ Every ``ModelForm`` also has a ``save()`` method. This method creates and saves a database object from the data bound to the form. A subclass of ``ModelForm`` can accept an existing model instance as the keyword argument ``instance``; if this is supplied, ``save()`` will update that instance. If it's not supplied, -``save()`` will create a new instance of the specified model:: +``save()`` will create a new instance of the specified model: + +.. code-block:: pycon >>> from myapp.models import Article >>> from myapp.forms import ArticleForm @@ -373,7 +377,9 @@ exists in the database. To work around this problem, every time you save a form using ``commit=False``, Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After you've manually saved the instance produced by the form, you can invoke -``save_m2m()`` to save the many-to-many form data. For example:: +``save_m2m()`` to save the many-to-many form data. For example: + +.. code-block:: pycon # Create a form instance with POST data. >>> f = AuthorForm(request.POST) @@ -392,7 +398,9 @@ you've manually saved the instance produced by the form, you can invoke Calling ``save_m2m()`` is only required if you use ``save(commit=False)``. 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:: +is saved without the need for any additional method calls. For example: + +.. code-block:: pycon # Create a form instance with POST data. >>> a = Author() @@ -680,7 +688,9 @@ Form inheritance As with basic forms, you can extend and reuse ``ModelForms`` by inheriting them. This is useful if you need to declare extra fields or extra methods on a parent class for use in a number of forms derived from models. For example, -using the previous ``ArticleForm`` class:: +using the previous ``ArticleForm`` class: + +.. code-block:: pycon >>> class EnhancedArticleForm(ArticleForm): ... def clean_pub_date(self): @@ -690,7 +700,9 @@ This creates a form that behaves identically to ``ArticleForm``, except there's some extra validation and cleaning for the ``pub_date`` field. You can also subclass the parent's ``Meta`` inner class if you want to change -the ``Meta.fields`` or ``Meta.exclude`` lists:: +the ``Meta.fields`` or ``Meta.exclude`` lists: + +.. code-block:: pycon >>> class RestrictedArticleForm(EnhancedArticleForm): ... class Meta(ArticleForm.Meta): @@ -725,7 +737,9 @@ Providing initial values As with regular forms, it's possible to specify initial data for forms by specifying an ``initial`` parameter when instantiating the form. Initial values provided this way will override both initial values from the form field -and values from an attached model instance. For example:: +and values from an attached model instance. For example: + +.. code-block:: pycon >>> article = Article.objects.get(pk=1) >>> article.headline @@ -742,14 +756,18 @@ ModelForm factory function You can create forms from a given model using the standalone function :func:`~django.forms.models.modelform_factory`, instead of using a class definition. This may be more convenient if you do not have many customizations -to make:: +to make: + +.. code-block:: pycon >>> from django.forms import modelform_factory >>> from myapp.models import Book >>> BookForm = modelform_factory(Book, fields=["author", "title"]) This can also be used to make modifications to existing forms, for example by -specifying the widgets to be used for a given field:: +specifying the widgets to be used for a given field: + +.. code-block:: pycon >>> from django.forms import Textarea >>> Form = modelform_factory(Book, form=BookForm, @@ -773,7 +791,9 @@ Model formsets Like :doc:`regular formsets </topics/forms/formsets>`, Django provides a couple of enhanced formset classes to make working with Django models more -convenient. Let's reuse the ``Author`` model from above:: +convenient. Let's reuse the ``Author`` model from above: + +.. code-block:: pycon >>> from django.forms import modelformset_factory >>> from myapp.models import Author @@ -781,12 +801,16 @@ convenient. Let's reuse the ``Author`` model from above:: Using ``fields`` restricts the formset to use only the given fields. Alternatively, you can take an "opt-out" approach, specifying which fields to -exclude:: +exclude: + +.. code-block:: pycon >>> AuthorFormSet = modelformset_factory(Author, exclude=['birth_date']) This will create a formset that is capable of working with the data associated -with the ``Author`` model. It works just like a regular formset:: +with the ``Author`` model. It works just like a regular formset: + +.. code-block:: pycon >>> formset = AuthorFormSet() >>> print(formset) @@ -818,7 +842,9 @@ Changing the queryset By default, when you create a formset from a model, the formset will use a queryset that includes all objects in the model (e.g., ``Author.objects.all()``). You can override this behavior by using the -``queryset`` argument:: +``queryset`` argument: + +.. code-block:: pycon >>> formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith='O')) @@ -833,13 +859,17 @@ Alternatively, you can create a subclass that sets ``self.queryset`` in super().__init__(*args, **kwargs) self.queryset = Author.objects.filter(name__startswith='O') -Then, pass your ``BaseAuthorFormSet`` class to the factory function:: +Then, pass your ``BaseAuthorFormSet`` class to the factory function: + +.. code-block:: pycon >>> AuthorFormSet = modelformset_factory( ... Author, fields=['name', 'title'], formset=BaseAuthorFormSet) If you want to return a formset that doesn't include *any* preexisting -instances of the model, you can specify an empty QuerySet:: +instances of the model, you can specify an empty QuerySet: + +.. code-block:: pycon >>> AuthorFormSet(queryset=Author.objects.none()) @@ -874,7 +904,9 @@ Specifying widgets to use in the form with ``widgets`` Using the ``widgets`` parameter, you can specify a dictionary of values to customize the ``ModelForm``’s widget class for a particular field. This works the same way as the ``widgets`` dictionary on the inner ``Meta`` -class of a ``ModelForm`` works:: +class of a ``ModelForm`` works: + +.. code-block:: pycon >>> AuthorFormSet = modelformset_factory( ... Author, fields=['name', 'title'], @@ -912,7 +944,9 @@ Saving objects in the formset ----------------------------- As with a ``ModelForm``, you can save the data as a model object. This is done -with the formset's ``save()`` method:: +with the formset's ``save()`` method: + +.. code-block:: pycon # Create a formset instance with POST data. >>> formset = AuthorFormSet(request.POST) @@ -930,7 +964,9 @@ excluded), these fields will not be set by the ``save()`` method. You can find more information about this restriction, which also holds for regular ``ModelForms``, in `Selecting the fields to use`_. -Pass ``commit=False`` to return the unsaved model instances:: +Pass ``commit=False`` to return the unsaved model instances: + +.. code-block:: pycon # don't save to the database >>> instances = formset.save(commit=False) @@ -959,7 +995,9 @@ As with regular formsets, you can use the ``max_num`` and ``extra`` parameters to :func:`~django.forms.models.modelformset_factory` to limit the number of extra forms displayed. -``max_num`` does not prevent existing objects from being displayed:: +``max_num`` does not prevent existing objects from being displayed: + +.. code-block:: pycon >>> Author.objects.order_by('name') <QuerySet [<Author: Charles Baudelaire>, <Author: Paul Verlaine>, <Author: Walt Whitman>]> @@ -976,7 +1014,9 @@ this. If the value of ``max_num`` is greater than the number of existing related objects, up to ``extra`` additional blank forms will be added to the formset, -so long as the total number of forms does not exceed ``max_num``:: +so long as the total number of forms does not exceed ``max_num``: + +.. code-block:: pycon >>> AuthorFormSet = modelformset_factory(Author, fields=['name'], max_num=4, extra=2) >>> formset = AuthorFormSet(queryset=Author.objects.order_by('name')) @@ -998,7 +1038,9 @@ Preventing new objects creation .. versionadded:: 4.1 Using the ``edit_only`` parameter, you can prevent creation of any new -objects:: +objects: + +.. code-block:: pycon >>> AuthorFormSet = modelformset_factory( ... Author, @@ -1106,18 +1148,20 @@ cases in this example. Using the formset in the template --------------------------------- -.. highlight:: html+django - There are three ways to render a formset in a Django template. -First, you can let the formset do most of the work:: +First, you can let the formset do most of the work: + +.. code-block:: html+django <form method="post"> {{ formset }} </form> Second, you can manually render the formset, but let the form deal with -itself:: +itself: + +.. code-block:: html+django <form method="post"> {{ formset.management_form }} @@ -1130,7 +1174,9 @@ When you manually render the forms yourself, be sure to render the management form as shown above. See the :ref:`management form documentation <understanding-the-managementform>`. -Third, you can manually render each field:: +Third, you can manually render each field: + +.. code-block:: html+django <form method="post"> {{ formset.management_form }} @@ -1143,7 +1189,9 @@ Third, you can manually render each field:: If you opt to use this third method and you don't iterate over the fields with a ``{% for %}`` loop, you'll need to render the primary key field. For example, -if you were rendering the ``name`` and ``age`` fields of a model:: +if you were rendering the ``name`` and ``age`` fields of a model: + +.. code-block:: html+django <form method="post"> {{ formset.management_form }} @@ -1161,8 +1209,6 @@ the model formset, in the ``POST`` case, will work correctly. (This example assumes a primary key named ``id``. If you've explicitly defined your own primary key that isn't called ``id``, make sure it gets rendered.) -.. highlight:: python - .. _inline-formsets: Inline formsets @@ -1184,7 +1230,9 @@ you have these two models:: title = models.CharField(max_length=100) If you want to create a formset that allows you to edit books belonging to -a particular author, you could do this:: +a particular author, you could do this: + +.. code-block:: pycon >>> from django.forms import inlineformset_factory >>> BookFormSet = inlineformset_factory(Author, Book, fields=['title']) @@ -1227,7 +1275,9 @@ For example, if you want to override ``clean()``:: See also :ref:`model-formsets-overriding-clean`. Then when you create your inline formset, pass in the optional argument -``formset``:: +``formset``: + +.. code-block:: pycon >>> from django.forms import inlineformset_factory >>> BookFormSet = inlineformset_factory(Author, Book, fields=['title'], @@ -1256,7 +1306,9 @@ the following model:: length_in_months = models.IntegerField() To resolve this, you can use ``fk_name`` to -:func:`~django.forms.models.inlineformset_factory`:: +:func:`~django.forms.models.inlineformset_factory`: + +.. code-block:: pycon >>> FriendshipFormSet = inlineformset_factory(Friend, Friendship, fk_name='from_friend', ... fields=['to_friend', 'length_in_months']) diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt index 4dc6f6af35..cfc22bee52 100644 --- a/docs/topics/http/sessions.txt +++ b/docs/topics/http/sessions.txt @@ -357,7 +357,9 @@ Bundled serializers only serialize basic data types. In addition, as JSON supports only string keys, note that using non-string - keys in ``request.session`` won't work as expected:: + keys in ``request.session`` won't work as expected: + + .. code-block:: pycon >>> # initial assignment >>> request.session[0] = 'bar' @@ -499,11 +501,15 @@ Using sessions out of views you should consider importing ``SessionStore`` from the session engine designated by :setting:`SESSION_ENGINE`, as below: + .. code-block:: pycon + >>> from importlib import import_module >>> from django.conf import settings >>> SessionStore = import_module(settings.SESSION_ENGINE).SessionStore -An API is available to manipulate session data outside of a view:: +An API is available to manipulate session data outside of a view: + +.. code-block:: pycon >>> from django.contrib.sessions.backends.db import SessionStore >>> s = SessionStore() @@ -526,7 +532,9 @@ 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 a normal Django model. The ``Session`` model is defined in :source:`django/contrib/sessions/models.py`. Because it's a normal model, you can -access sessions using the normal Django database API:: +access sessions using the normal Django database API: + +.. code-block:: pycon >>> from django.contrib.sessions.models import Session >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead') @@ -536,7 +544,9 @@ access sessions using the normal Django database API:: Note that you'll need to call :meth:`~base_session.AbstractBaseSession.get_decoded()` to get the session dictionary. This is necessary because the dictionary is stored in an encoded -format:: +format: + +.. code-block:: pycon >>> s.session_data 'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...' diff --git a/docs/topics/i18n/formatting.txt b/docs/topics/i18n/formatting.txt index b83c31e936..113a42606f 100644 --- a/docs/topics/i18n/formatting.txt +++ b/docs/topics/i18n/formatting.txt @@ -83,7 +83,9 @@ contained block. This tag allows a more fine grained control of localization than :setting:`USE_L10N`. -To activate or deactivate localization for a template block, use:: +To activate or deactivate localization for a template block, use: + +.. code-block:: html+django {% load l10n %} @@ -113,7 +115,9 @@ Template filters Forces localization of a single value. -For example:: +For example: + +.. code-block:: html+django {% load l10n %} @@ -130,7 +134,9 @@ tag. Forces a single value to be printed without localization. -For example:: +For example: + +.. code-block:: html+django {% load l10n %} @@ -167,7 +173,9 @@ information in these files as values inside can be exposed if you pass the string to ``django.utils.formats.get_format()`` (used by the :tfilter:`date` template filter). -To customize the English formats, a structure like this would be needed:: +To customize the English formats, a structure like this would be needed: + +.. code-block:: text mysite/ formats/ diff --git a/docs/topics/i18n/timezones.txt b/docs/topics/i18n/timezones.txt index bfc1b77a3f..4f557fbcae 100644 --- a/docs/topics/i18n/timezones.txt +++ b/docs/topics/i18n/timezones.txt @@ -253,8 +253,6 @@ output for computers rather than for humans. The following filters and tags, provided by the ``tz`` template tag library, allow you to control the time zone conversions. -.. highlight:: html+django - Template tags ------------- @@ -270,7 +268,9 @@ This tag has exactly the same effects as the :setting:`USE_TZ` setting as far as the template engine is concerned. It allows a more fine grained control of conversion. -To activate or deactivate conversion for a template block, use:: +To activate or deactivate conversion for a template block, use: + +.. code-block:: html+django {% load tz %} @@ -295,7 +295,7 @@ To activate or deactivate conversion for a template block, use:: Sets or unsets the current time zone in the contained block. When the current time zone is unset, the default time zone applies. -:: +.. code-block:: html+django {% load tz %} @@ -313,7 +313,9 @@ time zone is unset, the default time zone applies. ~~~~~~~~~~~~~~~~~~~~~~~~ You can get the name of the current time zone using the -``get_current_timezone`` tag:: +``get_current_timezone`` tag: + +.. code-block:: html+django {% get_current_timezone as TIME_ZONE %} @@ -335,7 +337,9 @@ return aware datetimes. Forces conversion of a single value to the current time zone. -For example:: +For example: + +.. code-block:: html+django {% load tz %} @@ -348,7 +352,9 @@ For example:: Forces conversion of a single value to UTC. -For example:: +For example: + +.. code-block:: html+django {% load tz %} @@ -364,14 +370,14 @@ Forces conversion of a single value to an arbitrary timezone. The argument must be an instance of a :class:`~datetime.tzinfo` subclass or a time zone name. -For example:: +For example: + +.. code-block:: html+django {% load tz %} {{ value|timezone:"Europe/Paris" }} -.. highlight:: python - .. _time-zones-migration-guide: Migration guide @@ -427,7 +433,9 @@ code: :func:`~django.utils.timezone.now`, :func:`~django.utils.timezone.make_naive`. Finally, in order to help you locate code that needs upgrading, Django raises -a warning when you attempt to save a naive datetime to the database:: +a warning when you attempt to save a naive datetime to the database: + +.. code-block:: pytb RuntimeWarning: DateTimeField ModelName.field_name received a naive datetime (2012-01-01 00:00:00) while time zone support is active. @@ -504,7 +512,9 @@ Setup their values should be in UTC (or both!). Finally, our calendar system contains interesting edge cases. For example, - you can't always subtract one year directly from a given date:: + you can't always subtract one year directly from a given date: + + .. code-block:: pycon >>> import datetime >>> def one_year_before(value): # Wrong example. @@ -534,7 +544,9 @@ Troubleshooting #. **My application crashes with** ``TypeError: can't compare offset-naive`` ``and offset-aware datetimes`` **-- what's wrong?** - Let's reproduce this error by comparing a naive and an aware datetime:: + Let's reproduce this error by comparing a naive and an aware datetime: + + .. code-block:: pycon >>> from django.utils import timezone >>> aware = timezone.now() @@ -582,7 +594,9 @@ Troubleshooting method. You also consider that a :class:`~datetime.date` is a lot like a :class:`~datetime.datetime`, except that it's less accurate. - None of this is true in a time zone aware environment:: + None of this is true in a time zone aware environment: + + .. code-block:: pycon >>> import datetime >>> import zoneinfo @@ -620,7 +634,9 @@ Troubleshooting If you really need to do the conversion yourself, you must ensure the datetime is converted to the appropriate time zone first. Usually, this - will be the current timezone:: + will be the current timezone: + + .. code-block:: pycon >>> from django.utils import timezone >>> timezone.activate(zoneinfo.ZoneInfo("Asia/Singapore")) @@ -647,7 +663,9 @@ Usage datetime?** Here you need to create the required ``ZoneInfo`` instance and attach it to - the naïve datetime:: + the naïve datetime: + + .. code-block:: pycon >>> import zoneinfo >>> from django.utils.dateparse import parse_datetime @@ -670,7 +688,9 @@ Usage sufficient. For the sake of completeness, though, if you really want the local time - in the current time zone, here's how you can obtain it:: + in the current time zone, here's how you can obtain it: + + .. code-block:: pycon >>> from django.utils import timezone >>> timezone.localtime(timezone.now()) diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 2d7542681d..4b4871bfeb 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -518,7 +518,9 @@ Localized names of languages .. function:: get_language_info(lang_code) The ``get_language_info()`` function provides detailed information about -languages:: +languages: + +.. code-block:: pycon >>> from django.utils.translation import activate, get_language_info >>> activate('fr') @@ -539,8 +541,6 @@ Similar access to this information is available for template code. See below. Internationalization: in template code ====================================== -.. highlight:: html+django - Translations in :doc:`Django templates </ref/templates/language>` uses two template tags and a slightly different syntax than in Python code. To give your template access to these tags, put ``{% load i18n %}`` toward the top of your template. @@ -562,14 +562,18 @@ have already loaded the ``i18n`` tag. -------------------------- The ``{% translate %}`` template tag translates either a constant string -(enclosed in single or double quotes) or variable content:: +(enclosed in single or double quotes) or variable content: + +.. code-block:: html+django <title>{% translate "This is the title." %}</title> <title>{% translate myvar %}</title> If the ``noop`` option is present, variable lookup still takes place but the translation is skipped. This is useful when "stubbing out" content that will -require translation in the future:: +require translation in the future: + +.. code-block:: html+django <title>{% translate "myvar" noop %}</title> @@ -585,7 +589,9 @@ It's not possible to mix a template variable inside a string within (placeholders), use :ttag:`{% blocktranslate %}<blocktranslate>` instead. If you'd like to retrieve a translated string without displaying it, you can -use the following syntax:: +use the following syntax: + +.. code-block:: html+django {% translate "This is the title" as the_title %} @@ -594,7 +600,9 @@ use the following syntax:: In practice you'll use this to get a string you can use in multiple places in a template or so you can use the output as an argument for other template tags or -filters:: +filters: + +.. code-block:: html+django {% translate "starting point" as start %} {% translate "end point" as end %} @@ -624,13 +632,17 @@ using the ``context`` keyword: Contrarily to the :ttag:`translate` tag, the ``blocktranslate`` tag allows you to mark complex sentences consisting of literals and variable content for -translation by making use of placeholders:: +translation by making use of placeholders: + +.. code-block:: html+django {% blocktranslate %}This string will have {{ value }} inside.{% endblocktranslate %} To translate a template expression -- say, accessing object attributes or using template filters -- you need to bind the expression to a local variable -for use within the translation block. Examples:: +for use within the translation block. Examples: + +.. code-block:: html+django {% blocktranslate with amount=article.price %} That will cost $ {{ amount }}. @@ -640,7 +652,9 @@ for use within the translation block. Examples:: This will have {{ myvar }} inside. {% endblocktranslate %} -You can use multiple expressions inside a single ``blocktranslate`` tag:: +You can use multiple expressions inside a single ``blocktranslate`` tag: + +.. code-block:: html+django {% blocktranslate with book_t=book|title author_t=author|title %} This is {{ book_t }} by {{ author_t }} @@ -666,7 +680,9 @@ This tag also provides for pluralization. To use it: ``{% plural %}`` tag within the ``{% blocktranslate %}`` and ``{% endblocktranslate %}`` tags. -An example:: +An example: + +.. code-block:: html+django {% blocktranslate count counter=list|length %} There is only one {{ name }} object. @@ -674,7 +690,9 @@ An example:: There are {{ counter }} {{ name }} objects. {% endblocktranslate %} -A more complex example:: +A more complex example: + +.. code-block:: html+django {% blocktranslate with amount=article.price count years=i.length %} That will cost $ {{ amount }} per year. @@ -689,7 +707,9 @@ same :ref:`notes regarding ngettext variables <pluralization-var-notes>` apply. Reverse URL lookups cannot be carried out within the ``blocktranslate`` and -should be retrieved (and stored) beforehand:: +should be retrieved (and stored) beforehand: + +.. code-block:: html+django {% url 'path.to.view' arg arg2 as the_url %} {% blocktranslate %} @@ -697,7 +717,9 @@ should be retrieved (and stored) beforehand:: {% endblocktranslate %} If you'd like to retrieve a translated string without displaying it, you can -use the following syntax:: +use the following syntax: + +.. code-block:: html+django {% blocktranslate asvar the_title %}The title is {{ title }}.{% endblocktranslate %} <title>{{ the_title }}</title> @@ -728,7 +750,9 @@ character to separate them. This is quite useful for indenting the content of a in the corresponding entry in the ``.po`` file, which makes the translation process easier. -For instance, the following ``{% blocktranslate %}`` tag:: +For instance, the following ``{% blocktranslate %}`` tag: + +.. code-block:: html+django {% blocktranslate trimmed %} First sentence. @@ -743,7 +767,9 @@ String literals passed to tags and filters ------------------------------------------ You can translate string literals passed as arguments to tags and filters -by using the familiar ``_()`` syntax:: +by using the familiar ``_()`` syntax: + +.. code-block:: html+django {% some_tag _("Page not found") value|yesno:_("yes,no") %} @@ -891,12 +917,16 @@ processor, then each ``RequestContext`` will have access to ``LANGUAGES``, You can also retrieve information about any of the available languages using provided template tags and filters. To get information about a single language, -use the ``{% get_language_info %}`` tag:: +use the ``{% get_language_info %}`` tag: + +.. code-block:: html+django {% get_language_info for LANGUAGE_CODE as lang %} {% get_language_info for "pl" as lang %} -You can then access the information:: +You can then access the information: + +.. code-block:: html+django Language code: {{ lang.code }}<br> Name of language: {{ lang.name_local }}<br> @@ -924,7 +954,9 @@ If you do this in your view: context = {'available_languages': ['en', 'es', 'fr']} return render(request, 'mytemplate.html', context) -you can iterate over those languages in the template:: +you can iterate over those languages in the template: + +.. code-block:: html+django {% get_language_info_list for available_languages as langs %} {% for lang in langs %} ... {% endfor %} @@ -947,8 +979,6 @@ There are also some filters available for convenience: Internationalization: in JavaScript code ======================================== -.. highlight:: python - Adding translations to JavaScript poses some problems: * JavaScript code doesn't have access to a ``gettext`` implementation. @@ -1034,8 +1064,6 @@ precedence. Using the JavaScript translation catalog ---------------------------------------- -.. highlight:: javascript - To use the catalog, pull in the dynamically generated script like this: .. code-block:: html+django @@ -1202,8 +1230,6 @@ Additionally, if there are complex rules around pluralization, the catalog view will render a conditional expression. This will evaluate to either a ``true`` (should pluralize) or ``false`` (should **not** pluralize) value. -.. highlight:: python - The ``JSONCatalog`` view ------------------------ @@ -1342,7 +1368,9 @@ Example URL patterns:: After defining these URL patterns, Django will automatically add the language prefix to the URL patterns that were added by the ``i18n_patterns`` -function. Example:: +function. Example: + +.. code-block:: pycon >>> from django.urls import reverse >>> from django.utils.translation import activate @@ -1358,7 +1386,9 @@ function. Example:: '/nl/news/news-slug/' With ``prefix_default_language=False`` and ``LANGUAGE_CODE='en'``, the URLs -will be:: +will be: + +.. code-block:: pycon >>> activate('en') >>> reverse('news:index') @@ -1411,7 +1441,9 @@ URL patterns can also be marked translatable using the ) After you've created the translations, the :func:`~django.urls.reverse` -function will return the URL in the active language. Example:: +function will return the URL in the active language. Example: + +.. code-block:: pycon >>> from django.urls import reverse >>> from django.utils.translation import activate @@ -1484,7 +1516,9 @@ Django comes with a tool, :djadmin:`django-admin makemessages The minimum version of the ``gettext`` utilities supported is 0.15. -To create or update a message file, run this command:: +To create or update a message file, run this command: + +.. code-block:: shell django-admin makemessages -l de @@ -1516,12 +1550,16 @@ will generate an error if :setting:`LOCALE_PATHS` is empty. By default :djadmin:`django-admin makemessages <makemessages>` examines every file that has the ``.html``, ``.txt`` or ``.py`` file extension. If you want to override that default, use the :option:`--extension <makemessages --extension>` -or ``-e`` option to specify the file extensions to examine:: +or ``-e`` option to specify the file extensions to examine: + +.. code-block:: shell django-admin makemessages -l de -e txt Separate multiple extensions with commas and/or use ``-e`` or ``--extension`` -multiple times:: +multiple times: + +.. code-block:: shell django-admin makemessages -l de -e html,txt -e xml @@ -1537,7 +1575,9 @@ multiple times:: To extract strings from a project containing Jinja2 templates, use `Message Extracting`_ from Babel_ instead. - Here's an example ``babel.cfg`` configuration file:: + Here's an example ``babel.cfg`` configuration file: + + .. code-block:: ini # Extraction from Python source files [python: **.py] @@ -1624,7 +1664,9 @@ otherwise, they'll be tacked together without whitespace! :djadmin:`compilemessages`. To reexamine all source code and templates for new translation strings and -update all message files for **all** languages, run this:: +update all message files for **all** languages, run this: + +.. code-block:: shell django-admin makemessages -a @@ -1639,7 +1681,9 @@ utility. This tool runs over all available ``.po`` files and creates ``.mo`` files, which are binary files optimized for use by ``gettext``. In the same directory from which you ran :djadmin:`django-admin makemessages <makemessages>`, run -:djadmin:`django-admin compilemessages <compilemessages>` like this:: +:djadmin:`django-admin compilemessages <compilemessages>` like this: + +.. code-block:: shell django-admin compilemessages @@ -1691,7 +1735,9 @@ You create and update the message files the same way as the other Django message files -- with the :djadmin:`django-admin makemessages <makemessages>` tool. The only difference is you need to explicitly specify what in gettext parlance is known as a domain in this case the ``djangojs`` domain, by providing a ``-d -djangojs`` parameter, like this:: +djangojs`` parameter, like this: + +.. code-block:: shell django-admin makemessages -d djangojs -l de @@ -1831,8 +1877,6 @@ redirected in the ``redirect_to`` context variable. Explicitly setting the active language -------------------------------------- -.. highlight:: python - You may want to set the active language for the current session explicitly. Perhaps a user's language preference is retrieved from another system, for example. You've already been introduced to :func:`django.utils.translation.activate()`. That diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index be3216c21f..62e347a49e 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -110,7 +110,9 @@ Workflow ======== Django can create migrations for you. Make changes to your models - say, add a -field and remove a model - and then run :djadmin:`makemigrations`:: +field and remove a model - and then run :djadmin:`makemigrations`: + +.. code-block:: shell $ python manage.py makemigrations Migrations for 'books': @@ -124,7 +126,9 @@ will be written out. Make sure to read the output to see what complex changes it might not be detecting what you expect. Once you have your new migration files, you should apply them to your -database to make sure they work as expected:: +database to make sure they work as expected: + +.. code-block:: shell $ python manage.py migrate Operations to perform: @@ -140,7 +144,9 @@ get both the changes to your models and the accompanying migration at the same time. If you want to give the migration(s) a meaningful name instead of a generated -one, you can use the :option:`makemigrations --name` option:: +one, you can use the :option:`makemigrations --name` option: + +.. code-block:: shell $ python manage.py makemigrations --name changed_my_model your_app_label @@ -342,7 +348,9 @@ 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 by running:: +need to convert it to use migrations by running: + +.. code-block:: shell $ python manage.py makemigrations your_app_label @@ -521,7 +529,9 @@ the main operation you use for data migrations is :class:`~django.db.migrations.operations.RunPython`. To start, make an empty migration file you can work from (Django will put -the file in the right place, suggest a name, and add dependencies for you):: +the file in the right place, suggest a name, and add dependencies for you): + +.. code-block:: shell python manage.py makemigrations --empty yourappname @@ -660,7 +670,9 @@ 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` - pass it the -app label and migration name you want to squash up to, and it'll get to work:: +app label and migration name you want to squash up to, and it'll get to work: + +.. code-block:: shell $ ./manage.py squashmigrations myapp 0004 Will squash the following migrations: diff --git a/docs/topics/pagination.txt b/docs/topics/pagination.txt index c91b1e8ba7..34fd6c97eb 100644 --- a/docs/topics/pagination.txt +++ b/docs/topics/pagination.txt @@ -18,7 +18,9 @@ Example Give :class:`~django.core.paginator.Paginator` a list of objects, plus the number of items you'd like to have on each page, and it gives you methods for -accessing the items for each page:: +accessing the items for each page: + +.. code-block:: pycon >>> from django.core.paginator import Paginator >>> objects = ['john', 'paul', 'george', 'ringo'] diff --git a/docs/topics/security.txt b/docs/topics/security.txt index f8f1df8a11..0f6f05163a 100644 --- a/docs/topics/security.txt +++ b/docs/topics/security.txt @@ -10,8 +10,6 @@ on securing a Django-powered site. Cross site scripting (XSS) protection ===================================== -.. highlight:: html+django - XSS attacks allow a user to inject client side scripts into the browsers of other users. This is usually achieved by storing the malicious scripts in the database where it will be retrieved and displayed to other users, or by getting diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt index f95db92c16..ae18b782a5 100644 --- a/docs/topics/serialization.txt +++ b/docs/topics/serialization.txt @@ -173,7 +173,9 @@ Identifier Information XML --- -The basic XML serialization format looks like this:: +The basic XML serialization format looks like this: + +.. code-block:: xml <?xml version="1.0" encoding="utf-8"?> <django-objects version="1.0"> @@ -193,7 +195,9 @@ Each field of the object is serialized as a ``<field>``-element sporting the fields "type" and "name". The text content of the element represents the value that should be stored. -Foreign keys and other relational fields are treated a little bit differently:: +Foreign keys and other relational fields are treated a little bit differently: + +.. code-block:: xml <object pk="27" model="auth.permission"> <!-- ... --> @@ -205,7 +209,9 @@ In this example we specify that the ``auth.Permission`` object with the PK 27 has a foreign key to the ``contenttypes.ContentType`` instance with the PK 9. ManyToMany-relations are exported for the model that binds them. For instance, -the ``auth.User`` model has such a relation to the ``auth.Permission`` model:: +the ``auth.User`` model has such a relation to the ``auth.Permission`` model: + +.. code-block:: xml <object pk="1" model="auth.user"> <!-- ... --> @@ -326,7 +332,9 @@ YAML YAML serialization looks quite similar to JSON. The object list is serialized as a sequence mappings with the keys "pk", "model" and "fields". Each field is -again a mapping with the key being name of the field and the value the value:: +again a mapping with the key being name of the field and the value the value: + +.. code-block:: yaml - model: sessions.session pk: 4b678b301dfd8a4e0dad910de3ae245b @@ -502,7 +510,9 @@ Firstly, you need to add another method -- this time to the model itself:: That method should always return a natural key tuple -- in this example, ``(first name, last name)``. Then, when you call ``serializers.serialize()``, you provide ``use_natural_foreign_keys=True`` -or ``use_natural_primary_keys=True`` arguments:: +or ``use_natural_primary_keys=True`` arguments: + +.. code-block:: pycon >>> serializers.serialize('json', [book1, book2], indent=2, ... use_natural_foreign_keys=True, use_natural_primary_keys=True) diff --git a/docs/topics/settings.txt b/docs/topics/settings.txt index 5b8265660c..e1dcc37daa 100644 --- a/docs/topics/settings.txt +++ b/docs/topics/settings.txt @@ -55,17 +55,23 @@ When using :doc:`django-admin </ref/django-admin>`, you can either set the environment variable once, or explicitly pass in the settings module each time you run the utility. -Example (Unix Bash shell):: +Example (Unix Bash shell): + +.. code-block:: shell export DJANGO_SETTINGS_MODULE=mysite.settings django-admin runserver -Example (Windows shell):: +Example (Windows shell): + +.. code-block:: doscon set DJANGO_SETTINGS_MODULE=mysite.settings django-admin runserver -Use the ``--settings`` command-line argument to specify the settings manually:: +Use the ``--settings`` command-line argument to specify the settings manually: + +.. code-block:: shell django-admin runserver --settings=mysite.settings diff --git a/docs/topics/signing.txt b/docs/topics/signing.txt index 0e88c443cc..53636caf32 100644 --- a/docs/topics/signing.txt +++ b/docs/topics/signing.txt @@ -46,7 +46,9 @@ Using the low-level API ======================= Django's signing methods live in the ``django.core.signing`` module. -To sign a value, first instantiate a ``Signer`` instance:: +To sign a value, first instantiate a ``Signer`` instance: + +.. code-block:: pycon >>> from django.core.signing import Signer >>> signer = Signer() @@ -55,7 +57,9 @@ To sign a value, first instantiate a ``Signer`` instance:: 'My string:GdMGD6HNQ_qdgxYP8yBZAdAIV1w' The signature is appended to the end of the string, following the colon. -You can retrieve the original value using the ``unsign`` method:: +You can retrieve the original value using the ``unsign`` method: + +.. code-block:: pycon >>> original = signer.unsign(value) >>> original @@ -63,7 +67,9 @@ You can retrieve the original value using the ``unsign`` method:: If you pass a non-string value to ``sign``, the value will be forced to string before being signed, and the ``unsign`` result will give you that string -value:: +value: + +.. code-block:: pycon >>> signed = signer.sign(2.5) >>> original = signer.unsign(signed) @@ -71,7 +77,9 @@ value:: '2.5' If you wish to protect a list, tuple, or dictionary you can do so using the -``sign_object()`` and ``unsign_object()`` methods:: +``sign_object()`` and ``unsign_object()`` methods: + +.. code-block:: pycon >>> signed_obj = signer.sign_object({'message': 'Hello!'}) >>> signed_obj @@ -83,7 +91,9 @@ If you wish to protect a list, tuple, or dictionary you can do so using the See :ref:`signing-complex-data` for more details. If the signature or value have been altered in any way, a -``django.core.signing.BadSignature`` exception will be raised:: +``django.core.signing.BadSignature`` exception will be raised: + +.. code-block:: pycon >>> from django.core import signing >>> value += 'm' @@ -94,7 +104,9 @@ If the signature or value have been altered in any way, a By default, the ``Signer`` class uses the :setting:`SECRET_KEY` setting to generate signatures. You can use a different secret by passing it to the -``Signer`` constructor:: +``Signer`` constructor: + +.. code-block:: pycon >>> signer = Signer(key='my-other-secret') >>> value = signer.sign('My string') @@ -125,7 +137,9 @@ Using the ``salt`` argument If you do not wish for every occurrence of a particular string to have the same signature hash, you can use the optional ``salt`` argument to the ``Signer`` class. Using a salt will seed the signing hash function with both the salt and -your :setting:`SECRET_KEY`:: +your :setting:`SECRET_KEY`: + +.. code-block:: pycon >>> signer = Signer() >>> signer.sign('My string') @@ -158,7 +172,9 @@ Verifying timestamped values ``TimestampSigner`` is a subclass of :class:`~Signer` that appends a signed timestamp to the value. This allows you to confirm that a signed value was -created within a specified period of time:: +created within a specified period of time: + +.. code-block:: pycon >>> from datetime import timedelta >>> from django.core.signing import TimestampSigner @@ -214,7 +230,9 @@ If you wish to protect a list, tuple or dictionary you can do so using the ``TimestampSigner(salt='django.core.signing').sign_object()/unsign_object()``). These use JSON serialization under the hood. JSON ensures that even if your :setting:`SECRET_KEY` is stolen an attacker will not be able to execute -arbitrary commands by exploiting the pickle format:: +arbitrary commands by exploiting the pickle format: + +.. code-block:: pycon >>> from django.core import signing >>> signer = signing.TimestampSigner() @@ -231,7 +249,9 @@ arbitrary commands by exploiting the pickle format:: Because of the nature of JSON (there is no native distinction between lists and tuples) if you pass in a tuple, you will get a list from -``signing.loads(object)``:: +``signing.loads(object)``: + +.. code-block:: pycon >>> from django.core import signing >>> value = signing.dumps(('a','b','c')) diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index 59658c66e9..47fc3cc024 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -49,8 +49,6 @@ namespace. The Django template language ============================ -.. highlight:: html+django - Syntax ------ @@ -75,17 +73,23 @@ Variables A variable outputs a value from the context, which is a dict-like object mapping keys to values. -Variables are surrounded by ``{{`` and ``}}`` like this:: +Variables are surrounded by ``{{`` and ``}}`` like this: + +.. code-block:: html+django My first name is {{ first_name }}. My last name is {{ last_name }}. With a context of ``{'first_name': 'John', 'last_name': 'Doe'}``, this template -renders to:: +renders to: + +.. code-block:: html+django My first name is John. My last name is Doe. Dictionary lookup, attribute lookup and list-index lookups are implemented with -a dot notation:: +a dot notation: + +.. code-block:: html+django {{ my_dict.key }} {{ my_object.attribute }} @@ -103,15 +107,21 @@ This definition is deliberately vague. For example, a tag can output content, serve as a control structure e.g. an "if" statement or a "for" loop, grab content from a database, or even enable access to other template tags. -Tags are surrounded by ``{%`` and ``%}`` like this:: +Tags are surrounded by ``{%`` and ``%}`` like this: + +.. code-block:: html+django {% csrf_token %} -Most tags accept arguments:: +Most tags accept arguments: + +.. code-block:: html+django {% cycle 'odd' 'even' %} -Some tags require beginning and ending tags:: +Some tags require beginning and ending tags: + +.. code-block:: html+django {% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %} @@ -124,16 +134,22 @@ Filters Filters transform the values of variables and tag arguments. -They look like this:: +They look like this: + +.. code-block:: html+django {{ django|title }} With a context of ``{'django': 'the web framework for perfectionists with -deadlines'}``, this template renders to:: +deadlines'}``, this template renders to: + +.. code-block:: html+django The Web Framework For Perfectionists With Deadlines -Some filters take an argument:: +Some filters take an argument: + +.. code-block:: html+django {{ my_date|date:"Y-m-d" }} @@ -144,7 +160,9 @@ available as well as :ref:`instructions for writing custom filters Comments ~~~~~~~~ -Comments look like this:: +Comments look like this: + +.. code-block:: html+django {# this won't be rendered #} @@ -219,8 +237,6 @@ and you can implement your own additional context processors, too. Support for template engines ============================ -.. highlight:: python - Configuration ------------- diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt index fafc4e0bbc..101058b7dc 100644 --- a/docs/topics/testing/advanced.txt +++ b/docs/topics/testing/advanced.txt @@ -414,7 +414,9 @@ you may want to use the Django test runner to run your own test suite and thus benefit from the Django testing infrastructure. A common practice is a *tests* directory next to the application code, with the -following structure:: +following structure: + +.. code-block:: text runtests.py polls/ @@ -869,12 +871,16 @@ the coverage of your tests. Django can be easily integrated with `coverage.py`_, a tool for measuring code coverage of Python programs. First, `install coverage.py`_. Next, run the -following from your project folder containing ``manage.py``:: +following from your project folder containing ``manage.py``: + +.. code-block:: shell coverage run --source='.' manage.py test myapp This runs your tests and collects coverage data of the executed files in your -project. You can see a report of this data by typing following command:: +project. You can see a report of this data by typing following command: + +.. code-block:: shell coverage report diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt index e37cf23737..69f27bbeb8 100644 --- a/docs/topics/testing/overview.txt +++ b/docs/topics/testing/overview.txt @@ -75,7 +75,9 @@ Running tests ============= Once you've written tests, run them using the :djadmin:`test` command of -your project's ``manage.py`` utility:: +your project's ``manage.py`` utility: + +.. code-block:: shell $ ./manage.py test @@ -85,7 +87,9 @@ any file named ``test*.py`` under the current working directory. You can specify particular tests to run by supplying any number of "test labels" to ``./manage.py test``. Each test label can be a full Python dotted -path to a package, module, ``TestCase`` subclass, or test method. For instance:: +path to a package, module, ``TestCase`` subclass, or test method. For instance: + +.. code-block:: shell # Run all the tests in the animals.tests module $ ./manage.py test animals.tests @@ -100,13 +104,17 @@ path to a package, module, ``TestCase`` subclass, or test method. For instance:: $ ./manage.py test animals.tests.AnimalTestCase.test_animals_can_speak You can also provide a path to a directory to discover tests below that -directory:: +directory: + +.. code-block:: shell $ ./manage.py test animals/ You can specify a custom filename pattern match using the ``-p`` (or ``--pattern``) option, if your test files are named differently from the -``test*.py`` pattern:: +``test*.py`` pattern: + +.. code-block:: shell $ ./manage.py test --pattern="tests_*.py" @@ -288,7 +296,9 @@ Understanding the test output When you run your tests, you'll see a number of messages as the test runner prepares itself. You can control the level of detail of these messages with the -``verbosity`` option on the command line:: +``verbosity`` option on the command line: + +.. code-block:: shell Creating test database... Creating table myapp_animal @@ -298,7 +308,9 @@ This tells you that the test runner is creating a test database, as described in the previous section. Once the test database has been created, Django will run your tests. -If everything goes well, you'll see something like this:: +If everything goes well, you'll see something like this: + +.. code-block:: shell ---------------------------------------------------------------------- Ran 22 tests in 0.221s @@ -306,7 +318,9 @@ If everything goes well, you'll see something like this:: OK If there are test failures, however, you'll see full details about which tests -failed:: +failed: + +.. code-block:: shell ====================================================================== FAIL: test_was_published_recently_with_future_poll (polls.tests.PollMethodTests) diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index ba42180744..25654feb29 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -48,7 +48,9 @@ Overview and a quick example ---------------------------- To use the test client, instantiate ``django.test.Client`` and retrieve -web pages:: +web pages: + +.. code-block:: pycon >>> from django.test import Client >>> c = Client() @@ -70,11 +72,15 @@ Note a few important things about how the test client works: framework. This helps make the unit tests run quickly. * When retrieving pages, remember to specify the *path* of the URL, not the - whole domain. For example, this is correct:: + whole domain. For example, this is correct: + + .. code-block:: pycon >>> c.get('/login/') - This is incorrect:: + This is incorrect: + + .. code-block:: pycon >>> c.get('https://www.example.com/login/') @@ -102,7 +108,9 @@ Note a few important things about how the test client works: checks, you can create an instance of the test client that enforces CSRF checks. To do this, pass in the ``enforce_csrf_checks`` argument when you construct your - client:: + client: + + .. code-block:: pycon >>> from django.test import Client >>> csrf_client = Client(enforce_csrf_checks=True) @@ -160,17 +168,23 @@ Use the ``django.test.Client`` class to make requests. object, which is documented below. The key-value pairs in the ``data`` dictionary are used to create a GET - data payload. For example:: + data payload. For example: + + .. code-block:: pycon >>> c = Client() >>> c.get('/customers/details/', {'name': 'fred', 'age': 7}) - ...will result in the evaluation of a GET request equivalent to:: + ...will result in the evaluation of a GET request equivalent to: + + .. code-block:: text /customers/details/?name=fred&age=7 The ``headers`` parameter can be used to specify headers to be sent in - the request. For example:: + the request. For example: + + .. code-block:: pycon >>> c = Client() >>> c.get('/customers/details/', {'name': 'fred', 'age': 7}, @@ -182,17 +196,21 @@ Use the ``django.test.Client`` class to make requests. Arbitrary keyword arguments set WSGI :pep:`environ variables <3333#environ-variables>`. For example, headers - to set the script name:: + to set the script name: + + .. code-block:: pycon >>> c = Client() >>> c.get("/", SCRIPT_NAME="/app/") If you already have the GET arguments in URL-encoded form, you can use that encoding instead of using the data argument. For example, - the previous GET request could also be posed as:: + the previous GET request could also be posed as: - >>> c = Client() - >>> c.get('/customers/details/?name=fred&age=7') + .. code-block:: pycon + + >>> c = Client() + >>> c.get('/customers/details/?name=fred&age=7') If you provide a URL with both an encoded GET data and a data argument, the data argument will take precedence. @@ -202,7 +220,9 @@ Use the ``django.test.Client`` class to make requests. containing tuples of the intermediate urls and status codes. If you had a URL ``/redirect_me/`` that redirected to ``/next/``, that - redirected to ``/final/``, this is what you'd see:: + redirected to ``/final/``, this is what you'd see: + + .. code-block:: pycon >>> response = c.get('/redirect_me/', follow=True) >>> response.redirect_chain @@ -221,7 +241,9 @@ Use the ``django.test.Client`` class to make requests. ``Response`` object, which is documented below. The key-value pairs in the ``data`` dictionary are used to submit POST - data. For example:: + data. For example: + + .. code-block:: pycon >>> c = Client() >>> c.post('/login/', {'name': 'fred', 'passwd': 'secret'}) @@ -264,7 +286,9 @@ Use the ``django.test.Client`` class to make requests. provide the file field name as a key, and a file handle to the file you wish to upload as a value. For example, if your form has fields ``name`` and ``attachment``, the latter a - :class:`~django.forms.FileField`:: + :class:`~django.forms.FileField`: + + .. code-block:: pycon >>> c = Client() >>> with open('wishlist.doc', 'rb') as fp: @@ -275,7 +299,9 @@ Use the ``django.test.Client`` class to make requests. :class:`~django.db.models.ImageField`, the object needs a ``name`` attribute that passes the :data:`~django.core.validators.validate_image_file_extension` validator. - For example:: + For example: + + .. code-block:: pycon >>> from io import BytesIO >>> img = BytesIO( @@ -300,9 +326,11 @@ Use the ``django.test.Client`` class to make requests. If the URL you request with a POST contains encoded parameters, these parameters will be made available in the request.GET data. For example, - if you were to make the request:: + if you were to make the request: + + .. code-block:: pycon - >>> c.post('/login/?visitor=true', {'name': 'fred', 'passwd': 'secret'}) + >>> c.post('/login/?visitor=true', {'name': 'fred', 'passwd': 'secret'}) ... the view handling this request could interrogate request.POST to retrieve the username and password, and could interrogate request.GET @@ -419,7 +447,9 @@ Use the ``django.test.Client`` class to make requests. (which is configured by your :setting:`AUTHENTICATION_BACKENDS` setting). If you're using the standard authentication backend provided by Django (``ModelBackend``), ``credentials`` should be the user's - username and password, provided as keyword arguments:: + username and password, provided as keyword arguments: + + .. code-block:: pycon >>> c = Client() >>> c.login(username='fred', password='secret') @@ -513,7 +543,9 @@ Specifically, a ``Response`` object has the following attributes: Regardless of the number of templates used during rendering, you can retrieve context values using the ``[]`` operator. For example, the - context variable ``name`` could be retrieved using:: + context variable ``name`` could be retrieved using: + + .. code-block:: pycon >>> response = client.get('/foo/') >>> response.context['name'] @@ -545,7 +577,9 @@ Specifically, a ``Response`` object has the following attributes: .. method:: json(**kwargs) The body of the response, parsed as JSON. Extra keyword arguments are - passed to :func:`json.loads`. For example:: + passed to :func:`json.loads`. For example: + + .. code-block:: pycon >>> response = client.get('/foo/') >>> response.json()['name'] @@ -1970,7 +2004,9 @@ test client, with two exceptions: * The ``follow`` parameter is not supported. * Headers passed as ``extra`` keyword arguments should not have the ``HTTP_`` prefix required by the synchronous client (see :meth:`Client.get`). For - example, here is how to set an HTTP ``Accept`` header:: + example, here is how to set an HTTP ``Accept`` header: + + .. code-block:: pycon >>> c = AsyncClient() >>> c.get( |
