[2.1.x] Refs #20910 -- Replaced snippet directive with code-block.
Backport of c49ea6f591
from master
This commit is contained in:
parent
2b2474b75d
commit
1853e2dbf2
|
@ -6,14 +6,13 @@ import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.parsers.rst import Directive, directives
|
from docutils.parsers.rst import Directive
|
||||||
from docutils.statemachine import ViewList
|
from docutils.statemachine import ViewList
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.directives import CodeBlock
|
from sphinx.directives import CodeBlock
|
||||||
from sphinx.domains.std import Cmdoption
|
from sphinx.domains.std import Cmdoption
|
||||||
from sphinx.util.console import bold
|
from sphinx.util.console import bold
|
||||||
from sphinx.util.nodes import set_source_info
|
|
||||||
from sphinx.writers.html import HTMLTranslator
|
from sphinx.writers.html import HTMLTranslator
|
||||||
|
|
||||||
# RE for option descriptions without a '--' prefix
|
# RE for option descriptions without a '--' prefix
|
||||||
|
@ -53,17 +52,6 @@ def setup(app):
|
||||||
app.add_directive('versionadded', VersionDirective)
|
app.add_directive('versionadded', VersionDirective)
|
||||||
app.add_directive('versionchanged', VersionDirective)
|
app.add_directive('versionchanged', VersionDirective)
|
||||||
app.add_builder(DjangoStandaloneHTMLBuilder)
|
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('djangohtml', DjangoHTMLTranslator)
|
||||||
app.set_translator('json', DjangoHTMLTranslator)
|
app.set_translator('json', DjangoHTMLTranslator)
|
||||||
app.add_node(
|
app.add_node(
|
||||||
|
@ -79,133 +67,6 @@ def setup(app):
|
||||||
return {'parallel_read_safe': True}
|
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):
|
class VersionDirective(Directive):
|
||||||
has_content = True
|
has_content = True
|
||||||
required_arguments = 1
|
required_arguments = 1
|
||||||
|
|
|
@ -29,15 +29,14 @@ pre {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header for some code blocks. */
|
/* Header for some code blocks. */
|
||||||
.snippet-filename {
|
.code-block-caption {
|
||||||
background-color: #393939;
|
background-color: #393939;
|
||||||
color: white;
|
color: white;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
font: bold 90% monospace;
|
font: bold 90% monospace;
|
||||||
}
|
}
|
||||||
.snippet-filename + .highlight > pre,
|
.literal-block-wrapper pre {
|
||||||
.snippet-filename + pre {
|
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,9 +101,8 @@ pre { font-size:small; background:#E0FFB8; border:1px solid #94da3a; border-widt
|
||||||
dt .literal, table .literal { background:none; }
|
dt .literal, table .literal { background:none; }
|
||||||
#bd a.reference { text-decoration: none; }
|
#bd a.reference { text-decoration: none; }
|
||||||
#bd a.reference tt.literal { border-bottom: 1px #234f32 dotted; }
|
#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.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.snippet-filename + div.highlight > pre { margin-top: 0; }
|
div.literal-block-wrapper pre { margin-top: 0; }
|
||||||
div.snippet-filename + pre { margin-top: 0; }
|
|
||||||
|
|
||||||
/* Restore colors of pygments hyperlinked code */
|
/* 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; }
|
#bd .highlight .k a:link, #bd .highlight .k a:visited { color: #000000; text-decoration: none; border-bottom: 1px dotted #000000; }
|
||||||
|
|
|
@ -58,7 +58,7 @@ look like in JSON:
|
||||||
|
|
||||||
And here's that same fixture as YAML:
|
And here's that same fixture as YAML:
|
||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: yaml
|
||||||
|
|
||||||
- model: myapp.person
|
- model: myapp.person
|
||||||
pk: 1
|
pk: 1
|
||||||
|
|
|
@ -39,8 +39,8 @@ attribute::
|
||||||
You can also provide hints that will be passed to the :meth:`allow_migrate()`
|
You can also provide hints that will be passed to the :meth:`allow_migrate()`
|
||||||
method of database routers as ``**hints``:
|
method of database routers as ``**hints``:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myapp/dbrouters.py
|
:caption: myapp/dbrouters.py
|
||||||
|
|
||||||
class MyRouter:
|
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
|
of the three new files) to the last migration, change ``AddField`` to
|
||||||
``AlterField``, and add imports of ``uuid`` and ``models``. For example:
|
``AlterField``, and add imports of ``uuid`` and ``models``. For example:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: 0006_remove_uuid_null.py
|
:caption: 0006_remove_uuid_null.py
|
||||||
|
|
||||||
# Generated by Django A.B on YYYY-MM-DD HH:MM
|
# Generated by Django A.B on YYYY-MM-DD HH:MM
|
||||||
from django.db import migrations, models
|
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
|
* Edit the first migration file. The generated migration class should look
|
||||||
similar to this:
|
similar to this:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: 0004_add_uuid_field.py
|
:caption: 0004_add_uuid_field.py
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
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
|
unique value (UUID in the example) for each existing row. Also add an import
|
||||||
of ``uuid``. For example:
|
of ``uuid``. For example:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: 0005_populate_uuid_values.py
|
:caption: 0005_populate_uuid_values.py
|
||||||
|
|
||||||
# Generated by Django A.B on YYYY-MM-DD HH:MM
|
# Generated by Django A.B on YYYY-MM-DD HH:MM
|
||||||
from django.db import migrations
|
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:
|
Here's a sample migration:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myapp/migrations/0124_move_old_app_to_new_app.py
|
:caption: myapp/migrations/0124_move_old_app_to_new_app.py
|
||||||
|
|
||||||
from django.apps import apps as global_apps
|
from django.apps import apps as global_apps
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
|
@ -123,8 +123,8 @@ Imports
|
||||||
|
|
||||||
For example (comments are for explanatory purposes only):
|
For example (comments are for explanatory purposes only):
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: django/contrib/admin/example.py
|
:caption: django/contrib/admin/example.py
|
||||||
|
|
||||||
# future
|
# future
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
|
@ -446,8 +446,8 @@ Since this pattern involves a lot of boilerplate, Django provides the
|
||||||
:func:`~django.test.utils.isolate_apps` instances are correctly
|
:func:`~django.test.utils.isolate_apps` instances are correctly
|
||||||
installed, you should pass the set of targeted ``app_label`` as arguments:
|
installed, you should pass the set of targeted ``app_label`` as arguments:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: tests/app_label/tests.py
|
:caption: tests/app_label/tests.py
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
|
|
|
@ -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:
|
* Access to Django's record on PyPI. Create a file with your credentials:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: ini
|
||||||
:filename: ~/.pypirc
|
:caption: ~/.pypirc
|
||||||
|
|
||||||
[pypi]
|
[pypi]
|
||||||
username:YourUsername
|
username:YourUsername
|
||||||
|
|
|
@ -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
|
representing your models -- so far, it's been solving many years' worth of
|
||||||
database-schema problems. Here's a quick example:
|
database-schema problems. Here's a quick example:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/news/models.py
|
:caption: mysite/news/models.py
|
||||||
|
|
||||||
from django.db import models
|
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
|
a website that lets authenticated users add, change and delete objects. It's
|
||||||
as easy as registering your model in the admin site:
|
as easy as registering your model in the admin site:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/news/models.py
|
:caption: mysite/news/models.py
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
@ -156,8 +156,8 @@ as easy as registering your model in the admin site:
|
||||||
content = models.TextField()
|
content = models.TextField()
|
||||||
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
|
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/news/admin.py
|
:caption: mysite/news/admin.py
|
||||||
|
|
||||||
from django.contrib import admin
|
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``
|
Here's what a URLconf might look like for the ``Reporter``/``Article``
|
||||||
example above:
|
example above:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/news/urls.py
|
:caption: mysite/news/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
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
|
and renders the template with the retrieved data. Here's an example view for
|
||||||
``year_archive`` from above:
|
``year_archive`` from above:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/news/views.py
|
:caption: mysite/news/views.py
|
||||||
|
|
||||||
from django.shortcuts import render
|
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
|
Let's say the ``news/year_archive.html`` template was found. Here's what that
|
||||||
might look like:
|
might look like:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: mysite/news/templates/news/year_archive.html
|
:caption: mysite/news/templates/news/year_archive.html
|
||||||
|
|
||||||
{% extends "base.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
|
Here's what the "base.html" template, including the use of :doc:`static files
|
||||||
</howto/static-files/index>`, might look like:
|
</howto/static-files/index>`, might look like:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: mysite/templates/base.html
|
:caption: mysite/templates/base.html
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
<html>
|
<html>
|
||||||
|
|
|
@ -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:
|
3. Create a file ``django-polls/README.rst`` with the following contents:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: rst
|
||||||
:filename: django-polls/README.rst
|
:caption: django-polls/README.rst
|
||||||
|
|
||||||
=====
|
=====
|
||||||
Polls
|
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
|
explanation. Create a file ``django-polls/setup.py`` with the following
|
||||||
contents:
|
contents:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: django-polls/setup.py
|
:caption: django-polls/setup.py
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from setuptools import find_packages, setup
|
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
|
file, create a file ``django-polls/MANIFEST.in`` with the following
|
||||||
contents:
|
contents:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: text
|
||||||
:filename: django-polls/MANIFEST.in
|
:caption: django-polls/MANIFEST.in
|
||||||
|
|
||||||
include LICENSE
|
include LICENSE
|
||||||
include README.rst
|
include README.rst
|
||||||
|
|
|
@ -243,8 +243,8 @@ Write your first view
|
||||||
Let's write the first view. Open the file ``polls/views.py``
|
Let's write the first view. Open the file ``polls/views.py``
|
||||||
and put the following Python code in it:
|
and put the following Python code in it:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.http import HttpResponse
|
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:
|
In the ``polls/urls.py`` file include the following code:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
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
|
``mysite/urls.py``, add an import for ``django.urls.include`` and insert an
|
||||||
:func:`~django.urls.include` in the ``urlpatterns`` list, so you have:
|
:func:`~django.urls.include` in the ``urlpatterns`` list, so you have:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/urls.py
|
:caption: mysite/urls.py
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
|
|
@ -135,8 +135,8 @@ with a ``Question``.
|
||||||
These concepts are represented by simple Python classes. Edit the
|
These concepts are represented by simple Python classes. Edit the
|
||||||
:file:`polls/models.py` file so it looks like this:
|
:file:`polls/models.py` file so it looks like this:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/models.py
|
:caption: polls/models.py
|
||||||
|
|
||||||
from django.db import models
|
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
|
add that dotted path to the :setting:`INSTALLED_APPS` setting. It'll look like
|
||||||
this:
|
this:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/settings.py
|
:caption: mysite/settings.py
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
'polls.apps.PollsConfig',
|
'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
|
:meth:`~django.db.models.Model.__str__` method to both ``Question`` and
|
||||||
``Choice``:
|
``Choice``:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/models.py
|
:caption: polls/models.py
|
||||||
|
|
||||||
from django.db import models
|
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
|
Note these are normal Python methods. Let's add a custom method, just for
|
||||||
demonstration:
|
demonstration:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/models.py
|
:caption: polls/models.py
|
||||||
|
|
||||||
import datetime
|
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`
|
objects have an admin interface. To do this, open the :file:`polls/admin.py`
|
||||||
file, and edit it to look like this:
|
file, and edit it to look like this:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ Writing more views
|
||||||
Now let's add a few more views to ``polls/views.py``. These views are
|
Now let's add a few more views to ``polls/views.py``. These views are
|
||||||
slightly different, because they take an argument:
|
slightly different, because they take an argument:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
def detail(request, question_id):
|
def detail(request, question_id):
|
||||||
return HttpResponse("You're looking at question %s." % 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
|
Wire these new views into the ``polls.urls`` module by adding the following
|
||||||
:func:`~django.urls.path` calls:
|
:func:`~django.urls.path` calls:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
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
|
view, which displays the latest 5 poll questions in the system, separated by
|
||||||
commas, according to publication date:
|
commas, according to publication date:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
@ -196,8 +196,8 @@ Django simply as ``polls/index.html``.
|
||||||
|
|
||||||
Put the following code in that template:
|
Put the following code in that template:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/index.html
|
:caption: polls/templates/polls/index.html
|
||||||
|
|
||||||
{% if latest_question_list %}
|
{% if latest_question_list %}
|
||||||
<ul>
|
<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:
|
Now let's update our ``index`` view in ``polls/views.py`` to use the template:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.template import loader
|
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,
|
template. Django provides a shortcut. Here's the full ``index()`` view,
|
||||||
rewritten:
|
rewritten:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.shortcuts import render
|
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
|
Now, let's tackle the question detail view -- the page that displays the question text
|
||||||
for a given poll. Here's the view:
|
for a given poll. Here's the view:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.shortcuts import render
|
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
|
later, but if you'd like to quickly get the above example working, a file
|
||||||
containing just:
|
containing just:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/detail.html
|
:caption: polls/templates/polls/detail.html
|
||||||
|
|
||||||
{{ question }}
|
{{ 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
|
and raise :exc:`~django.http.Http404` if the object doesn't exist. Django
|
||||||
provides a shortcut. Here's the ``detail()`` view, rewritten:
|
provides a shortcut. Here's the ``detail()`` view, rewritten:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.shortcuts import get_object_or_404, render
|
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
|
variable ``question``, here's what the ``polls/detail.html`` template might look
|
||||||
like:
|
like:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/detail.html
|
:caption: polls/templates/polls/detail.html
|
||||||
|
|
||||||
<h1>{{ question.question_text }}</h1>
|
<h1>{{ question.question_text }}</h1>
|
||||||
<ul>
|
<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``
|
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:
|
file, go ahead and add an ``app_name`` to set the application namespace:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
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:
|
Now change your ``polls/index.html`` template from:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/index.html
|
:caption: polls/templates/polls/index.html
|
||||||
|
|
||||||
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
|
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
|
||||||
|
|
||||||
to point at the namespaced detail view:
|
to point at the namespaced detail view:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/index.html
|
:caption: polls/templates/polls/index.html
|
||||||
|
|
||||||
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
|
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ Write a simple form
|
||||||
Let's update our poll detail template ("polls/detail.html") from the last
|
Let's update our poll detail template ("polls/detail.html") from the last
|
||||||
tutorial, so that the template contains an HTML ``<form>`` element:
|
tutorial, so that the template contains an HTML ``<form>`` element:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/detail.html
|
:caption: polls/templates/polls/detail.html
|
||||||
|
|
||||||
<h1>{{ question.question_text }}</h1>
|
<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
|
something with it. Remember, in :doc:`Tutorial 3 </intro/tutorial03>`, we
|
||||||
created a URLconf for the polls application that includes this line:
|
created a URLconf for the polls application that includes this line:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
path('<int:question_id>/vote/', views.vote, name='vote'),
|
path('<int:question_id>/vote/', views.vote, name='vote'),
|
||||||
|
|
||||||
We also created a dummy implementation of the ``vote()`` function. Let's
|
We also created a dummy implementation of the ``vote()`` function. Let's
|
||||||
create a real version. Add the following to ``polls/views.py``:
|
create a real version. Add the following to ``polls/views.py``:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, render
|
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
|
After somebody votes in a question, the ``vote()`` view redirects to the results
|
||||||
page for the question. Let's write that view:
|
page for the question. Let's write that view:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
|
|
||||||
|
@ -162,8 +162,8 @@ redundancy later.
|
||||||
|
|
||||||
Now, create a ``polls/results.html`` template:
|
Now, create a ``polls/results.html`` template:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/results.html
|
:caption: polls/templates/polls/results.html
|
||||||
|
|
||||||
<h1>{{ question.question_text }}</h1>
|
<h1>{{ question.question_text }}</h1>
|
||||||
|
|
||||||
|
@ -234,8 +234,8 @@ Amend URLconf
|
||||||
|
|
||||||
First, open the ``polls/urls.py`` URLconf and change it like so:
|
First, open the ``polls/urls.py`` URLconf and change it like so:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
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
|
views and use Django's generic views instead. To do so, open the
|
||||||
``polls/views.py`` file and change it like so:
|
``polls/views.py`` file and change it like so:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
|
|
|
@ -166,8 +166,8 @@ whose name begins with ``test``.
|
||||||
|
|
||||||
Put the following in the ``tests.py`` file in the ``polls`` application:
|
Put the following in the ``tests.py`` file in the ``polls`` application:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/tests.py
|
:caption: polls/tests.py
|
||||||
|
|
||||||
import datetime
|
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
|
``models.py``, so that it will only return ``True`` if the date is also in the
|
||||||
past:
|
past:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/models.py
|
:caption: polls/models.py
|
||||||
|
|
||||||
def was_published_recently(self):
|
def was_published_recently(self):
|
||||||
now = timezone.now()
|
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
|
Add two more test methods to the same class, to test the behavior of the method
|
||||||
more comprehensively:
|
more comprehensively:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/tests.py
|
:caption: polls/tests.py
|
||||||
|
|
||||||
def test_was_published_recently_with_old_question(self):
|
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,
|
In :doc:`Tutorial 4 </intro/tutorial04>` we introduced a class-based view,
|
||||||
based on :class:`~django.views.generic.list.ListView`:
|
based on :class:`~django.views.generic.list.ListView`:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
class IndexView(generic.ListView):
|
class IndexView(generic.ListView):
|
||||||
template_name = 'polls/index.html'
|
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
|
checks the date by comparing it with ``timezone.now()``. First we need to add
|
||||||
an import:
|
an import:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
and then we must amend the ``get_queryset`` method like so:
|
and then we must amend the ``get_queryset`` method like so:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""
|
"""
|
||||||
|
@ -450,16 +450,16 @@ our :djadmin:`shell` session above.
|
||||||
|
|
||||||
Add the following to ``polls/tests.py``:
|
Add the following to ``polls/tests.py``:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/tests.py
|
:caption: polls/tests.py
|
||||||
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
and we'll create a shortcut function to create questions as well as a new test
|
and we'll create a shortcut function to create questions as well as a new test
|
||||||
class:
|
class:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/tests.py
|
:caption: polls/tests.py
|
||||||
|
|
||||||
def create_question(question_text, days):
|
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
|
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``:
|
we need to add a similar constraint to ``DetailView``:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/views.py
|
:caption: polls/views.py
|
||||||
|
|
||||||
class DetailView(generic.DetailView):
|
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``
|
``pub_date`` is in the past can be displayed, and that one with a ``pub_date``
|
||||||
in the future is not:
|
in the future is not:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/tests.py
|
:caption: polls/tests.py
|
||||||
|
|
||||||
class QuestionDetailViewTests(TestCase):
|
class QuestionDetailViewTests(TestCase):
|
||||||
def test_future_question(self):
|
def test_future_question(self):
|
||||||
|
|
|
@ -56,8 +56,8 @@ reference the path for templates.
|
||||||
|
|
||||||
Put the following code in that stylesheet (``polls/static/polls/style.css``):
|
Put the following code in that stylesheet (``polls/static/polls/style.css``):
|
||||||
|
|
||||||
.. snippet:: css
|
.. code-block:: css
|
||||||
:filename: polls/static/polls/style.css
|
:caption: polls/static/polls/style.css
|
||||||
|
|
||||||
li a {
|
li a {
|
||||||
color: green;
|
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``:
|
Next, add the following at the top of ``polls/templates/polls/index.html``:
|
||||||
|
|
||||||
.. snippet:: html+django
|
.. code-block:: html+django
|
||||||
:filename: polls/templates/polls/index.html
|
:caption: polls/templates/polls/index.html
|
||||||
|
|
||||||
{% load static %}
|
{% 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``):
|
Then, add to your stylesheet (``polls/static/polls/style.css``):
|
||||||
|
|
||||||
.. snippet:: css
|
.. code-block:: css
|
||||||
:filename: polls/static/polls/style.css
|
:caption: polls/static/polls/style.css
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: white url("images/background.gif") no-repeat;
|
background: white url("images/background.gif") no-repeat;
|
||||||
|
|
|
@ -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
|
Let's see how this works by reordering the fields on the edit form. Replace
|
||||||
the ``admin.site.register(Question)`` line with:
|
the ``admin.site.register(Question)`` line with:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
from django.contrib import admin
|
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
|
And speaking of forms with dozens of fields, you might want to split the form
|
||||||
up into fieldsets:
|
up into fieldsets:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
@ -81,8 +81,8 @@ Yet.
|
||||||
There are two ways to solve this problem. The first is to register ``Choice``
|
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:
|
with the admin just as we did with ``Question``. That's easy:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
from django.contrib import admin
|
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``
|
Remove the ``register()`` call for the ``Choice`` model. Then, edit the ``Question``
|
||||||
registration code to read:
|
registration code to read:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
from django.contrib import admin
|
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
|
tabular way of displaying inline related objects; you just need to change
|
||||||
the ``ChoiceInline`` declaration to read:
|
the ``ChoiceInline`` declaration to read:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
class ChoiceInline(admin.TabularInline):
|
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
|
tuple of field names to display, as columns, on the change list page for the
|
||||||
object:
|
object:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
class QuestionAdmin(admin.ModelAdmin):
|
class QuestionAdmin(admin.ModelAdmin):
|
||||||
# ...
|
# ...
|
||||||
|
@ -204,8 +204,8 @@ object:
|
||||||
Just for good measure, let's also include the ``was_published_recently()``
|
Just for good measure, let's also include the ``was_published_recently()``
|
||||||
method from :doc:`Tutorial 2 </intro/tutorial02>`:
|
method from :doc:`Tutorial 2 </intro/tutorial02>`:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/admin.py
|
:caption: polls/admin.py
|
||||||
|
|
||||||
class QuestionAdmin(admin.ModelAdmin):
|
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
|
You can improve that by giving that method (in :file:`polls/models.py`) a few
|
||||||
attributes, as follows:
|
attributes, as follows:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/models.py
|
:caption: polls/models.py
|
||||||
|
|
||||||
class Question(models.Model):
|
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
|
Open your settings file (:file:`mysite/settings.py`, remember) and add a
|
||||||
:setting:`DIRS <TEMPLATES-DIRS>` option in the :setting:`TEMPLATES` setting:
|
:setting:`DIRS <TEMPLATES-DIRS>` option in the :setting:`TEMPLATES` setting:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/settings.py
|
:caption: mysite/settings.py
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -2933,8 +2933,8 @@ instantiate any other Python class) and register your models and
|
||||||
``ModelAdmin`` subclasses with it instead of with the default site. Finally,
|
``ModelAdmin`` subclasses with it instead of with the default site. Finally,
|
||||||
update :file:`myproject/urls.py` to reference your :class:`AdminSite` subclass.
|
update :file:`myproject/urls.py` to reference your :class:`AdminSite` subclass.
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myapp/admin.py
|
:caption: myapp/admin.py
|
||||||
|
|
||||||
from django.contrib.admin import AdminSite
|
from django.contrib.admin import AdminSite
|
||||||
|
|
||||||
|
@ -2947,8 +2947,8 @@ update :file:`myproject/urls.py` to reference your :class:`AdminSite` subclass.
|
||||||
admin_site.register(MyModel)
|
admin_site.register(MyModel)
|
||||||
|
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myproject/urls.py
|
:caption: myproject/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
|
@ -2976,24 +2976,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
|
to the dotted import path of either a ``AdminSite`` subclass or a callable that
|
||||||
returns a site instance.
|
returns a site instance.
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myproject/admin.py
|
:caption: myproject/admin.py
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
class MyAdminSite(admin.AdminSite):
|
class MyAdminSite(admin.AdminSite):
|
||||||
...
|
...
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myproject/apps.py
|
:caption: myproject/apps.py
|
||||||
|
|
||||||
from django.contrib.admin.apps import AdminConfig
|
from django.contrib.admin.apps import AdminConfig
|
||||||
|
|
||||||
class MyAdminConfig(AdminConfig):
|
class MyAdminConfig(AdminConfig):
|
||||||
default_site = 'myproject.admin.MyAdminSite'
|
default_site = 'myproject.admin.MyAdminSite'
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myproject/settings.py
|
:caption: myproject/settings.py
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
...
|
...
|
||||||
|
|
|
@ -31,8 +31,8 @@ In your custom ``change_form.html`` template, extend the
|
||||||
<script type="text/javascript" src="{% static 'app/formset_handlers.js' %}"></script>
|
<script type="text/javascript" src="{% static 'app/formset_handlers.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
.. snippet:: javascript
|
.. code-block:: javascript
|
||||||
:filename: app/static/app/formset_handlers.js
|
:caption: app/static/app/formset_handlers.js
|
||||||
|
|
||||||
(function($) {
|
(function($) {
|
||||||
$(document).on('formset:added', function(event, $row, formsetName) {
|
$(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>
|
<script type="text/javascript" src="{% static 'app/unregistered_handlers.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
.. snippet:: javascript
|
.. code-block:: javascript
|
||||||
:filename: app/static/app/unregistered_handlers.js
|
:caption: app/static/app/unregistered_handlers.js
|
||||||
|
|
||||||
django.jQuery(document).on('formset:added', function(event, $row, formsetName) {
|
django.jQuery(document).on('formset:added', function(event, $row, formsetName) {
|
||||||
// Row added
|
// Row added
|
||||||
|
|
|
@ -314,8 +314,8 @@ The ``Func`` API is as follows:
|
||||||
``arg_joiner``, and any other ``**extra_context`` parameters to
|
``arg_joiner``, and any other ``**extra_context`` parameters to
|
||||||
customize the SQL as needed. For example:
|
customize the SQL as needed. For example:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: django/db/models/functions.py
|
:caption: django/db/models/functions.py
|
||||||
|
|
||||||
class ConcatPair(Func):
|
class ConcatPair(Func):
|
||||||
...
|
...
|
||||||
|
|
|
@ -1194,8 +1194,8 @@ Relationships defined this way on :ref:`abstract models
|
||||||
<abstract-base-classes>` are resolved when the model is subclassed as a
|
<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``:
|
concrete model and are not relative to the abstract model's ``app_label``:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: products/models.py
|
:caption: products/models.py
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
@ -1205,8 +1205,8 @@ concrete model and are not relative to the abstract model's ``app_label``:
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: production/models.py
|
:caption: production/models.py
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from products.models import AbstractCar
|
from products.models import AbstractCar
|
||||||
|
|
|
@ -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,
|
current one as well as templates included via the :ttag:`include` tag,
|
||||||
just like all block tags. For example:
|
just like all block tags. For example:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: html+django
|
||||||
:filename: base.html
|
:caption: base.html
|
||||||
|
|
||||||
{% autoescape off %}
|
{% autoescape off %}
|
||||||
<h1>{% block title %}{% endblock %}</h1>
|
<h1>{% block title %}{% endblock %}</h1>
|
||||||
|
@ -568,8 +568,8 @@ just like all block tags. For example:
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endautoescape %}
|
{% endautoescape %}
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: html+django
|
||||||
:filename: child.html
|
:caption: child.html
|
||||||
|
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}This & that{% endblock %}
|
{% 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
|
And of course you can easily access methods you've explicitly defined on your
|
||||||
own models:
|
own models:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: models.py
|
:caption: models.py
|
||||||
|
|
||||||
class Task(models.Model):
|
class Task(models.Model):
|
||||||
def foo(self):
|
def foo(self):
|
||||||
return "bar"
|
return "bar"
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: html+django
|
||||||
:filename: template.html
|
:caption: template.html
|
||||||
|
|
||||||
{{ task.foo }}
|
{{ task.foo }}
|
||||||
|
|
||||||
|
|
|
@ -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
|
``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:
|
``app_name``. For example, the URL patterns in the tutorial are changed from:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/urls.py
|
:caption: mysite/urls.py
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^polls/', include('polls.urls', namespace="polls")),
|
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:
|
to:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/urls.py
|
:caption: mysite/urls.py
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^polls/', include('polls.urls')), # 'namespace="polls"' removed
|
url(r'^polls/', include('polls.urls')), # 'namespace="polls"' removed
|
||||||
...
|
...
|
||||||
]
|
]
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
app_name = 'polls' # added
|
app_name = 'polls' # added
|
||||||
urlpatterns = [...]
|
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
|
is deprecated. Instead, pass ``admin.site.urls`` directly to
|
||||||
:func:`~django.conf.urls.url()`:
|
:func:`~django.conf.urls.url()`:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: urls.py
|
:caption: urls.py
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
|
@ -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:
|
First, we'll add the custom hasher:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: accounts/hashers.py
|
:caption: accounts/hashers.py
|
||||||
|
|
||||||
from django.contrib.auth.hashers import (
|
from django.contrib.auth.hashers import (
|
||||||
PBKDF2PasswordHasher, SHA1PasswordHasher,
|
PBKDF2PasswordHasher, SHA1PasswordHasher,
|
||||||
|
@ -271,8 +271,8 @@ First, we'll add the custom hasher:
|
||||||
|
|
||||||
The data migration might look something like:
|
The data migration might look something like:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: accounts/migrations/0002_migrate_sha1_passwords.py
|
:caption: accounts/migrations/0002_migrate_sha1_passwords.py
|
||||||
|
|
||||||
from django.db import migrations
|
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:
|
Finally, we'll add a :setting:`PASSWORD_HASHERS` setting:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: mysite/settings.py
|
:caption: mysite/settings.py
|
||||||
|
|
||||||
PASSWORD_HASHERS = [
|
PASSWORD_HASHERS = [
|
||||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||||
|
|
|
@ -18,8 +18,8 @@ Basic forms
|
||||||
|
|
||||||
Given a simple contact form:
|
Given a simple contact form:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: forms.py
|
:caption: forms.py
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ Given a simple contact form:
|
||||||
|
|
||||||
The view can be constructed using a ``FormView``:
|
The view can be constructed using a ``FormView``:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from myapp.forms import ContactForm
|
from myapp.forms import ContactForm
|
||||||
from django.views.generic.edit import FormView
|
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
|
First we need to add :meth:`~django.db.models.Model.get_absolute_url()` to our
|
||||||
``Author`` class:
|
``Author`` class:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: models.py
|
:caption: models.py
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
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
|
work. Notice how we're just configuring the generic class-based views
|
||||||
here; we don't have to write any logic ourselves:
|
here; we don't have to write any logic ourselves:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
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:
|
Finally, we hook these new views into the URLconf:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: urls.py
|
:caption: urls.py
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from myapp.views import AuthorCreate, AuthorDelete, AuthorUpdate
|
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
|
you can use a custom :class:`~django.forms.ModelForm` to do this. First, add
|
||||||
the foreign key relation to the model:
|
the foreign key relation to the model:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: models.py
|
:caption: models.py
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
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
|
to edit, and override
|
||||||
:meth:`~django.views.generic.edit.ModelFormMixin.form_valid()` to add the user:
|
:meth:`~django.views.generic.edit.ModelFormMixin.form_valid()` to add the user:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from django.views.generic.edit import CreateView
|
from django.views.generic.edit import CreateView
|
||||||
from myapp.models import Author
|
from myapp.models import Author
|
||||||
|
|
|
@ -222,8 +222,8 @@ we'll want the functionality provided by
|
||||||
We'll demonstrate this with the ``Author`` model we used in the
|
We'll demonstrate this with the ``Author`` model we used in the
|
||||||
:doc:`generic class-based views introduction<generic-display>`.
|
:doc:`generic class-based views introduction<generic-display>`.
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
@ -255,8 +255,8 @@ mixin.
|
||||||
|
|
||||||
We can hook this into our URLs easily enough:
|
We can hook this into our URLs easily enough:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: urls.py
|
:caption: urls.py
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from books.views import RecordInterest
|
from books.views import RecordInterest
|
||||||
|
|
|
@ -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``
|
For example, if you had ``organic.py`` and ``synthetic.py`` in the ``models``
|
||||||
directory:
|
directory:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: myapp/models/__init__.py
|
:caption: myapp/models/__init__.py
|
||||||
|
|
||||||
from .organic import Person
|
from .organic import Person
|
||||||
from .synthetic import Robot
|
from .synthetic import Robot
|
||||||
|
|
|
@ -226,8 +226,8 @@ The :class:`Form` class
|
||||||
We already know what we want our HTML form to look like. Our starting point for
|
We already know what we want our HTML form to look like. Our starting point for
|
||||||
it in Django is this:
|
it in Django is this:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: forms.py
|
:caption: forms.py
|
||||||
|
|
||||||
from django import forms
|
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
|
To handle the form we need to instantiate it in the view for the URL where we
|
||||||
want it to be published:
|
want it to be published:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import render
|
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
|
Consider a more useful form than our minimal example above, which we could use
|
||||||
to implement "contact me" functionality on a personal website:
|
to implement "contact me" functionality on a personal website:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: forms.py
|
:caption: forms.py
|
||||||
|
|
||||||
from django import forms
|
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:
|
Here's how the form data could be processed in the view that handles this form:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ Basic file uploads
|
||||||
|
|
||||||
Consider a simple form containing a :class:`~django.forms.FileField`:
|
Consider a simple form containing a :class:`~django.forms.FileField`:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: forms.py
|
:caption: forms.py
|
||||||
|
|
||||||
from django import forms
|
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
|
form as described in :ref:`binding-uploaded-files`. This would look
|
||||||
something like:
|
something like:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import render
|
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``
|
If you want to upload multiple files using one form field, set the ``multiple``
|
||||||
HTML attribute of field's widget:
|
HTML attribute of field's widget:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: forms.py
|
:caption: forms.py
|
||||||
|
|
||||||
from django import forms
|
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
|
:class:`~django.views.generic.edit.FormView` subclass to handle multiple file
|
||||||
uploads:
|
uploads:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: views.py
|
:caption: views.py
|
||||||
|
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
from .forms import FileFieldForm
|
from .forms import FileFieldForm
|
||||||
|
|
|
@ -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
|
so that it takes the instance namespace into consideration when creating and
|
||||||
displaying polls.
|
displaying polls.
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: urls.py
|
:caption: urls.py
|
||||||
|
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
|
||||||
|
@ -771,8 +771,8 @@ displaying polls.
|
||||||
path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
|
path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
|
||||||
]
|
]
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
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`,
|
module, or a string reference to the module, to :func:`~django.urls.include`,
|
||||||
not the list of ``urlpatterns`` itself.
|
not the list of ``urlpatterns`` itself.
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: polls/urls.py
|
:caption: polls/urls.py
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
|
@ -844,8 +844,8 @@ not the list of ``urlpatterns`` itself.
|
||||||
...
|
...
|
||||||
]
|
]
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: urls.py
|
:caption: urls.py
|
||||||
|
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
|
||||||
|
|
|
@ -429,8 +429,8 @@ configuration process for :ref:`Django's default logging
|
||||||
<default-logging-configuration>`. Here's an example that disables Django's
|
<default-logging-configuration>`. Here's an example that disables Django's
|
||||||
logging configuration and then manually configures logging:
|
logging configuration and then manually configures logging:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: settings.py
|
:caption: settings.py
|
||||||
|
|
||||||
LOGGING_CONFIG = None
|
LOGGING_CONFIG = None
|
||||||
|
|
||||||
|
|
|
@ -325,8 +325,8 @@ following structure::
|
||||||
|
|
||||||
Let's take a look inside a couple of those files:
|
Let's take a look inside a couple of those files:
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: runtests.py
|
:caption: runtests.py
|
||||||
|
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
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
|
command-line options for controlling verbosity, passing in specific test
|
||||||
labels to run, etc.
|
labels to run, etc.
|
||||||
|
|
||||||
.. snippet::
|
.. code-block:: python
|
||||||
:filename: tests/test_settings.py
|
:caption: tests/test_settings.py
|
||||||
|
|
||||||
SECRET_KEY = 'fake-key'
|
SECRET_KEY = 'fake-key'
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
|
Loading…
Reference in New Issue