mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #30573 -- Rephrased documentation to avoid words that minimise the involved difficulty.
This patch does not remove all occurrences of the words in question. Rather, I went through all of the occurrences of the words listed below, and judged if they a) suggested the reader had some kind of knowledge/experience, and b) if they added anything of value (including tone of voice, etc). I left most of the words alone. I looked at the following words: - simply/simple - easy/easier/easiest - obvious - just - merely - straightforward - ridiculous Thanks to Carlton Gibson for guidance on how to approach this issue, and to Tim Bell for providing the idea. But the enormous lion's share of thanks go to Adam Johnson for his patient and helpful review.
This commit is contained in:
committed by
Mariusz Felisiak
parent
addabc492b
commit
4a954cfd11
@@ -9,7 +9,7 @@ then change it." This works well for a majority of use cases. However, if you
|
||||
need to make the same change to many objects at once, this workflow can be
|
||||
quite tedious.
|
||||
|
||||
In these cases, Django's admin lets you write and register "actions" -- simple
|
||||
In these cases, Django's admin lets you write and register "actions" --
|
||||
functions that get called with a list of objects selected on the change list
|
||||
page.
|
||||
|
||||
@@ -43,7 +43,7 @@ Writing actions
|
||||
The easiest way to explain actions is by example, so let's dive in.
|
||||
|
||||
A common use case for admin actions is the bulk updating of a model. Imagine a
|
||||
simple news application with an ``Article`` model::
|
||||
news application with an ``Article`` model::
|
||||
|
||||
from django.db import models
|
||||
|
||||
@@ -71,7 +71,7 @@ Writing action functions
|
||||
------------------------
|
||||
|
||||
First, we'll need to write a function that gets called when the action is
|
||||
triggered from the admin. Action functions are just regular functions that take
|
||||
triggered from the admin. Action functions are regular functions that take
|
||||
three arguments:
|
||||
|
||||
* The current :class:`ModelAdmin`
|
||||
@@ -89,7 +89,7 @@ request object, but we will use the queryset::
|
||||
|
||||
For the best performance, we're using the queryset's :ref:`update method
|
||||
<topics-db-queries-update>`. Other types of actions might need to deal
|
||||
with each object individually; in these cases we'd just iterate over the
|
||||
with each object individually; in these cases we'd iterate over the
|
||||
queryset::
|
||||
|
||||
for obj in queryset:
|
||||
@@ -138,7 +138,7 @@ That code will give us an admin change list that looks something like this:
|
||||
.. image:: _images/adding-actions-to-the-modeladmin.png
|
||||
|
||||
That's really all there is to it! If you're itching to write your own actions,
|
||||
you now know enough to get started. The rest of this document just covers more
|
||||
you now know enough to get started. The rest of this document covers more
|
||||
advanced techniques.
|
||||
|
||||
Handling errors in actions
|
||||
@@ -159,12 +159,12 @@ advanced options.
|
||||
Actions as :class:`ModelAdmin` methods
|
||||
--------------------------------------
|
||||
|
||||
The example above shows the ``make_published`` action defined as a simple
|
||||
function. That's perfectly fine, but it's not perfect from a code design point
|
||||
of view: since the action is tightly coupled to the ``Article`` object, it
|
||||
makes sense to hook the action to the ``ArticleAdmin`` object itself.
|
||||
The example above shows the ``make_published`` action defined as a function.
|
||||
That's perfectly fine, but it's not perfect from a code design point of view:
|
||||
since the action is tightly coupled to the ``Article`` object, it makes sense
|
||||
to hook the action to the ``ArticleAdmin`` object itself.
|
||||
|
||||
That's easy enough to do::
|
||||
You can do it like this::
|
||||
|
||||
class ArticleAdmin(admin.ModelAdmin):
|
||||
...
|
||||
@@ -180,9 +180,9 @@ Notice first that we've moved ``make_published`` into a method and renamed the
|
||||
``'make_published'`` in ``actions`` instead of a direct function reference. This
|
||||
tells the :class:`ModelAdmin` to look up the action as a method.
|
||||
|
||||
Defining actions as methods gives the action more straightforward, idiomatic
|
||||
access to the :class:`ModelAdmin` itself, allowing the action to call any of the
|
||||
methods provided by the admin.
|
||||
Defining actions as methods gives the action more idiomatic access to the
|
||||
:class:`ModelAdmin` itself, allowing the action to call any of the methods
|
||||
provided by the admin.
|
||||
|
||||
.. _custom-admin-action:
|
||||
|
||||
@@ -208,17 +208,15 @@ performing an action:
|
||||
Actions that provide intermediate pages
|
||||
---------------------------------------
|
||||
|
||||
By default, after an action is performed the user is simply redirected back
|
||||
to the original change list page. However, some actions, especially more
|
||||
complex ones, will need to return intermediate pages. For example, the
|
||||
built-in delete action asks for confirmation before deleting the selected
|
||||
objects.
|
||||
By default, after an action is performed the user is redirected back to the
|
||||
original change list page. However, some actions, especially more complex ones,
|
||||
will need to return intermediate pages. For example, the built-in delete action
|
||||
asks for confirmation before deleting the selected objects.
|
||||
|
||||
To provide an intermediary page, simply return an
|
||||
:class:`~django.http.HttpResponse` (or subclass) from your action. For
|
||||
example, you might write a simple export function that uses Django's
|
||||
:doc:`serialization functions </topics/serialization>` to dump some selected
|
||||
objects as JSON::
|
||||
To provide an intermediary page, return an :class:`~django.http.HttpResponse`
|
||||
(or subclass) from your action. For example, you might write a export function
|
||||
that uses Django's :doc:`serialization functions </topics/serialization>` to
|
||||
dump some selected objects as JSON::
|
||||
|
||||
from django.core import serializers
|
||||
from django.http import HttpResponse
|
||||
@@ -236,7 +234,7 @@ This allows you to provide complex interaction logic on the intermediary
|
||||
pages. For example, if you wanted to provide a more complete export function,
|
||||
you'd want to let the user choose a format, and possibly a list of fields to
|
||||
include in the export. The best thing to do would be to write a small action
|
||||
that simply redirects to your custom export view::
|
||||
that redirects to your custom export view::
|
||||
|
||||
from django.contrib import admin
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
@@ -247,9 +245,9 @@ that simply redirects to your custom export view::
|
||||
ct = ContentType.objects.get_for_model(queryset.model)
|
||||
return HttpResponseRedirect("/export/?ct=%s&ids=%s" % (ct.pk, ",".join(selected)))
|
||||
|
||||
As you can see, the action is the simple part; all the complex logic would
|
||||
belong in your export view. This would need to deal with objects of any type,
|
||||
hence the business with the ``ContentType``.
|
||||
As you can see, the action is rather short; all the complex logic would belong
|
||||
in your export view. This would need to deal with objects of any type, hence
|
||||
the business with the ``ContentType``.
|
||||
|
||||
Writing this view is left as an exercise to the reader.
|
||||
|
||||
@@ -303,8 +301,7 @@ Disabling a site-wide action
|
||||
site-wide.
|
||||
|
||||
If, however, you need to re-enable a globally-disabled action for one
|
||||
particular model, simply list it explicitly in your ``ModelAdmin.actions``
|
||||
list::
|
||||
particular model, list it explicitly in your ``ModelAdmin.actions`` list::
|
||||
|
||||
# Globally disable delete selected
|
||||
admin.site.disable_action('delete_selected')
|
||||
@@ -323,8 +320,8 @@ Disabling a site-wide action
|
||||
Disabling all actions for a particular :class:`ModelAdmin`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want *no* bulk actions available for a given :class:`ModelAdmin`, simply
|
||||
set :attr:`ModelAdmin.actions` to ``None``::
|
||||
If you want *no* bulk actions available for a given :class:`ModelAdmin`, set
|
||||
:attr:`ModelAdmin.actions` to ``None``::
|
||||
|
||||
class MyModelAdmin(admin.ModelAdmin):
|
||||
actions = None
|
||||
|
||||
@@ -83,8 +83,7 @@ Other topics
|
||||
|
||||
The ``ModelAdmin`` class is the representation of a model in the admin
|
||||
interface. Usually, these are stored in a file named ``admin.py`` in your
|
||||
application. Let's take a look at a very simple example of
|
||||
the ``ModelAdmin``::
|
||||
application. Let's take a look at an example of the ``ModelAdmin``::
|
||||
|
||||
from django.contrib import admin
|
||||
from myproject.myapp.models import Author
|
||||
@@ -1195,8 +1194,8 @@ subclass::
|
||||
A read-only field can not only display data from a model's field, it can
|
||||
also display the output of a model's method or a method of the
|
||||
``ModelAdmin`` class itself. This is very similar to the way
|
||||
:attr:`ModelAdmin.list_display` behaves. This provides an easy way to use
|
||||
the admin interface to provide feedback on the status of the objects being
|
||||
:attr:`ModelAdmin.list_display` behaves. This provides a way to use the
|
||||
admin interface to provide feedback on the status of the objects being
|
||||
edited, for example::
|
||||
|
||||
from django.contrib import admin
|
||||
@@ -1742,7 +1741,7 @@ templates used by the :class:`ModelAdmin` views:
|
||||
kwargs['form'] = MySuperuserForm
|
||||
return super().get_form(request, obj, **kwargs)
|
||||
|
||||
You may also simply return a custom :class:`~django.forms.ModelForm` class
|
||||
You may also return a custom :class:`~django.forms.ModelForm` class
|
||||
directly.
|
||||
|
||||
.. method:: ModelAdmin.get_formsets_with_inlines(request, obj=None)
|
||||
@@ -2159,9 +2158,9 @@ return the uncompressed versions of the various JavaScript files, including
|
||||
Adding custom validation to the admin
|
||||
-------------------------------------
|
||||
|
||||
Adding custom validation of data in the admin is quite easy. The automatic
|
||||
admin interface reuses :mod:`django.forms`, and the ``ModelAdmin`` class gives
|
||||
you the ability define your own form::
|
||||
You can also add custom validation of data in the admin. The automatic admin
|
||||
interface reuses :mod:`django.forms`, and the ``ModelAdmin`` class gives you
|
||||
the ability define your own form::
|
||||
|
||||
class ArticleAdmin(admin.ModelAdmin):
|
||||
form = MyArticleAdminForm
|
||||
@@ -2535,8 +2534,7 @@ layout required for multiple widgets will vary depending on the intermediate
|
||||
model.
|
||||
|
||||
However, we still want to be able to edit that information inline. Fortunately,
|
||||
this is easy to do with inline admin models. Suppose we have the following
|
||||
models::
|
||||
we can do this with inline admin models. Suppose we have the following models::
|
||||
|
||||
from django.db import models
|
||||
|
||||
@@ -2560,7 +2558,7 @@ define an inline class for the ``Membership`` model::
|
||||
model = Membership
|
||||
extra = 1
|
||||
|
||||
This simple example uses the default ``InlineModelAdmin`` values for the
|
||||
This example uses the default ``InlineModelAdmin`` values for the
|
||||
``Membership`` model, and limits the extra add forms to one. This could be
|
||||
customized using any of the options available to ``InlineModelAdmin`` classes.
|
||||
|
||||
@@ -2633,9 +2631,9 @@ specific information.
|
||||
Overriding admin templates
|
||||
==========================
|
||||
|
||||
It is relatively easy to override many of the templates which the admin module
|
||||
uses to generate the various pages of an admin site. You can even override a
|
||||
few of these templates for a specific app, or a specific model.
|
||||
You can override many of the templates which the admin module uses to generate
|
||||
the various pages of an admin site. You can even override a few of these
|
||||
templates for a specific app, or a specific model.
|
||||
|
||||
Set up your projects admin template directories
|
||||
-----------------------------------------------
|
||||
@@ -2732,7 +2730,7 @@ app or per model. The following can:
|
||||
* ``submit_line.html``
|
||||
|
||||
For those templates that cannot be overridden in this way, you may still
|
||||
override them for your entire project. Just place the new version in your
|
||||
override them for your entire project by placing the new version in your
|
||||
``templates/admin`` directory. This is particularly useful to create custom 404
|
||||
and 500 pages.
|
||||
|
||||
@@ -2923,11 +2921,11 @@ Customizing the :class:`AdminSite` class
|
||||
----------------------------------------
|
||||
|
||||
If you'd like to set up your own admin site with custom behavior, you're free
|
||||
to subclass ``AdminSite`` and override or add anything you like. Then, simply
|
||||
create an instance of your ``AdminSite`` subclass (the same way you'd
|
||||
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.
|
||||
to subclass ``AdminSite`` and override or add anything you like. Then, create
|
||||
an instance of your ``AdminSite`` subclass (the same way you'd 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.
|
||||
|
||||
.. code-block:: python
|
||||
:caption: myapp/admin.py
|
||||
@@ -3000,9 +2998,9 @@ returns a site instance.
|
||||
Multiple admin sites in the same URLconf
|
||||
----------------------------------------
|
||||
|
||||
It's easy to create multiple instances of the admin site on the same
|
||||
Django-powered website. Just create multiple instances of ``AdminSite`` and
|
||||
root each one at a different URL.
|
||||
You can create multiple instances of the admin site on the same Django-powered
|
||||
website. Create multiple instances of ``AdminSite`` and place each one at a
|
||||
different URL.
|
||||
|
||||
In this example, the URLs ``/basic-admin/`` and ``/advanced-admin/`` feature
|
||||
separate versions of the admin site -- using the ``AdminSite`` instances
|
||||
|
||||
@@ -55,9 +55,9 @@ Two points to keep in mind:
|
||||
various operations in the change form and we need that to be rendered too.
|
||||
|
||||
Sometimes you'll need to work with ``jQuery`` plugins that are not registered
|
||||
in the ``django.jQuery`` namespace. To do that, simply change how the code
|
||||
listens for events. Instead of wrapping the listener in the ``django.jQuery``
|
||||
namespace, just listen to the event triggered from there. For example:
|
||||
in the ``django.jQuery`` namespace. To do that, change how the code listens for
|
||||
events. Instead of wrapping the listener in the ``django.jQuery`` namespace,
|
||||
listen to the event triggered from there. For example:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
|
||||
@@ -648,8 +648,8 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
|
||||
.. method:: authenticate(request, remote_user)
|
||||
|
||||
The username passed as ``remote_user`` is considered trusted. This
|
||||
method simply returns the user object with the given username, creating
|
||||
a new user object if :attr:`~RemoteUserBackend.create_unknown_user` is
|
||||
method returns the user object with the given username, creating a new
|
||||
user object if :attr:`~RemoteUserBackend.create_unknown_user` is
|
||||
``True``.
|
||||
|
||||
Returns ``None`` if :attr:`~RemoteUserBackend.create_unknown_user` is
|
||||
|
||||
@@ -240,7 +240,7 @@ to go one step further and use
|
||||
:class:`~django.contrib.contenttypes.models.ContentType` to enable truly
|
||||
generic (sometimes called "polymorphic") relationships between models.
|
||||
|
||||
A simple example is a tagging system, which might look like this::
|
||||
For example, it could be used for a tagging system like so::
|
||||
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
@@ -438,7 +438,7 @@ it would be deleted at the same time.
|
||||
Unlike :class:`~django.db.models.ForeignKey`,
|
||||
:class:`~django.contrib.contenttypes.fields.GenericForeignKey` does not accept
|
||||
an :attr:`~django.db.models.ForeignKey.on_delete` argument to customize this
|
||||
behavior; if desired, you can avoid the cascade-deletion simply by not using
|
||||
behavior; if desired, you can avoid the cascade-deletion by not using
|
||||
:class:`~django.contrib.contenttypes.fields.GenericRelation`, and alternate
|
||||
behavior can be provided via the :data:`~django.db.models.signals.pre_delete`
|
||||
signal.
|
||||
|
||||
@@ -5,14 +5,14 @@ The flatpages app
|
||||
.. module:: django.contrib.flatpages
|
||||
:synopsis: A framework for managing simple ?flat? HTML content in a database.
|
||||
|
||||
Django comes with an optional "flatpages" application. It lets you store simple
|
||||
"flat" HTML content in a database and handles the management for you via
|
||||
Django's admin interface and a Python API.
|
||||
Django comes with an optional "flatpages" application. It lets you store "flat"
|
||||
HTML content in a database and handles the management for you via Django's
|
||||
admin interface and a Python API.
|
||||
|
||||
A flatpage is a simple object with a URL, title and content. Use it for
|
||||
one-off, special-case pages, such as "About" or "Privacy Policy" pages, that
|
||||
you want to store in a database but for which you don't want to develop a
|
||||
custom Django application.
|
||||
A flatpage is a object with a URL, title and content. Use it for one-off,
|
||||
special-case pages, such as "About" or "Privacy Policy" pages, that you want to
|
||||
store in a database but for which you don't want to develop a custom Django
|
||||
application.
|
||||
|
||||
A flatpage can use a custom template or a default, systemwide flatpage
|
||||
template. It can be associated with one, or multiple, sites.
|
||||
@@ -58,9 +58,9 @@ How it works
|
||||
============
|
||||
|
||||
``manage.py migrate`` creates two tables in your database: ``django_flatpage``
|
||||
and ``django_flatpage_sites``. ``django_flatpage`` is a simple lookup table
|
||||
that simply maps a URL to a title and bunch of text content.
|
||||
``django_flatpage_sites`` associates a flatpage with a site.
|
||||
and ``django_flatpage_sites``. ``django_flatpage`` is a lookup table that maps
|
||||
a URL to a title and bunch of text content. ``django_flatpage_sites``
|
||||
associates a flatpage with a site.
|
||||
|
||||
Using the URLconf
|
||||
-----------------
|
||||
@@ -229,12 +229,12 @@ By default, flatpages are rendered via the template
|
||||
particular flatpage: in the admin, a collapsed fieldset titled
|
||||
"Advanced options" (clicking will expand it) contains a field for
|
||||
specifying a template name. If you're creating a flat page via the
|
||||
Python API you can simply set the template name as the field
|
||||
``template_name`` on the ``FlatPage`` object.
|
||||
Python API you can set the template name as the field ``template_name`` on the
|
||||
``FlatPage`` object.
|
||||
|
||||
Creating the :file:`flatpages/default.html` template is your responsibility;
|
||||
in your template directory, just create a :file:`flatpages` directory
|
||||
containing a file :file:`default.html`.
|
||||
in your template directory, create a :file:`flatpages` directory containing a
|
||||
file :file:`default.html`.
|
||||
|
||||
Flatpage templates are passed a single context variable, ``flatpage``,
|
||||
which is the flatpage object.
|
||||
|
||||
@@ -284,10 +284,10 @@ Then distance queries may be performed as follows::
|
||||
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(mi=20)))
|
||||
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(chain=100)))
|
||||
|
||||
Raster queries work the same way by simply replacing the geometry field
|
||||
``point`` with a raster field, or the ``pnt`` object with a raster object, or
|
||||
both. To specify the band index of a raster input on the right hand side, a
|
||||
3-tuple can be passed to the lookup as follows::
|
||||
Raster queries work the same way by replacing the geometry field ``point`` with
|
||||
a raster field, or the ``pnt`` object with a raster object, or both. To specify
|
||||
the band index of a raster input on the right hand side, a 3-tuple can be
|
||||
passed to the lookup as follows::
|
||||
|
||||
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(rst, 2, D(km=7)))
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ Form widgets
|
||||
GeoDjango form widgets allow you to display and edit geographic data on a
|
||||
visual map.
|
||||
Note that none of the currently available widgets supports 3D geometries, hence
|
||||
geometry fields will fallback using a simple ``Textarea`` widget for such data.
|
||||
geometry fields will fallback using a ``Textarea`` widget for such data.
|
||||
|
||||
Widget attributes
|
||||
-----------------
|
||||
|
||||
@@ -36,7 +36,7 @@ The GDAL/OGR tools described here are designed to help you read in
|
||||
your geospatial data, in order for most of them to be useful you have
|
||||
to have some data to work with. If you're starting out and don't yet
|
||||
have any data of your own to use, GeoDjango tests contain a number of
|
||||
simple data sets that you can use for testing. You can download them here::
|
||||
data sets that you can use for testing. You can download them here::
|
||||
|
||||
$ wget https://raw.githubusercontent.com/django/django/master/tests/gis_tests/data/cities/cities.{shp,prj,shx,dbf}
|
||||
$ wget https://raw.githubusercontent.com/django/django/master/tests/gis_tests/data/rasters/raster.tif
|
||||
@@ -49,7 +49,7 @@ Vector Data Source Objects
|
||||
|
||||
:class:`DataSource` is a wrapper for the OGR data source object that
|
||||
supports reading data from a variety of OGR-supported geospatial file
|
||||
formats and data sources using a simple, consistent interface. Each
|
||||
formats and data sources using a consistent interface. Each
|
||||
data source is represented by a :class:`DataSource` object which contains
|
||||
one or more layers of data. Each layer, represented by a :class:`Layer`
|
||||
object, contains some number of geographic features (:class:`Feature`),
|
||||
@@ -1085,7 +1085,7 @@ Raster Data Objects
|
||||
|
||||
:class:`GDALRaster` is a wrapper for the GDAL raster source object that
|
||||
supports reading data from a variety of GDAL-supported geospatial file
|
||||
formats and data sources using a simple, consistent interface. Each
|
||||
formats and data sources using a consistent interface. Each
|
||||
data source is represented by a :class:`GDALRaster` object which contains
|
||||
one or more layers of data named bands. Each band, represented by a
|
||||
:class:`GDALBand` object, contains georeferenced image data. For example, an RGB
|
||||
|
||||
@@ -887,8 +887,8 @@ SpatiaLite
|
||||
Returns a ``GEOMETRYCOLLECTION`` or a ``MULTI`` geometry object from the geometry
|
||||
column. This is analogous to a simplified version of the :class:`Union`
|
||||
aggregate, except it can be several orders of magnitude faster than performing
|
||||
a union because it simply rolls up geometries into a collection or multi object,
|
||||
not caring about dissolving boundaries.
|
||||
a union because it rolls up geometries into a collection or multi object, not
|
||||
caring about dissolving boundaries.
|
||||
|
||||
``Extent``
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -833,7 +833,7 @@ Geometry Collections
|
||||
Prepared Geometries
|
||||
===================
|
||||
|
||||
In order to obtain a prepared geometry, just access the
|
||||
In order to obtain a prepared geometry, access the
|
||||
:attr:`GEOSGeometry.prepared` property. Once you have a
|
||||
``PreparedGeometry`` instance its spatial predicate methods, listed below,
|
||||
may be used with other ``GEOSGeometry`` objects. An operation with a prepared
|
||||
@@ -911,8 +911,8 @@ I/O Objects
|
||||
Reader Objects
|
||||
--------------
|
||||
|
||||
The reader I/O classes simply return a :class:`GEOSGeometry` instance from the
|
||||
WKB and/or WKT input given to their ``read(geom)`` method.
|
||||
The reader I/O classes return a :class:`GEOSGeometry` instance from the WKB
|
||||
and/or WKT input given to their ``read(geom)`` method.
|
||||
|
||||
.. class:: WKBReader
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ totally fine with GeoDjango. Your mileage may vary.
|
||||
|
||||
The GeoDjango interfaces to GEOS, GDAL, and GeoIP may be used
|
||||
independently of Django. In other words, no database or settings file
|
||||
required -- just import them as normal from :mod:`django.contrib.gis`.
|
||||
required -- import them as normal from :mod:`django.contrib.gis`.
|
||||
|
||||
.. _PROJ.4: https://github.com/OSGeo/proj.4/wiki/
|
||||
__ https://postgis.net/
|
||||
|
||||
@@ -272,9 +272,9 @@ KyngChaos packages
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
William Kyngesburye provides a number of `geospatial library binary packages`__
|
||||
that make it simple to get GeoDjango installed on macOS without compiling
|
||||
them from source. However, `Xcode`_ is still necessary for compiling the
|
||||
Python database adapters :ref:`psycopg2_kyngchaos` (for PostGIS).
|
||||
that help to get GeoDjango installed on macOS without compiling them from
|
||||
source. However, `Xcode`_ is still necessary for compiling the Python database
|
||||
adapters :ref:`psycopg2_kyngchaos` (for PostGIS).
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -385,9 +385,9 @@ PostgreSQL
|
||||
~~~~~~~~~~
|
||||
|
||||
First, download the latest `PostgreSQL 9.x installer`__ from the
|
||||
`EnterpriseDB`__ website. After downloading, simply run the installer,
|
||||
follow the on-screen directions, and keep the default options unless
|
||||
you know the consequences of changing them.
|
||||
`EnterpriseDB`__ website. After downloading, run the installer, follow the
|
||||
on-screen directions, and keep the default options unless you know the
|
||||
consequences of changing them.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -446,14 +446,13 @@ __ http://www.stickpeople.com/projects/python/win-psycopg/
|
||||
OSGeo4W
|
||||
~~~~~~~
|
||||
|
||||
The `OSGeo4W installer`_ makes it simple to install the PROJ.4, GDAL, and GEOS
|
||||
libraries required by GeoDjango. First, download the `OSGeo4W installer`_,
|
||||
and run it. Select :menuselection:`Express Web-GIS Install` and click next.
|
||||
In the 'Select Packages' list, ensure that GDAL is selected; MapServer and
|
||||
Apache are also enabled by default, but are not required by GeoDjango and
|
||||
may be unchecked safely. After clicking next, the packages will be
|
||||
automatically downloaded and installed, after which you may exit the
|
||||
installer.
|
||||
The `OSGeo4W installer`_ helps to install the PROJ.4, GDAL, and GEOS libraries
|
||||
required by GeoDjango. First, download the `OSGeo4W installer`_, and run it.
|
||||
Select :menuselection:`Express Web-GIS Install` and click next. In the 'Select
|
||||
Packages' list, ensure that GDAL is selected; MapServer and Apache are also
|
||||
enabled by default, but are not required by GeoDjango and may be unchecked
|
||||
safely. After clicking next, the packages will be automatically downloaded and
|
||||
installed, after which you may exit the installer.
|
||||
|
||||
.. _OSGeo4W installer: https://trac.osgeo.org/osgeo4w/
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ command line interface and enter the following query::
|
||||
sqlite> CREATE VIRTUAL TABLE testrtree USING rtree(id,minX,maxX,minY,maxY);
|
||||
|
||||
If you obtain an error, you will have to recompile SQLite from source. Otherwise,
|
||||
just skip this section.
|
||||
skip this section.
|
||||
|
||||
To install from sources, download the latest amalgamation source archive from
|
||||
the `SQLite download page`__, and extract::
|
||||
|
||||
@@ -25,8 +25,8 @@ then inserting into a GeoDjango model.
|
||||
that :class:`LayerMapping` is using too much memory, set
|
||||
:setting:`DEBUG` to ``False`` in your settings. When :setting:`DEBUG`
|
||||
is set to ``True``, Django :ref:`automatically logs <faq-see-raw-sql-queries>`
|
||||
*every* SQL query -- thus, when SQL statements contain geometries, it is
|
||||
easy to consume more memory than is typical.
|
||||
*every* SQL query -- and when SQL statements contain geometries, this may
|
||||
consume more memory than is typical.
|
||||
|
||||
Example
|
||||
=======
|
||||
@@ -75,10 +75,10 @@ Example
|
||||
Saved: Name: 2
|
||||
Saved: Name: 3
|
||||
|
||||
Here, :class:`LayerMapping` just transformed the three geometries from the
|
||||
shapefile in their original spatial reference system (WGS84) to the spatial
|
||||
reference system of the GeoDjango model (NAD83). If no spatial reference
|
||||
system is defined for the layer, use the ``source_srs`` keyword with a
|
||||
Here, :class:`LayerMapping` transformed the three geometries from the shapefile
|
||||
in their original spatial reference system (WGS84) to the spatial reference
|
||||
system of the GeoDjango model (NAD83). If no spatial reference system is
|
||||
defined for the layer, use the ``source_srs`` keyword with a
|
||||
:class:`~django.contrib.gis.gdal.SpatialReference` object to specify one.
|
||||
|
||||
``LayerMapping`` API
|
||||
|
||||
@@ -26,8 +26,8 @@ instantiated in units of kilometers (``km``) and miles (``mi``)::
|
||||
>>> print(d2)
|
||||
5.0 mi
|
||||
|
||||
Conversions are easy, just access the preferred unit attribute to get a
|
||||
converted distance quantity::
|
||||
For conversions, access the preferred unit attribute to get a converted
|
||||
distance quantity::
|
||||
|
||||
>>> print(d1.mi) # Converting 5 kilometers to miles
|
||||
3.10685596119
|
||||
|
||||
@@ -73,8 +73,8 @@ is done from an existing superuser account)::
|
||||
Windows
|
||||
-------
|
||||
|
||||
On Windows platforms the pgAdmin III utility may also be used as
|
||||
a simple way to add superuser privileges to your database user.
|
||||
On Windows platforms you can use the pgAdmin III utility to add superuser
|
||||
privileges to your database user.
|
||||
|
||||
By default, the PostGIS installer on Windows includes a template
|
||||
spatial database entitled ``template_postgis``.
|
||||
|
||||
@@ -758,8 +758,8 @@ available with the :class:`~django.contrib.gis.admin.GeoModelAdmin`
|
||||
The PROJ.4 datum shifting files must be installed (see the :ref:`PROJ.4
|
||||
installation instructions <proj4>` for more details).
|
||||
|
||||
If you meet this requirement, then just substitute the ``OSMGeoAdmin``
|
||||
option class in your ``admin.py`` file::
|
||||
If you meet this requirement, then substitute the ``OSMGeoAdmin`` option class
|
||||
in your ``admin.py`` file::
|
||||
|
||||
admin.site.register(WorldBorder, admin.OSMGeoAdmin)
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ See the :doc:`contenttypes documentation </ref/contrib/contenttypes>`.
|
||||
``flatpages``
|
||||
=============
|
||||
|
||||
A framework for managing simple "flat" HTML content in a database.
|
||||
A framework for managing "flat" HTML content in a database.
|
||||
|
||||
See the :doc:`flatpages documentation </ref/contrib/flatpages>`.
|
||||
|
||||
|
||||
@@ -194,9 +194,9 @@ If you're using the context processor, your template should be rendered with a
|
||||
``RequestContext``. Otherwise, ensure ``messages`` is available to
|
||||
the template context.
|
||||
|
||||
Even if you know there is only just one message, you should still iterate over
|
||||
the ``messages`` sequence, because otherwise the message storage will not be cleared
|
||||
for the next request.
|
||||
Even if you know there is only one message, you should still iterate over the
|
||||
``messages`` sequence, because otherwise the message storage will not be
|
||||
cleared for the next request.
|
||||
|
||||
The context processor also provides a ``DEFAULT_MESSAGE_LEVELS`` variable which
|
||||
is a mapping of the message level names to their numeric value::
|
||||
@@ -235,8 +235,7 @@ The ``Message`` class
|
||||
.. class:: storage.base.Message
|
||||
|
||||
When you loop over the list of messages in a template, what you get are
|
||||
instances of the ``Message`` class. It's quite a simple object, with only a
|
||||
few attributes:
|
||||
instances of the ``Message`` class. They have only a few attributes:
|
||||
|
||||
* ``message``: The actual text of the message.
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ may be a good choice for the :ref:`range fields <range-fields>` and
|
||||
|
||||
.. class:: ArrayField(base_field, size=None, **options)
|
||||
|
||||
A field for storing lists of data. Most field types can be used, you simply
|
||||
A field for storing lists of data. Most field types can be used, and you
|
||||
pass another field instance as the :attr:`base_field
|
||||
<ArrayField.base_field>`. You may also specify a :attr:`size
|
||||
<ArrayField.size>`. ``ArrayField`` can be nested to store multi-dimensional
|
||||
@@ -333,7 +333,7 @@ We will use the following example model::
|
||||
Key lookups
|
||||
~~~~~~~~~~~
|
||||
|
||||
To query based on a given key, you simply use that key as the lookup name::
|
||||
To query based on a given key, you can use that key as the lookup name::
|
||||
|
||||
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
|
||||
>>> Dog.objects.create(name='Meg', data={'breed': 'collie'})
|
||||
@@ -537,8 +537,7 @@ We will use the following example model::
|
||||
Key, index, and path lookups
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To query based on a given dictionary key, simply use that key as the lookup
|
||||
name::
|
||||
To query based on a given dictionary key, use that key as the lookup name::
|
||||
|
||||
>>> Dog.objects.create(name='Rufus', data={
|
||||
... 'breed': 'labrador',
|
||||
|
||||
@@ -15,8 +15,7 @@ Fields
|
||||
|
||||
.. class:: SimpleArrayField(base_field, delimiter=',', max_length=None, min_length=None)
|
||||
|
||||
A simple field which maps to an array. It is represented by an HTML
|
||||
``<input>``.
|
||||
A field which maps to an array. It is represented by an HTML ``<input>``.
|
||||
|
||||
.. attribute:: base_field
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ The ``search`` lookup
|
||||
|
||||
.. fieldlookup:: search
|
||||
|
||||
The simplest way to use full text search is to search a single term against a
|
||||
A common way to use full text search is to search a single term against a
|
||||
single column in the database. For example::
|
||||
|
||||
>>> Entry.objects.filter(body_text__search='Cheese')
|
||||
@@ -111,9 +111,9 @@ See :ref:`postgresql-fts-search-configuration` for an explanation of the
|
||||
|
||||
.. class:: SearchRank(vector, query, weights=None)
|
||||
|
||||
So far, we've just returned the results for which any match between the vector
|
||||
and the query are possible. It's likely you may wish to order the results by
|
||||
some sort of relevancy. PostgreSQL provides a ranking function which takes into
|
||||
So far, we've returned the results for which any match between the vector and
|
||||
the query are possible. It's likely you may wish to order the results by some
|
||||
sort of relevancy. PostgreSQL provides a ranking function which takes into
|
||||
account how often the query terms appear in the document, how close together
|
||||
the terms are in the document, and how important the part of the document is
|
||||
where they occur. The better the match, the higher the value of the rank. To
|
||||
|
||||
@@ -5,7 +5,7 @@ The redirects app
|
||||
.. module:: django.contrib.redirects
|
||||
:synopsis: A framework for managing redirects.
|
||||
|
||||
Django comes with an optional redirects application. It lets you store simple
|
||||
Django comes with an optional redirects application. It lets you store
|
||||
redirects in a database and handles the redirecting for you. It uses the HTTP
|
||||
response status code ``301 Moved Permanently`` by default.
|
||||
|
||||
@@ -25,7 +25,7 @@ How it works
|
||||
============
|
||||
|
||||
``manage.py migrate`` creates a ``django_redirect`` table in your database. This
|
||||
is a simple lookup table with ``site_id``, ``old_path`` and ``new_path`` fields.
|
||||
is a lookup table with ``site_id``, ``old_path`` and ``new_path`` fields.
|
||||
|
||||
The :class:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware`
|
||||
does all of the work. Each time any Django application raises a 404
|
||||
|
||||
@@ -5,8 +5,8 @@ The sitemap framework
|
||||
.. module:: django.contrib.sitemaps
|
||||
:synopsis: A framework for generating Google sitemap XML files.
|
||||
|
||||
Django comes with a high-level sitemap-generating framework that makes
|
||||
creating sitemap_ XML files easy.
|
||||
Django comes with a high-level sitemap-generating framework to create sitemap_
|
||||
XML files.
|
||||
|
||||
.. _sitemap: https://www.sitemaps.org/
|
||||
|
||||
@@ -22,7 +22,7 @@ The Django sitemap framework automates the creation of this XML file by letting
|
||||
you express this information in Python code.
|
||||
|
||||
It works much like Django's :doc:`syndication framework
|
||||
</ref/contrib/syndication>`. To create a sitemap, just write a
|
||||
</ref/contrib/syndication>`. To create a sitemap, write a
|
||||
:class:`~django.contrib.sitemaps.Sitemap` class and point to it in your
|
||||
:doc:`URLconf </topics/http/urls>`.
|
||||
|
||||
@@ -76,11 +76,11 @@ a :class:`~django.contrib.sitemaps.Sitemap` class (e.g.,
|
||||
``Sitemap`` classes
|
||||
===================
|
||||
|
||||
A :class:`~django.contrib.sitemaps.Sitemap` class is a simple Python
|
||||
class that represents a "section" of entries in your sitemap. For example,
|
||||
one :class:`~django.contrib.sitemaps.Sitemap` class could represent
|
||||
all the entries of your Weblog, while another could represent all of the
|
||||
events in your events calendar.
|
||||
A :class:`~django.contrib.sitemaps.Sitemap` class is a Python class that
|
||||
represents a "section" of entries in your sitemap. For example, one
|
||||
:class:`~django.contrib.sitemaps.Sitemap` class could represent all the entries
|
||||
of your Weblog, while another could represent all of the events in your events
|
||||
calendar.
|
||||
|
||||
In the simplest case, all these sections get lumped together into one
|
||||
:file:`sitemap.xml`, but it's also possible to use the framework to generate a
|
||||
@@ -90,8 +90,8 @@ sitemap index that references individual sitemap files, one per section. (See
|
||||
:class:`~django.contrib.sitemaps.Sitemap` classes must subclass
|
||||
``django.contrib.sitemaps.Sitemap``. They can live anywhere in your codebase.
|
||||
|
||||
A simple example
|
||||
================
|
||||
An example
|
||||
==========
|
||||
|
||||
Let's assume you have a blog system, with an ``Entry`` model, and you want your
|
||||
sitemap to include all the links to your individual blog entries. Here's how
|
||||
@@ -116,11 +116,10 @@ Note:
|
||||
attributes corresponding to ``<changefreq>`` and ``<priority>`` elements,
|
||||
respectively. They can be made callable as functions, as
|
||||
:attr:`~Sitemap.lastmod` was in the example.
|
||||
* :attr:`~Sitemap.items()` is simply a method that returns a list of
|
||||
objects. The objects returned will get passed to any callable methods
|
||||
corresponding to a sitemap property (:attr:`~Sitemap.location`,
|
||||
:attr:`~Sitemap.lastmod`, :attr:`~Sitemap.changefreq`, and
|
||||
:attr:`~Sitemap.priority`).
|
||||
* :attr:`~Sitemap.items()` is a method that returns a list of objects. The
|
||||
objects returned will get passed to any callable methods corresponding to a
|
||||
sitemap property (:attr:`~Sitemap.location`, :attr:`~Sitemap.lastmod`,
|
||||
:attr:`~Sitemap.changefreq`, and :attr:`~Sitemap.priority`).
|
||||
* :attr:`~Sitemap.lastmod` should return a :class:`~datetime.datetime`.
|
||||
* There is no :attr:`~Sitemap.location` method in this example, but you
|
||||
can provide it in order to specify the URL for your object. By default,
|
||||
|
||||
@@ -13,7 +13,7 @@ the domain names and "verbose" names of your Django-powered sites.
|
||||
Use it if your single Django installation powers more than one site and you
|
||||
need to differentiate between those sites in some way.
|
||||
|
||||
The sites framework is mainly based on a simple model:
|
||||
The sites framework is mainly based on this model:
|
||||
|
||||
.. class:: models.Site
|
||||
|
||||
@@ -37,7 +37,7 @@ try to get the current site by comparing the
|
||||
the :meth:`request.get_host() <django.http.HttpRequest.get_host>` method.
|
||||
|
||||
How you use this is up to you, but Django uses it in a couple of ways
|
||||
automatically via simple conventions.
|
||||
automatically via a couple of conventions.
|
||||
|
||||
Example usage
|
||||
=============
|
||||
@@ -58,10 +58,10 @@ publish the same story twice: once for LJWorld.com and again for Lawrence.com.
|
||||
But that's inefficient for site producers, and it's redundant to store
|
||||
multiple copies of the same story in the database.
|
||||
|
||||
The better solution is simple: Both sites use the same article database, and an
|
||||
article is associated with one or more sites. In Django model terminology,
|
||||
that's represented by a :class:`~django.db.models.ManyToManyField` in the
|
||||
``Article`` model::
|
||||
A better solution removes the content duplication: Both sites use the same
|
||||
article database, and an article is associated with one or more sites. In
|
||||
Django model terminology, that's represented by a
|
||||
:class:`~django.db.models.ManyToManyField` in the ``Article`` model::
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
from django.db import models
|
||||
@@ -80,8 +80,8 @@ This accomplishes several things quite nicely:
|
||||
database; it only has a single record in the database.
|
||||
|
||||
* It lets the site developers use the same Django view code for both sites.
|
||||
The view code that displays a given story just checks to make sure the
|
||||
requested story is on the current site. It looks something like this::
|
||||
The view code that displays a given story checks to make sure the requested
|
||||
story is on the current site. It looks something like this::
|
||||
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
|
||||
@@ -215,7 +215,7 @@ subscribing to LJWorld.com alerts." Same goes for the email's message body.
|
||||
Note that an even more flexible (but more heavyweight) way of doing this would
|
||||
be to use Django's template system. Assuming Lawrence.com and LJWorld.com have
|
||||
different template directories (:setting:`DIRS <TEMPLATES-DIRS>`), you could
|
||||
simply farm out to the template system like so::
|
||||
farm out to the template system like so::
|
||||
|
||||
from django.core.mail import send_mail
|
||||
from django.template import Context, loader
|
||||
@@ -243,7 +243,7 @@ Getting the current domain for full URLs
|
||||
Django's ``get_absolute_url()`` convention is nice for getting your objects'
|
||||
URL without the domain name, but in some cases you might want to display the
|
||||
full URL -- with ``http://`` and the domain and everything -- for an object.
|
||||
To do this, you can use the sites framework. A simple example::
|
||||
To do this, you can use the sites framework. An example::
|
||||
|
||||
>>> from django.contrib.sites.models import Site
|
||||
>>> obj = MyModel.objects.get(id=3)
|
||||
@@ -401,7 +401,7 @@ If you often use this pattern::
|
||||
site = Site.objects.get_current()
|
||||
...
|
||||
|
||||
there is simple way to avoid repetitions. Add
|
||||
To avoid repetitions, add
|
||||
:class:`django.contrib.sites.middleware.CurrentSiteMiddleware` to
|
||||
:setting:`MIDDLEWARE`. The middleware sets the ``site`` attribute on every
|
||||
request object, so you can use ``request.site`` to get the current site.
|
||||
|
||||
@@ -387,7 +387,7 @@ hashed names of processed files instead of a static manifest file called
|
||||
have access to the file system.
|
||||
|
||||
If you want to override certain options of the cache backend the storage uses,
|
||||
simply specify a custom entry in the :setting:`CACHES` setting named
|
||||
specify a custom entry in the :setting:`CACHES` setting named
|
||||
``'staticfiles'``. It falls back to using the ``'default'`` cache backend.
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -6,8 +6,8 @@ The syndication feed framework
|
||||
:synopsis: A framework for generating syndication feeds, in RSS and Atom,
|
||||
quite easily.
|
||||
|
||||
Django comes with a high-level syndication-feed-generating framework
|
||||
that makes creating RSS_ and Atom_ feeds easy.
|
||||
Django comes with a high-level syndication-feed-generating framework for
|
||||
creating RSS_ and Atom_ feeds.
|
||||
|
||||
To create any syndication feed, all you have to do is write a short
|
||||
Python class. You can create as many feeds as you want.
|
||||
@@ -94,13 +94,12 @@ Note:
|
||||
standard RSS ``<title>``, ``<link>`` and ``<description>`` elements,
|
||||
respectively.
|
||||
|
||||
* ``items()`` is, simply, a method that returns a list of objects that
|
||||
should be included in the feed as ``<item>`` elements. Although this
|
||||
example returns ``NewsItem`` objects using Django's
|
||||
:doc:`object-relational mapper </ref/models/querysets>`, ``items()``
|
||||
doesn't have to return model instances. Although you get a few bits of
|
||||
functionality "for free" by using Django models, ``items()`` can
|
||||
return any type of object you want.
|
||||
* ``items()`` is, a method that returns a list of objects that should be
|
||||
included in the feed as ``<item>`` elements. Although this example returns
|
||||
``NewsItem`` objects using Django's :doc:`object-relational mapper
|
||||
</ref/models/querysets>`, ``items()`` doesn't have to return model instances.
|
||||
Although you get a few bits of functionality "for free" by using Django
|
||||
models, ``items()`` can return any type of object you want.
|
||||
|
||||
* If you're creating an Atom feed, rather than an RSS feed, set the
|
||||
``subtitle`` attribute instead of the ``description`` attribute.
|
||||
@@ -246,7 +245,7 @@ Here's the code for these beat-specific feeds::
|
||||
|
||||
To generate the feed's ``<title>``, ``<link>`` and ``<description>``, Django
|
||||
uses the ``title()``, ``link()`` and ``description()`` methods. In
|
||||
the previous example, they were simple string class attributes, but this example
|
||||
the previous example, they were string class attributes, but this example
|
||||
illustrates that they can be either strings *or* methods. For each of
|
||||
``title``, ``link`` and ``description``, Django follows this
|
||||
algorithm:
|
||||
@@ -262,7 +261,8 @@ Also note that ``items()`` also follows the same algorithm -- first, it
|
||||
tries ``items(obj)``, then ``items()``, then finally an ``items``
|
||||
class attribute (which should be a list).
|
||||
|
||||
We are using a template for the item descriptions. It can be very simple:
|
||||
We are using a template for the item descriptions. It can be as minimal as
|
||||
this:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
@@ -333,10 +333,9 @@ Publishing Atom and RSS feeds in tandem
|
||||
---------------------------------------
|
||||
|
||||
Some developers like to make available both Atom *and* RSS versions of their
|
||||
feeds. That's easy to do with Django: Just create a subclass of your
|
||||
:class:`~django.contrib.syndication.views.Feed`
|
||||
class and set the ``feed_type`` to something different. Then update your
|
||||
URLconf to add the extra versions.
|
||||
feeds. To do that, you can create a subclass of your
|
||||
:class:`~django.contrib.syndication.views.Feed` class and set the ``feed_type``
|
||||
to something different. Then update your URLconf to add the extra versions.
|
||||
|
||||
Here's a full example::
|
||||
|
||||
@@ -367,8 +366,8 @@ Here's a full example::
|
||||
subtitle and description are not necessarily the same thing. Instead, you
|
||||
should define a ``subtitle`` attribute.
|
||||
|
||||
In the above example, we simply set the Atom feed's ``subtitle`` to the
|
||||
RSS feed's ``description``, because it's quite short already.
|
||||
In the above example, we set the Atom feed's ``subtitle`` to the RSS feed's
|
||||
``description``, because it's quite short already.
|
||||
|
||||
And the accompanying URLconf::
|
||||
|
||||
@@ -1073,5 +1072,5 @@ For example, you might start implementing an iTunes RSS feed generator like so::
|
||||
super().add_root_elements(handler)
|
||||
handler.addQuickElement('itunes:explicit', 'clean')
|
||||
|
||||
Obviously there's a lot more work to be done for a complete custom feed class,
|
||||
but the above example should demonstrate the basic idea.
|
||||
There's a lot more work to be done for a complete custom feed class, but the
|
||||
above example should demonstrate the basic idea.
|
||||
|
||||
Reference in New Issue
Block a user