From c49ea6f5911296dcb40190c905e38b43cdc7c7a3 Mon Sep 17 00:00:00 2001 From: Curtis Maloney <curtis@tinbrain.net> Date: Tue, 11 Sep 2018 03:00:34 +1000 Subject: [PATCH] Refs #20910 -- Replaced snippet directive with code-block. --- docs/_ext/djangodocs.py | 141 +----------------- docs/_theme/djangodocs-epub/static/epub.css | 5 +- docs/_theme/djangodocs/static/djangodocs.css | 5 +- docs/howto/initial-data.txt | 2 +- docs/howto/writing-migrations.txt | 20 +-- .../writing-code/coding-style.txt | 4 +- .../contributing/writing-code/unit-tests.txt | 4 +- docs/internals/howto-release-django.txt | 4 +- docs/intro/overview.txt | 28 ++-- docs/intro/reusable-apps.txt | 12 +- docs/intro/tutorial01.txt | 12 +- docs/intro/tutorial02.txt | 20 +-- docs/intro/tutorial03.txt | 52 +++---- docs/intro/tutorial04.txt | 28 ++-- docs/intro/tutorial05.txt | 40 ++--- docs/intro/tutorial06.txt | 12 +- docs/intro/tutorial07.txt | 36 ++--- docs/ref/contrib/admin/index.txt | 20 +-- docs/ref/contrib/admin/javascript.txt | 8 +- docs/ref/models/expressions.txt | 4 +- docs/ref/models/fields.txt | 8 +- docs/ref/templates/language.txt | 16 +- docs/releases/1.9.txt | 16 +- docs/topics/auth/passwords.txt | 12 +- .../class-based-views/generic-editing.txt | 28 ++-- docs/topics/class-based-views/mixins.txt | 8 +- docs/topics/db/models.txt | 4 +- docs/topics/forms/index.txt | 16 +- docs/topics/http/file-uploads.txt | 16 +- docs/topics/http/urls.txt | 16 +- docs/topics/logging.txt | 4 +- docs/topics/testing/advanced.txt | 8 +- 32 files changed, 234 insertions(+), 375 deletions(-) diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py index 95f5218d70..30d3741b89 100644 --- a/docs/_ext/djangodocs.py +++ b/docs/_ext/djangodocs.py @@ -6,14 +6,13 @@ import os import re from docutils import nodes -from docutils.parsers.rst import Directive, directives +from docutils.parsers.rst import Directive from docutils.statemachine import ViewList from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.directives import CodeBlock from sphinx.domains.std import Cmdoption from sphinx.util.console import bold -from sphinx.util.nodes import set_source_info from sphinx.writers.html import HTMLTranslator # RE for option descriptions without a '--' prefix @@ -53,17 +52,6 @@ def setup(app): app.add_directive('versionadded', VersionDirective) app.add_directive('versionchanged', VersionDirective) app.add_builder(DjangoStandaloneHTMLBuilder) - - # register the snippet directive - app.add_directive('snippet', SnippetWithFilename) - # register a node for snippet directive so that the xml parser - # knows how to handle the enter/exit parsing event - app.add_node(snippet_with_filename, - html=(visit_snippet, depart_snippet_literal), - latex=(visit_snippet_latex, depart_snippet_latex), - man=(visit_snippet_literal, depart_snippet_literal), - text=(visit_snippet_literal, depart_snippet_literal), - texinfo=(visit_snippet_literal, depart_snippet_literal)) app.set_translator('djangohtml', DjangoHTMLTranslator) app.set_translator('json', DjangoHTMLTranslator) app.add_node( @@ -79,133 +67,6 @@ def setup(app): return {'parallel_read_safe': True} -class snippet_with_filename(nodes.literal_block): - """ - Subclass the literal_block to override the visit/depart event handlers - """ - pass - - -def visit_snippet_literal(self, node): - """ - default literal block handler - """ - self.visit_literal_block(node) - - -def depart_snippet_literal(self, node): - """ - default literal block handler - """ - self.depart_literal_block(node) - - -def visit_snippet(self, node): - """ - HTML document generator visit handler - """ - lang = self.highlightlang - linenos = node.rawsource.count('\n') >= self.highlightlinenothreshold - 1 - fname = node['filename'] - highlight_args = node.get('highlight_args', {}) - if 'language' in node: - # code-block directives - lang = node['language'] - highlight_args['force'] = True - if 'linenos' in node: - linenos = node['linenos'] - - def warner(msg): - self.builder.warn(msg, (self.builder.current_docname, node.line)) - - highlighted = self.highlighter.highlight_block(node.rawsource, lang, - warn=warner, - linenos=linenos, - **highlight_args) - starttag = self.starttag(node, 'div', suffix='', - CLASS='highlight-%s snippet' % lang) - self.body.append(starttag) - self.body.append('<div class="snippet-filename">%s</div>\n''' % (fname,)) - self.body.append(highlighted) - self.body.append('</div>\n') - raise nodes.SkipNode - - -def visit_snippet_latex(self, node): - """ - Latex document generator visit handler - """ - code = node.rawsource.rstrip('\n') - - lang = self.hlsettingstack[-1][0] - linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1 - fname = node['filename'] - highlight_args = node.get('highlight_args', {}) - if 'language' in node: - # code-block directives - lang = node['language'] - highlight_args['force'] = True - if 'linenos' in node: - linenos = node['linenos'] - - def warner(msg): - self.builder.warn(msg, (self.curfilestack[-1], node.line)) - - hlcode = self.highlighter.highlight_block(code, lang, warn=warner, - linenos=linenos, - **highlight_args) - - self.body.append( - '\n{\\colorbox[rgb]{0.9,0.9,0.9}' - '{\\makebox[\\textwidth][l]' - '{\\small\\texttt{%s}}}}\n' % ( - # Some filenames have '_', which is special in latex. - fname.replace('_', r'\_'), - ) - ) - - if self.table: - hlcode = hlcode.replace('\\begin{Verbatim}', - '\\begin{OriginalVerbatim}') - self.table.has_problematic = True - self.table.has_verbatim = True - - hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim} - hlcode = hlcode.rstrip() + '\n' - self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' % - (self.table and 'Original' or '')) - - # Prevent rawsource from appearing in output a second time. - raise nodes.SkipNode - - -def depart_snippet_latex(self, node): - """ - Latex document generator depart handler. - """ - pass - - -class SnippetWithFilename(Directive): - """ - The 'snippet' directive that allows to add the filename (optional) - of a code snippet in the document. This is modeled after CodeBlock. - """ - has_content = True - optional_arguments = 1 - option_spec = {'filename': directives.unchanged_required} - - def run(self): - code = '\n'.join(self.content) - - literal = snippet_with_filename(code, code) - if self.arguments: - literal['language'] = self.arguments[0] - literal['filename'] = self.options['filename'] - set_source_info(self, literal) - return [literal] - - class VersionDirective(Directive): has_content = True required_arguments = 1 diff --git a/docs/_theme/djangodocs-epub/static/epub.css b/docs/_theme/djangodocs-epub/static/epub.css index b74af5e9bf..7db68b53fb 100644 --- a/docs/_theme/djangodocs-epub/static/epub.css +++ b/docs/_theme/djangodocs-epub/static/epub.css @@ -29,15 +29,14 @@ pre { } /* Header for some code blocks. */ -.snippet-filename { +.code-block-caption { background-color: #393939; color: white; margin: 0; padding: 0.5em; font: bold 90% monospace; } -.snippet-filename + .highlight > pre, -.snippet-filename + pre { +.literal-block-wrapper pre { margin-top: 0; } diff --git a/docs/_theme/djangodocs/static/djangodocs.css b/docs/_theme/djangodocs/static/djangodocs.css index 143bcdb6c9..1a397f44c0 100644 --- a/docs/_theme/djangodocs/static/djangodocs.css +++ b/docs/_theme/djangodocs/static/djangodocs.css @@ -101,9 +101,8 @@ pre { font-size:small; background:#E0FFB8; border:1px solid #94da3a; border-widt dt .literal, table .literal { background:none; } #bd a.reference { text-decoration: none; } #bd a.reference tt.literal { border-bottom: 1px #234f32 dotted; } -div.snippet-filename { color: white; background-color: #234F32; margin: 0; padding: 2px 5px; width: 100%; font-family: monospace; font-size: small; line-height: 1.3em; } -div.snippet-filename + div.highlight > pre { margin-top: 0; } -div.snippet-filename + pre { margin-top: 0; } +div.code-block-caption { color: white; background-color: #234F32; margin: 0; padding: 2px 5px; width: 100%; font-family: monospace; font-size: small; line-height: 1.3em; } +div.literal-block-wrapper pre { margin-top: 0; } /* Restore colors of pygments hyperlinked code */ #bd .highlight .k a:link, #bd .highlight .k a:visited { color: #000000; text-decoration: none; border-bottom: 1px dotted #000000; } diff --git a/docs/howto/initial-data.txt b/docs/howto/initial-data.txt index 64012f66b9..fcfecc82a1 100644 --- a/docs/howto/initial-data.txt +++ b/docs/howto/initial-data.txt @@ -58,7 +58,7 @@ look like in JSON: And here's that same fixture as YAML: -.. code-block:: none +.. code-block:: yaml - model: myapp.person pk: 1 diff --git a/docs/howto/writing-migrations.txt b/docs/howto/writing-migrations.txt index 4596f64eb6..f98a56c534 100644 --- a/docs/howto/writing-migrations.txt +++ b/docs/howto/writing-migrations.txt @@ -39,8 +39,8 @@ attribute:: You can also provide hints that will be passed to the :meth:`allow_migrate()` method of database routers as ``**hints``: -.. snippet:: - :filename: myapp/dbrouters.py +.. code-block:: python + :caption: myapp/dbrouters.py class MyRouter: @@ -97,8 +97,8 @@ the respective field according to your needs. of the three new files) to the last migration, change ``AddField`` to ``AlterField``, and add imports of ``uuid`` and ``models``. For example: - .. snippet:: - :filename: 0006_remove_uuid_null.py + .. code-block:: python + :caption: 0006_remove_uuid_null.py # Generated by Django A.B on YYYY-MM-DD HH:MM from django.db import migrations, models @@ -121,8 +121,8 @@ the respective field according to your needs. * Edit the first migration file. The generated migration class should look similar to this: - .. snippet:: - :filename: 0004_add_uuid_field.py + .. code-block:: python + :caption: 0004_add_uuid_field.py class Migration(migrations.Migration): @@ -148,8 +148,8 @@ the respective field according to your needs. unique value (UUID in the example) for each existing row. Also add an import of ``uuid``. For example: - .. snippet:: - :filename: 0005_populate_uuid_values.py + .. code-block:: python + :caption: 0005_populate_uuid_values.py # Generated by Django A.B on YYYY-MM-DD HH:MM from django.db import migrations @@ -279,8 +279,8 @@ project anywhere without first installing and then uninstalling the old app. Here's a sample migration: -.. snippet:: - :filename: myapp/migrations/0124_move_old_app_to_new_app.py +.. code-block:: python + :caption: myapp/migrations/0124_move_old_app_to_new_app.py from django.apps import apps as global_apps from django.db import migrations diff --git a/docs/internals/contributing/writing-code/coding-style.txt b/docs/internals/contributing/writing-code/coding-style.txt index 36203e3ab7..4b37f1f3c6 100644 --- a/docs/internals/contributing/writing-code/coding-style.txt +++ b/docs/internals/contributing/writing-code/coding-style.txt @@ -123,8 +123,8 @@ Imports For example (comments are for explanatory purposes only): - .. snippet:: - :filename: django/contrib/admin/example.py + .. code-block:: python + :caption: django/contrib/admin/example.py # future from __future__ import unicode_literals diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 7ce2da08ef..973ed27644 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -446,8 +446,8 @@ Since this pattern involves a lot of boilerplate, Django provides the :func:`~django.test.utils.isolate_apps` instances are correctly installed, you should pass the set of targeted ``app_label`` as arguments: - .. snippet:: - :filename: tests/app_label/tests.py + .. code-block:: python + :caption: tests/app_label/tests.py from django.db import models from django.test import SimpleTestCase diff --git a/docs/internals/howto-release-django.txt b/docs/internals/howto-release-django.txt index f79fd363f8..6f91751616 100644 --- a/docs/internals/howto-release-django.txt +++ b/docs/internals/howto-release-django.txt @@ -62,8 +62,8 @@ You'll need a few things before getting started: * Access to Django's record on PyPI. Create a file with your credentials: - .. snippet:: - :filename: ~/.pypirc + .. code-block:: ini + :caption: ~/.pypirc [pypi] username:YourUsername diff --git a/docs/intro/overview.txt b/docs/intro/overview.txt index e091ab0229..82b7a71a60 100644 --- a/docs/intro/overview.txt +++ b/docs/intro/overview.txt @@ -25,8 +25,8 @@ The :doc:`data-model syntax </topics/db/models>` offers many rich ways of representing your models -- so far, it's been solving many years' worth of database-schema problems. Here's a quick example: -.. snippet:: - :filename: mysite/news/models.py +.. code-block:: python + :caption: mysite/news/models.py from django.db import models @@ -145,8 +145,8 @@ production ready :doc:`administrative interface </ref/contrib/admin/index>` -- a website that lets authenticated users add, change and delete objects. It's as easy as registering your model in the admin site: -.. snippet:: - :filename: mysite/news/models.py +.. code-block:: python + :caption: mysite/news/models.py from django.db import models @@ -156,8 +156,8 @@ as easy as registering your model in the admin site: content = models.TextField() reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE) -.. snippet:: - :filename: mysite/news/admin.py +.. code-block:: python + :caption: mysite/news/admin.py from django.contrib import admin @@ -188,8 +188,8 @@ to decouple URLs from Python code. Here's what a URLconf might look like for the ``Reporter``/``Article`` example above: -.. snippet:: - :filename: mysite/news/urls.py +.. code-block:: python + :caption: mysite/news/urls.py from django.urls import path @@ -228,8 +228,8 @@ Generally, a view retrieves data according to the parameters, loads a template and renders the template with the retrieved data. Here's an example view for ``year_archive`` from above: -.. snippet:: - :filename: mysite/news/views.py +.. code-block:: python + :caption: mysite/news/views.py from django.shortcuts import render @@ -257,8 +257,8 @@ in the first directory, it checks the second, and so on. Let's say the ``news/year_archive.html`` template was found. Here's what that might look like: -.. snippet:: html+django - :filename: mysite/news/templates/news/year_archive.html +.. code-block:: html+django + :caption: mysite/news/templates/news/year_archive.html {% extends "base.html" %} @@ -298,8 +298,8 @@ in templates: each template has to define only what's unique to that template. Here's what the "base.html" template, including the use of :doc:`static files </howto/static-files/index>`, might look like: -.. snippet:: html+django - :filename: mysite/templates/base.html +.. code-block:: html+django + :caption: mysite/templates/base.html {% load static %} <html> diff --git a/docs/intro/reusable-apps.txt b/docs/intro/reusable-apps.txt index 8b71b523a4..e76bab8173 100644 --- a/docs/intro/reusable-apps.txt +++ b/docs/intro/reusable-apps.txt @@ -141,8 +141,8 @@ this. For a small app like polls, this process isn't too difficult. 3. Create a file ``django-polls/README.rst`` with the following contents: - .. snippet:: - :filename: django-polls/README.rst + .. code-block:: rst + :caption: django-polls/README.rst ===== Polls @@ -188,8 +188,8 @@ this. For a small app like polls, this process isn't too difficult. explanation. Create a file ``django-polls/setup.py`` with the following contents: - .. snippet:: - :filename: django-polls/setup.py + .. code-block:: python + :caption: django-polls/setup.py import os from setuptools import find_packages, setup @@ -233,8 +233,8 @@ this. For a small app like polls, this process isn't too difficult. file, create a file ``django-polls/MANIFEST.in`` with the following contents: - .. snippet:: - :filename: django-polls/MANIFEST.in + .. code-block:: text + :caption: django-polls/MANIFEST.in include LICENSE include README.rst diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt index d387e2d6a7..db3340e702 100644 --- a/docs/intro/tutorial01.txt +++ b/docs/intro/tutorial01.txt @@ -243,8 +243,8 @@ Write your first view Let's write the first view. Open the file ``polls/views.py`` and put the following Python code in it: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.http import HttpResponse @@ -271,8 +271,8 @@ Your app directory should now look like:: In the ``polls/urls.py`` file include the following code: -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py from django.urls import path @@ -286,8 +286,8 @@ The next step is to point the root URLconf at the ``polls.urls`` module. In ``mysite/urls.py``, add an import for ``django.urls.include`` and insert an :func:`~django.urls.include` in the ``urlpatterns`` list, so you have: -.. snippet:: - :filename: mysite/urls.py +.. code-block:: python + :caption: mysite/urls.py from django.contrib import admin from django.urls import include, path diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index ea9c3dff56..4d2a62bec2 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -135,8 +135,8 @@ with a ``Question``. These concepts are represented by simple Python classes. Edit the :file:`polls/models.py` file so it looks like this: -.. snippet:: - :filename: polls/models.py +.. code-block:: python + :caption: polls/models.py from django.db import models @@ -211,8 +211,8 @@ is ``'polls.apps.PollsConfig'``. Edit the :file:`mysite/settings.py` file and add that dotted path to the :setting:`INSTALLED_APPS` setting. It'll look like this: -.. snippet:: - :filename: mysite/settings.py +.. code-block:: python + :caption: mysite/settings.py INSTALLED_APPS = [ 'polls.apps.PollsConfig', @@ -423,8 +423,8 @@ representation of this object. Let's fix that by editing the ``Question`` model :meth:`~django.db.models.Model.__str__` method to both ``Question`` and ``Choice``: -.. snippet:: - :filename: polls/models.py +.. code-block:: python + :caption: polls/models.py from django.db import models @@ -446,8 +446,8 @@ automatically-generated admin. Note these are normal Python methods. Let's add a custom method, just for demonstration: -.. snippet:: - :filename: polls/models.py +.. code-block:: python + :caption: polls/models.py import datetime @@ -644,8 +644,8 @@ Just one thing to do: we need to tell the admin that ``Question`` objects have an admin interface. To do this, open the :file:`polls/admin.py` file, and edit it to look like this: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py from django.contrib import admin diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt index 32c0c99fd1..de84ad0612 100644 --- a/docs/intro/tutorial03.txt +++ b/docs/intro/tutorial03.txt @@ -64,8 +64,8 @@ Writing more views Now let's add a few more views to ``polls/views.py``. These views are slightly different, because they take an argument: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id) @@ -80,8 +80,8 @@ slightly different, because they take an argument: Wire these new views into the ``polls.urls`` module by adding the following :func:`~django.urls.path` calls: -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py from django.urls import path @@ -147,8 +147,8 @@ in :doc:`Tutorial 2 </intro/tutorial02>`. Here's one stab at a new ``index()`` view, which displays the latest 5 poll questions in the system, separated by commas, according to publication date: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.http import HttpResponse @@ -196,8 +196,8 @@ Django simply as ``polls/index.html``. Put the following code in that template: -.. snippet:: html+django - :filename: polls/templates/polls/index.html +.. code-block:: html+django + :caption: polls/templates/polls/index.html {% if latest_question_list %} <ul> @@ -211,8 +211,8 @@ Put the following code in that template: Now let's update our ``index`` view in ``polls/views.py`` to use the template: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.http import HttpResponse from django.template import loader @@ -244,8 +244,8 @@ It's a very common idiom to load a template, fill a context and return an template. Django provides a shortcut. Here's the full ``index()`` view, rewritten: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.shortcuts import render @@ -273,8 +273,8 @@ Raising a 404 error Now, let's tackle the question detail view -- the page that displays the question text for a given poll. Here's the view: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.http import Http404 from django.shortcuts import render @@ -295,8 +295,8 @@ We'll discuss what you could put in that ``polls/detail.html`` template a bit later, but if you'd like to quickly get the above example working, a file containing just: -.. snippet:: html+django - :filename: polls/templates/polls/detail.html +.. code-block:: html+django + :caption: polls/templates/polls/detail.html {{ question }} @@ -309,8 +309,8 @@ It's a very common idiom to use :meth:`~django.db.models.query.QuerySet.get` and raise :exc:`~django.http.Http404` if the object doesn't exist. Django provides a shortcut. Here's the ``detail()`` view, rewritten: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.shortcuts import get_object_or_404, render @@ -351,8 +351,8 @@ Back to the ``detail()`` view for our poll application. Given the context variable ``question``, here's what the ``polls/detail.html`` template might look like: -.. snippet:: html+django - :filename: polls/templates/polls/detail.html +.. code-block:: html+django + :caption: polls/templates/polls/detail.html <h1>{{ question.question_text }}</h1> <ul> @@ -425,8 +425,8 @@ make it so that Django knows which app view to create for a url when using the The answer is to add namespaces to your URLconf. In the ``polls/urls.py`` file, go ahead and add an ``app_name`` to set the application namespace: -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py from django.urls import path @@ -442,15 +442,15 @@ file, go ahead and add an ``app_name`` to set the application namespace: Now change your ``polls/index.html`` template from: -.. snippet:: html+django - :filename: polls/templates/polls/index.html +.. code-block:: html+django + :caption: polls/templates/polls/index.html <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li> to point at the namespaced detail view: -.. snippet:: html+django - :filename: polls/templates/polls/index.html +.. code-block:: html+django + :caption: polls/templates/polls/index.html <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li> diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt index 65caef3043..2eacd297ed 100644 --- a/docs/intro/tutorial04.txt +++ b/docs/intro/tutorial04.txt @@ -12,8 +12,8 @@ Write a simple form Let's update our poll detail template ("polls/detail.html") from the last tutorial, so that the template contains an HTML ``<form>`` element: -.. snippet:: html+django - :filename: polls/templates/polls/detail.html +.. code-block:: html+django + :caption: polls/templates/polls/detail.html <h1>{{ question.question_text }}</h1> @@ -58,16 +58,16 @@ Now, let's create a Django view that handles the submitted data and does something with it. Remember, in :doc:`Tutorial 3 </intro/tutorial03>`, we created a URLconf for the polls application that includes this line: -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py path('<int:question_id>/vote/', views.vote, name='vote'), We also created a dummy implementation of the ``vote()`` function. Let's create a real version. Add the following to ``polls/views.py``: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404, render @@ -146,8 +146,8 @@ response documentation </ref/request-response>`. After somebody votes in a question, the ``vote()`` view redirects to the results page for the question. Let's write that view: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.shortcuts import get_object_or_404, render @@ -162,8 +162,8 @@ redundancy later. Now, create a ``polls/results.html`` template: -.. snippet:: html+django - :filename: polls/templates/polls/results.html +.. code-block:: html+django + :caption: polls/templates/polls/results.html <h1>{{ question.question_text }}</h1> @@ -234,8 +234,8 @@ Amend URLconf First, open the ``polls/urls.py`` URLconf and change it like so: -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py from django.urls import path @@ -259,8 +259,8 @@ Next, we're going to remove our old ``index``, ``detail``, and ``results`` views and use Django's generic views instead. To do so, open the ``polls/views.py`` file and change it like so: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render diff --git a/docs/intro/tutorial05.txt b/docs/intro/tutorial05.txt index ad5d09ca1d..222bbf4972 100644 --- a/docs/intro/tutorial05.txt +++ b/docs/intro/tutorial05.txt @@ -166,8 +166,8 @@ whose name begins with ``test``. Put the following in the ``tests.py`` file in the ``polls`` application: -.. snippet:: - :filename: polls/tests.py +.. code-block:: python + :caption: polls/tests.py import datetime @@ -248,8 +248,8 @@ return ``False`` if its ``pub_date`` is in the future. Amend the method in ``models.py``, so that it will only return ``True`` if the date is also in the past: -.. snippet:: - :filename: polls/models.py +.. code-block:: python + :caption: polls/models.py def was_published_recently(self): now = timezone.now() @@ -284,8 +284,8 @@ introduced another. Add two more test methods to the same class, to test the behavior of the method more comprehensively: -.. snippet:: - :filename: polls/tests.py +.. code-block:: python + :caption: polls/tests.py def test_was_published_recently_with_old_question(self): """ @@ -400,8 +400,8 @@ The list of polls shows polls that aren't published yet (i.e. those that have a In :doc:`Tutorial 4 </intro/tutorial04>` we introduced a class-based view, based on :class:`~django.views.generic.list.ListView`: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py class IndexView(generic.ListView): template_name = 'polls/index.html' @@ -415,15 +415,15 @@ We need to amend the ``get_queryset()`` method and change it so that it also checks the date by comparing it with ``timezone.now()``. First we need to add an import: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py from django.utils import timezone and then we must amend the ``get_queryset`` method like so: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py def get_queryset(self): """ @@ -450,16 +450,16 @@ our :djadmin:`shell` session above. Add the following to ``polls/tests.py``: -.. snippet:: - :filename: polls/tests.py +.. code-block:: python + :caption: polls/tests.py from django.urls import reverse and we'll create a shortcut function to create questions as well as a new test class: -.. snippet:: - :filename: polls/tests.py +.. code-block:: python + :caption: polls/tests.py def create_question(question_text, days): """ @@ -559,8 +559,8 @@ What we have works well; however, even though future questions don't appear in the *index*, users can still reach them if they know or guess the right URL. So we need to add a similar constraint to ``DetailView``: -.. snippet:: - :filename: polls/views.py +.. code-block:: python + :caption: polls/views.py class DetailView(generic.DetailView): ... @@ -574,8 +574,8 @@ And of course, we will add some tests, to check that a ``Question`` whose ``pub_date`` is in the past can be displayed, and that one with a ``pub_date`` in the future is not: -.. snippet:: - :filename: polls/tests.py +.. code-block:: python + :caption: polls/tests.py class QuestionDetailViewTests(TestCase): def test_future_question(self): diff --git a/docs/intro/tutorial06.txt b/docs/intro/tutorial06.txt index dff3bc1e2c..db1f1f47fd 100644 --- a/docs/intro/tutorial06.txt +++ b/docs/intro/tutorial06.txt @@ -56,8 +56,8 @@ reference the path for templates. Put the following code in that stylesheet (``polls/static/polls/style.css``): -.. snippet:: css - :filename: polls/static/polls/style.css +.. code-block:: css + :caption: polls/static/polls/style.css li a { color: green; @@ -65,8 +65,8 @@ Put the following code in that stylesheet (``polls/static/polls/style.css``): Next, add the following at the top of ``polls/templates/polls/index.html``: -.. snippet:: html+django - :filename: polls/templates/polls/index.html +.. code-block:: html+django + :caption: polls/templates/polls/index.html {% load static %} @@ -88,8 +88,8 @@ called ``background.gif``. In other words, put your image in Then, add to your stylesheet (``polls/static/polls/style.css``): -.. snippet:: css - :filename: polls/static/polls/style.css +.. code-block:: css + :caption: polls/static/polls/style.css body { background: white url("images/background.gif") no-repeat; diff --git a/docs/intro/tutorial07.txt b/docs/intro/tutorial07.txt index 5924f55c6a..001c6ec998 100644 --- a/docs/intro/tutorial07.txt +++ b/docs/intro/tutorial07.txt @@ -18,8 +18,8 @@ Django the options you want when you register the object. Let's see how this works by reordering the fields on the edit form. Replace the ``admin.site.register(Question)`` line with: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py from django.contrib import admin @@ -47,8 +47,8 @@ of fields, choosing an intuitive order is an important usability detail. And speaking of forms with dozens of fields, you might want to split the form up into fieldsets: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py from django.contrib import admin @@ -81,8 +81,8 @@ Yet. There are two ways to solve this problem. The first is to register ``Choice`` with the admin just as we did with ``Question``. That's easy: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py from django.contrib import admin @@ -115,8 +115,8 @@ It'd be better if you could add a bunch of Choices directly when you create the Remove the ``register()`` call for the ``Choice`` model. Then, edit the ``Question`` registration code to read: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py from django.contrib import admin @@ -162,8 +162,8 @@ fields for entering related ``Choice`` objects. For that reason, Django offers a tabular way of displaying inline related objects; you just need to change the ``ChoiceInline`` declaration to read: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py class ChoiceInline(admin.TabularInline): #... @@ -194,8 +194,8 @@ more helpful if we could display individual fields. To do that, use the tuple of field names to display, as columns, on the change list page for the object: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py class QuestionAdmin(admin.ModelAdmin): # ... @@ -204,8 +204,8 @@ object: Just for good measure, let's also include the ``was_published_recently()`` method from :doc:`Tutorial 2 </intro/tutorial02>`: -.. snippet:: - :filename: polls/admin.py +.. code-block:: python + :caption: polls/admin.py class QuestionAdmin(admin.ModelAdmin): # ... @@ -226,8 +226,8 @@ representation of the output. You can improve that by giving that method (in :file:`polls/models.py`) a few attributes, as follows: -.. snippet:: - :filename: polls/models.py +.. code-block:: python + :caption: polls/models.py class Question(models.Model): # ... @@ -301,8 +301,8 @@ keeping your templates within the project is a good convention to follow. Open your settings file (:file:`mysite/settings.py`, remember) and add a :setting:`DIRS <TEMPLATES-DIRS>` option in the :setting:`TEMPLATES` setting: -.. snippet:: - :filename: mysite/settings.py +.. code-block:: python + :caption: mysite/settings.py TEMPLATES = [ { diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index d317ad4083..c28453006c 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -2929,8 +2929,8 @@ instantiate any other Python class) and register your models and ``ModelAdmin`` subclasses with it instead of with the default site. Finally, update :file:`myproject/urls.py` to reference your :class:`AdminSite` subclass. -.. snippet:: - :filename: myapp/admin.py +.. code-block:: python + :caption: myapp/admin.py from django.contrib.admin import AdminSite @@ -2943,8 +2943,8 @@ update :file:`myproject/urls.py` to reference your :class:`AdminSite` subclass. admin_site.register(MyModel) -.. snippet:: - :filename: myproject/urls.py +.. code-block:: python + :caption: myproject/urls.py from django.urls import path @@ -2972,24 +2972,24 @@ You can override the default ``django.contrib.admin.site`` by setting the to the dotted import path of either a ``AdminSite`` subclass or a callable that returns a site instance. -.. snippet:: - :filename: myproject/admin.py +.. code-block:: python + :caption: myproject/admin.py from django.contrib import admin class MyAdminSite(admin.AdminSite): ... -.. snippet:: - :filename: myproject/apps.py +.. code-block:: python + :caption: myproject/apps.py from django.contrib.admin.apps import AdminConfig class MyAdminConfig(AdminConfig): default_site = 'myproject.admin.MyAdminSite' -.. snippet:: - :filename: myproject/settings.py +.. code-block:: python + :caption: myproject/settings.py INSTALLED_APPS = [ ... diff --git a/docs/ref/contrib/admin/javascript.txt b/docs/ref/contrib/admin/javascript.txt index 52374800b4..bf94655f38 100644 --- a/docs/ref/contrib/admin/javascript.txt +++ b/docs/ref/contrib/admin/javascript.txt @@ -31,8 +31,8 @@ In your custom ``change_form.html`` template, extend the <script type="text/javascript" src="{% static 'app/formset_handlers.js' %}"></script> {% endblock %} -.. snippet:: javascript - :filename: app/static/app/formset_handlers.js +.. code-block:: javascript + :caption: app/static/app/formset_handlers.js (function($) { $(document).on('formset:added', function(event, $row, formsetName) { @@ -69,8 +69,8 @@ namespace, just listen to the event triggered from there. For example: <script type="text/javascript" src="{% static 'app/unregistered_handlers.js' %}"></script> {% endblock %} -.. snippet:: javascript - :filename: app/static/app/unregistered_handlers.js +.. code-block:: javascript + :caption: app/static/app/unregistered_handlers.js django.jQuery(document).on('formset:added', function(event, $row, formsetName) { // Row added diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index 281b3144ae..2f2629cc69 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -314,8 +314,8 @@ The ``Func`` API is as follows: ``arg_joiner``, and any other ``**extra_context`` parameters to customize the SQL as needed. For example: - .. snippet:: - :filename: django/db/models/functions.py + .. code-block:: python + :caption: django/db/models/functions.py class ConcatPair(Func): ... diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index c66b600130..8c3f9ae7ba 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -1194,8 +1194,8 @@ Relationships defined this way on :ref:`abstract models <abstract-base-classes>` are resolved when the model is subclassed as a concrete model and are not relative to the abstract model's ``app_label``: -.. snippet:: - :filename: products/models.py +.. code-block:: python + :caption: products/models.py from django.db import models @@ -1205,8 +1205,8 @@ concrete model and are not relative to the abstract model's ``app_label``: class Meta: abstract = True -.. snippet:: - :filename: production/models.py +.. code-block:: python + :caption: production/models.py from django.db import models from products.models import AbstractCar diff --git a/docs/ref/templates/language.txt b/docs/ref/templates/language.txt index a10cfde03b..1287f012c2 100644 --- a/docs/ref/templates/language.txt +++ b/docs/ref/templates/language.txt @@ -559,8 +559,8 @@ The auto-escaping tag passes its effect onto templates that extend the current one as well as templates included via the :ttag:`include` tag, just like all block tags. For example: -.. snippet:: - :filename: base.html +.. code-block:: html+django + :caption: base.html {% autoescape off %} <h1>{% block title %}{% endblock %}</h1> @@ -568,8 +568,8 @@ just like all block tags. For example: {% endblock %} {% endautoescape %} -.. snippet:: - :filename: child.html +.. code-block:: html+django + :caption: child.html {% extends "base.html" %} {% block title %}This & that{% endblock %} @@ -649,15 +649,15 @@ of all comments related to the current task with:: And of course you can easily access methods you've explicitly defined on your own models: -.. snippet:: - :filename: models.py +.. code-block:: python + :caption: models.py class Task(models.Model): def foo(self): return "bar" -.. snippet:: - :filename: template.html +.. code-block:: html+django + :caption: template.html {{ task.foo }} diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index 9fccbea08e..f4c29f4b72 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -1264,8 +1264,8 @@ attribute (as below). If the ``app_name`` is set in this new way, the ``namespace`` argument is no longer required. It will default to the value of ``app_name``. For example, the URL patterns in the tutorial are changed from: -.. snippet:: - :filename: mysite/urls.py +.. code-block:: python + :caption: mysite/urls.py urlpatterns = [ url(r'^polls/', include('polls.urls', namespace="polls")), @@ -1274,16 +1274,16 @@ attribute (as below). If the ``app_name`` is set in this new way, the to: -.. snippet:: - :filename: mysite/urls.py +.. code-block:: python + :caption: mysite/urls.py urlpatterns = [ url(r'^polls/', include('polls.urls')), # 'namespace="polls"' removed ... ] -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py app_name = 'polls' # added urlpatterns = [...] @@ -1292,8 +1292,8 @@ This change also means that the old way of including an ``AdminSite`` instance is deprecated. Instead, pass ``admin.site.urls`` directly to :func:`~django.conf.urls.url()`: -.. snippet:: - :filename: urls.py +.. code-block:: python + :caption: urls.py from django.conf.urls import url from django.contrib import admin diff --git a/docs/topics/auth/passwords.txt b/docs/topics/auth/passwords.txt index 7b72c4292d..fa2fddaa16 100644 --- a/docs/topics/auth/passwords.txt +++ b/docs/topics/auth/passwords.txt @@ -251,8 +251,8 @@ modify the pattern to work with any algorithm or with a custom user model. First, we'll add the custom hasher: -.. snippet:: - :filename: accounts/hashers.py +.. code-block:: python + :caption: accounts/hashers.py from django.contrib.auth.hashers import ( PBKDF2PasswordHasher, SHA1PasswordHasher, @@ -271,8 +271,8 @@ First, we'll add the custom hasher: The data migration might look something like: -.. snippet:: - :filename: accounts/migrations/0002_migrate_sha1_passwords.py +.. code-block:: python + :caption: accounts/migrations/0002_migrate_sha1_passwords.py from django.db import migrations @@ -306,8 +306,8 @@ several thousand users, depending on the speed of your hardware. Finally, we'll add a :setting:`PASSWORD_HASHERS` setting: -.. snippet:: - :filename: mysite/settings.py +.. code-block:: python + :caption: mysite/settings.py PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.PBKDF2PasswordHasher', diff --git a/docs/topics/class-based-views/generic-editing.txt b/docs/topics/class-based-views/generic-editing.txt index 15e136939f..a89483ec5a 100644 --- a/docs/topics/class-based-views/generic-editing.txt +++ b/docs/topics/class-based-views/generic-editing.txt @@ -18,8 +18,8 @@ Basic forms Given a simple contact form: -.. snippet:: - :filename: forms.py +.. code-block:: python + :caption: forms.py from django import forms @@ -33,8 +33,8 @@ Given a simple contact form: The view can be constructed using a ``FormView``: -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from myapp.forms import ContactForm from django.views.generic.edit import FormView @@ -96,8 +96,8 @@ add extra validation) simply set First we need to add :meth:`~django.db.models.Model.get_absolute_url()` to our ``Author`` class: -.. snippet:: - :filename: models.py +.. code-block:: python + :caption: models.py from django.db import models from django.urls import reverse @@ -112,8 +112,8 @@ Then we can use :class:`CreateView` and friends to do the actual work. Notice how we're just configuring the generic class-based views here; we don't have to write any logic ourselves: -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from django.urls import reverse_lazy from django.views.generic.edit import CreateView, DeleteView, UpdateView @@ -146,8 +146,8 @@ and :attr:`~django.views.generic.edit.FormMixin.form_class` attributes, an Finally, we hook these new views into the URLconf: -.. snippet:: - :filename: urls.py +.. code-block:: python + :caption: urls.py from django.urls import path from myapp.views import AuthorCreate, AuthorDelete, AuthorUpdate @@ -187,8 +187,8 @@ To track the user that created an object using a :class:`CreateView`, you can use a custom :class:`~django.forms.ModelForm` to do this. First, add the foreign key relation to the model: -.. snippet:: - :filename: models.py +.. code-block:: python + :caption: models.py from django.contrib.auth.models import User from django.db import models @@ -203,8 +203,8 @@ In the view, ensure that you don't include ``created_by`` in the list of fields to edit, and override :meth:`~django.views.generic.edit.ModelFormMixin.form_valid()` to add the user: -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from django.views.generic.edit import CreateView from myapp.models import Author diff --git a/docs/topics/class-based-views/mixins.txt b/docs/topics/class-based-views/mixins.txt index e066cfcfb5..ac0648df98 100644 --- a/docs/topics/class-based-views/mixins.txt +++ b/docs/topics/class-based-views/mixins.txt @@ -222,8 +222,8 @@ we'll want the functionality provided by We'll demonstrate this with the ``Author`` model we used in the :doc:`generic class-based views introduction<generic-display>`. -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from django.http import HttpResponseForbidden, HttpResponseRedirect from django.urls import reverse @@ -255,8 +255,8 @@ mixin. We can hook this into our URLs easily enough: -.. snippet:: - :filename: urls.py +.. code-block:: python + :caption: urls.py from django.urls import path from books.views import RecordInterest diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 74ec4dc230..e61b91c81c 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -1429,8 +1429,8 @@ store your models. You must import the models in the ``__init__.py`` file. For example, if you had ``organic.py`` and ``synthetic.py`` in the ``models`` directory: -.. snippet:: - :filename: myapp/models/__init__.py +.. code-block:: python + :caption: myapp/models/__init__.py from .organic import Person from .synthetic import Robot diff --git a/docs/topics/forms/index.txt b/docs/topics/forms/index.txt index f8ef20a9bc..8340c0f096 100644 --- a/docs/topics/forms/index.txt +++ b/docs/topics/forms/index.txt @@ -226,8 +226,8 @@ The :class:`Form` class We already know what we want our HTML form to look like. Our starting point for it in Django is this: -.. snippet:: - :filename: forms.py +.. code-block:: python + :caption: forms.py from django import forms @@ -276,8 +276,8 @@ logic. To handle the form we need to instantiate it in the view for the URL where we want it to be published: -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from django.http import HttpResponseRedirect from django.shortcuts import render @@ -404,8 +404,8 @@ More on fields Consider a more useful form than our minimal example above, which we could use to implement "contact me" functionality on a personal website: -.. snippet:: - :filename: forms.py +.. code-block:: python + :caption: forms.py from django import forms @@ -453,8 +453,8 @@ values to a Python ``int`` and ``float`` respectively. Here's how the form data could be processed in the view that handles this form: -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from django.core.mail import send_mail diff --git a/docs/topics/http/file-uploads.txt b/docs/topics/http/file-uploads.txt index 46ebf2e52a..21a6f06853 100644 --- a/docs/topics/http/file-uploads.txt +++ b/docs/topics/http/file-uploads.txt @@ -21,8 +21,8 @@ Basic file uploads Consider a simple form containing a :class:`~django.forms.FileField`: -.. snippet:: - :filename: forms.py +.. code-block:: python + :caption: forms.py from django import forms @@ -46,8 +46,8 @@ Most of the time, you'll simply pass the file data from ``request`` into the form as described in :ref:`binding-uploaded-files`. This would look something like: -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from django.http import HttpResponseRedirect from django.shortcuts import render @@ -133,8 +133,8 @@ Uploading multiple files If you want to upload multiple files using one form field, set the ``multiple`` HTML attribute of field's widget: -.. snippet:: - :filename: forms.py +.. code-block:: python + :caption: forms.py from django import forms @@ -145,8 +145,8 @@ Then override the ``post`` method of your :class:`~django.views.generic.edit.FormView` subclass to handle multiple file uploads: -.. snippet:: - :filename: views.py +.. code-block:: python + :caption: views.py from django.views.generic.edit import FormView from .forms import FileFieldForm diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt index 4ee7a4e9ba..50d63e9a88 100644 --- a/docs/topics/http/urls.txt +++ b/docs/topics/http/urls.txt @@ -761,8 +761,8 @@ and one called ``'publisher-polls'``. Assume we have enhanced that application so that it takes the instance namespace into consideration when creating and displaying polls. -.. snippet:: - :filename: urls.py +.. code-block:: python + :caption: urls.py from django.urls import include, path @@ -771,8 +771,8 @@ displaying polls. path('publisher-polls/', include('polls.urls', namespace='publisher-polls')), ] -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py from django.urls import path @@ -830,8 +830,8 @@ at the same level as the ``urlpatterns`` attribute. You have to pass the actual module, or a string reference to the module, to :func:`~django.urls.include`, not the list of ``urlpatterns`` itself. -.. snippet:: - :filename: polls/urls.py +.. code-block:: python + :caption: polls/urls.py from django.urls import path @@ -844,8 +844,8 @@ not the list of ``urlpatterns`` itself. ... ] -.. snippet:: - :filename: urls.py +.. code-block:: python + :caption: urls.py from django.urls import include, path diff --git a/docs/topics/logging.txt b/docs/topics/logging.txt index 5772df0341..0e0700c618 100644 --- a/docs/topics/logging.txt +++ b/docs/topics/logging.txt @@ -429,8 +429,8 @@ configuration process for :ref:`Django's default logging <default-logging-configuration>`. Here's an example that disables Django's logging configuration and then manually configures logging: -.. snippet:: - :filename: settings.py +.. code-block:: python + :caption: settings.py LOGGING_CONFIG = None diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt index 7e65a896f2..455c121acd 100644 --- a/docs/topics/testing/advanced.txt +++ b/docs/topics/testing/advanced.txt @@ -325,8 +325,8 @@ following structure:: Let's take a look inside a couple of those files: -.. snippet:: - :filename: runtests.py +.. code-block:: python + :caption: runtests.py #!/usr/bin/env python import os @@ -353,8 +353,8 @@ necessary to use the Django test runner. You may want to add command-line options for controlling verbosity, passing in specific test labels to run, etc. -.. snippet:: - :filename: tests/test_settings.py +.. code-block:: python + :caption: tests/test_settings.py SECRET_KEY = 'fake-key' INSTALLED_APPS = [