Refs #34140 -- Applied rst code-block to non-Python examples.

Thanks to J.V. Zammit, Paolo Melchiorre, and Mariusz Felisiak for
reviews.
This commit is contained in:
Carlton Gibson 2023-02-09 16:48:46 +01:00 committed by Mariusz Felisiak
parent 7bb741d787
commit 534ac48297
120 changed files with 3998 additions and 1398 deletions

View file

@ -3201,7 +3201,9 @@ with an instance namespace corresponding to the name of the Site instance.
So - if you wanted to get a reference to the Change view for a particular
``Choice`` object (from the polls application) in the default admin, you would
call::
call:
.. code-block:: pycon
>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
@ -3214,7 +3216,9 @@ This will find the first registered instance of the admin application
If you want to find a URL in a specific admin instance, provide the name of
that instance as a ``current_app`` hint to the reverse call. For example,
if you specifically wanted the admin view from the admin instance named
``custom``, you would need to call::
``custom``, you would need to call:
.. code-block:: pycon
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,), current_app='custom')

View file

@ -121,7 +121,9 @@ model it represents, or to retrieve objects from that model:
For example, we could look up the
:class:`~django.contrib.contenttypes.models.ContentType` for the
:class:`~django.contrib.auth.models.User` model::
:class:`~django.contrib.auth.models.User` model:
.. code-block:: pycon
>>> from django.contrib.contenttypes.models import ContentType
>>> user_type = ContentType.objects.get(app_label='auth', model='user')
@ -130,7 +132,9 @@ For example, we could look up the
And then use it to query for a particular
:class:`~django.contrib.auth.models.User`, or to get access
to the ``User`` model class::
to the ``User`` model class:
.. code-block:: pycon
>>> user_type.model_class()
<class 'django.contrib.auth.models.User'>
@ -219,7 +223,9 @@ The :meth:`~ContentTypeManager.get_for_model()` method is especially
useful when you know you need to work with a
:class:`ContentType <django.contrib.contenttypes.models.ContentType>` but don't
want to go to the trouble of obtaining the model's metadata to perform a manual
lookup::
lookup:
.. code-block:: pycon
>>> from django.contrib.auth.models import User
>>> ContentType.objects.get_for_model(User)
@ -340,7 +346,9 @@ This will enable an API similar to the one used for a normal
:class:`~django.db.models.ForeignKey`;
each ``TaggedItem`` will have a ``content_object`` field that returns the
object it's related to, and you can also assign to that field or use it when
creating a ``TaggedItem``::
creating a ``TaggedItem``:
.. code-block:: pycon
>>> from django.contrib.auth.models import User
>>> guido = User.objects.get(username='Guido')
@ -351,7 +359,9 @@ creating a ``TaggedItem``::
If the related object is deleted, the ``content_type`` and ``object_id`` fields
remain set to their original values and the ``GenericForeignKey`` returns
``None``::
``None``:
.. code-block:: pycon
>>> guido.delete()
>>> t.content_object # returns None
@ -360,7 +370,9 @@ Due to the way :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
is implemented, you cannot use such fields directly with filters (``filter()``
and ``exclude()``, for example) via the database API. Because a
:class:`~django.contrib.contenttypes.fields.GenericForeignKey` isn't a
normal field object, these examples will *not* work::
normal field object, these examples will *not* work:
.. code-block:: pycon
# This will fail
>>> TaggedItem.objects.filter(content_object=guido)
@ -393,7 +405,9 @@ a "reverse" generic relationship to enable an additional API. For example::
tags = GenericRelation(TaggedItem)
``Bookmark`` instances will each have a ``tags`` attribute, which can
be used to retrieve their associated ``TaggedItems``::
be used to retrieve their associated ``TaggedItems``:
.. code-block:: pycon
>>> b = Bookmark(url='https://www.djangoproject.com/')
>>> b.save()
@ -405,7 +419,9 @@ be used to retrieve their associated ``TaggedItems``::
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
You can also use ``add()``, ``create()``, or ``set()`` to create
relationships::
relationships:
.. code-block:: pycon
>>> t3 = TaggedItem(tag='Web development')
>>> b.tags.add(t3, bulk=False)
@ -417,7 +433,9 @@ relationships::
>>> b.tags.all()
<QuerySet [<TaggedItem: django>, <TaggedItem: Web development>]>
The ``remove()`` call will bulk delete the specified model objects::
The ``remove()`` call will bulk delete the specified model objects:
.. code-block:: pycon
>>> b.tags.remove(t3)
>>> b.tags.all()
@ -426,7 +444,9 @@ The ``remove()`` call will bulk delete the specified model objects::
<QuerySet [<TaggedItem: django>]>
The ``clear()`` method can be used to bulk delete all related objects for an
instance::
instance:
.. code-block:: pycon
>>> b.tags.clear()
>>> b.tags.all()
@ -440,14 +460,18 @@ Defining :class:`~django.contrib.contenttypes.fields.GenericRelation` with
tags = GenericRelation(TaggedItem, related_query_name='bookmark')
This enables filtering, ordering, and other query operations on ``Bookmark``
from ``TaggedItem``::
from ``TaggedItem``:
.. code-block:: pycon
>>> # Get all tags belonging to bookmarks containing `django` in the url
>>> TaggedItem.objects.filter(bookmark__url__contains='django')
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
If you don't add the ``related_query_name``, you can do the same types of
lookups manually::
lookups manually:
.. code-block:: pycon
>>> bookmarks = Bookmark.objects.filter(url__contains='django')
>>> bookmark_type = ContentType.objects.get_for_model(Bookmark)
@ -491,7 +515,9 @@ Generic relations and aggregation
:doc:`Django's database aggregation API </topics/db/aggregation>` works with a
:class:`~django.contrib.contenttypes.fields.GenericRelation`. For example, you
can find out how many tags all the bookmarks have::
can find out how many tags all the bookmarks have:
.. code-block:: pycon
>>> Bookmark.objects.aggregate(Count('tags'))
{'tags__count': 3}

View file

@ -37,13 +37,17 @@ Creating and Saving Models with Geometry Fields
===============================================
Here is an example of how to create a geometry object (assuming the ``Zipcode``
model)::
model):
.. code-block:: pycon
>>> from zipcode.models import Zipcode
>>> z = Zipcode(code=77096, poly='POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
>>> z.save()
:class:`~django.contrib.gis.geos.GEOSGeometry` objects may also be used to save geometric models::
:class:`~django.contrib.gis.geos.GEOSGeometry` objects may also be used to save geometric models:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> poly = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))')
@ -53,7 +57,9 @@ model)::
Moreover, if the ``GEOSGeometry`` is in a different coordinate system (has a
different SRID value) than that of the field, then it will be implicitly
transformed into the SRID of the model's field, using the spatial database's
transform procedure::
transform procedure:
.. code-block:: pycon
>>> poly_3084 = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))', srid=3084) # SRID 3084 is 'NAD83(HARN) / Texas Centric Lambert Conformal'
>>> z = Zipcode(code=78212, poly=poly_3084)
@ -82,14 +88,18 @@ The raster field will therefore accept any input that is accepted by the
:class:`~django.contrib.gis.gdal.GDALRaster` constructor.
Here is an example of how to create a raster object from a raster file
``volcano.tif`` (assuming the ``Elevation`` model)::
``volcano.tif`` (assuming the ``Elevation`` model):
.. code-block:: pycon
>>> from elevation.models import Elevation
>>> dem = Elevation(name='Volcano', rast='/path/to/raster/volcano.tif')
>>> dem.save()
:class:`~django.contrib.gis.gdal.GDALRaster` objects may also be used to save
raster models::
raster models:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import GDALRaster
>>> rast = GDALRaster({'width': 10, 'height': 10, 'name': 'Canyon', 'srid': 4326,
@ -97,7 +107,9 @@ raster models::
>>> dem = Elevation(name='Canyon', rast=rast)
>>> dem.save()
Note that this equivalent to::
Note that this equivalent to:
.. code-block:: pycon
>>> dem = Elevation.objects.create(
... name='Canyon',
@ -125,12 +137,16 @@ Geometry Lookups
----------------
Geographic queries with geometries take the following general form (assuming
the ``Zipcode`` model used in the :doc:`model-api`)::
the ``Zipcode`` model used in the :doc:`model-api`):
.. code-block:: pycon
>>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>)
>>> qs = Zipcode.objects.exclude(...)
For example::
For example:
.. code-block:: pycon
>>> qs = Zipcode.objects.filter(poly__contains=pnt)
>>> qs = Elevation.objects.filter(poly__contains=rst)
@ -157,13 +173,17 @@ used to pass a band index. On the right hand side, a tuple of the raster and
band index can be specified.
This results in the following general form for lookups involving rasters
(assuming the ``Elevation`` model used in the :doc:`model-api`)::
(assuming the ``Elevation`` model used in the :doc:`model-api`):
.. code-block:: pycon
>>> qs = Elevation.objects.filter(<field>__<lookup_type>=<parameter>)
>>> qs = Elevation.objects.filter(<field>__<band_index>__<lookup_type>=<parameter>)
>>> qs = Elevation.objects.filter(<field>__<lookup_type>=(<raster_input, <band_index>)
For example::
For example:
.. code-block:: pycon
>>> qs = Elevation.objects.filter(rast__contains=geom)
>>> qs = Elevation.objects.filter(rast__contains=rst)
@ -256,7 +276,9 @@ For example, let's say we have a ``SouthTexasCity`` model (from the
# is used, units are in meters.
point = models.PointField(srid=32140)
Then distance queries may be performed as follows::
Then distance queries may be performed as follows:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> from django.contrib.gis.measure import D # ``D`` is a shortcut for ``Distance``
@ -273,7 +295,9 @@ Then distance queries may be performed 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::
passed to the lookup as follows:
.. code-block:: pycon
>>> qs = SouthTexasCity.objects.filter(point__distance_gte=(rst, 2, D(km=7)))

View file

@ -8,7 +8,9 @@ Geographic Database Functions
The functions documented on this page allow users to access geographic database
functions to be used in annotations, aggregations, or filters in Django.
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.db.models.functions import Length
>>> Track.objects.annotate(length=Length('line')).filter(length__gt=100)
@ -61,7 +63,9 @@ Accepts a single geographic field or expression and returns a `GeoJSON
is not a complete GeoJSON structure but only the ``geometry`` key content of a
GeoJSON structure. See also :doc:`/ref/contrib/gis/serializers`.
Example::
Example:
.. code-block:: pycon
>>> City.objects.annotate(json=AsGeoJSON('point')).get(name='Chicago').json
{"type":"Point","coordinates":[-87.65018,41.85039]}
@ -94,7 +98,9 @@ SpatiaLite
Accepts a single geographic field or expression and returns a `Geographic Markup
Language (GML)`__ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> qs = Zipcode.objects.annotate(gml=AsGML('poly'))
>>> print(qs[0].gml)
@ -123,7 +129,9 @@ __ https://en.wikipedia.org/wiki/Geography_Markup_Language
Accepts a single geographic field or expression and returns a `Keyhole Markup
Language (KML)`__ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> qs = Zipcode.objects.annotate(kml=AsKML('poly'))
>>> print(qs[0].kml)
@ -176,7 +184,9 @@ Oracle, `PostGIS <https://postgis.net/docs/ST_AsBinary.html>`__, SpatiaLite
Accepts a single geographic field or expression and returns a `Well-known
binary (WKB)`_ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> bytes(City.objects.annotate(wkb=AsWKB('point')).get(name='Chelyabinsk').wkb)
b'\x01\x01\x00\x00\x00]3\xf9f\x9b\x91K@\x00X\x1d9\xd2\xb9N@'
@ -193,7 +203,9 @@ Oracle, `PostGIS <https://postgis.net/docs/ST_AsText.html>`__, SpatiaLite
Accepts a single geographic field or expression and returns a `Well-known text
(WKT)`_ representation of the geometry.
Example::
Example:
.. code-block:: pycon
>>> City.objects.annotate(wkt=AsWKT('point')).get(name='Chelyabinsk').wkt
'POINT (55.137555 61.451728)'
@ -289,7 +301,9 @@ resource-intensive).
In the following example, the distance from the city of Hobart to every other
:class:`~django.contrib.gis.db.models.PointField` in the ``AustraliaCity``
queryset is calculated::
queryset is calculated:
.. code-block:: pycon
>>> from django.contrib.gis.db.models.functions import Distance
>>> pnt = AustraliaCity.objects.get(name='Hobart').point

View file

@ -36,7 +36,9 @@ 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
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:
.. code-block:: shell
$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/cities/cities.{shp,prj,shx,dbf}
$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/rasters/raster.tif
@ -75,7 +77,9 @@ each feature in that layer.
Once you've created your ``DataSource``, you can find out how many layers
of data it contains by accessing the :attr:`layer_count` property, or
(equivalently) by using the ``len()`` function. For information on
accessing the layers of data themselves, see the next section::
accessing the layers of data themselves, see the next section:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource('/path/to/your/cities.shp')
@ -110,7 +114,9 @@ __ https://gdal.org/drivers/vector/
Typically, all the features in a given layer have the same geometry type.
The :attr:`geom_type` property of a layer is an :class:`OGRGeomType` that
identifies the feature type. We can use it to print out some basic
information about each layer in a :class:`DataSource`::
information about each layer in a :class:`DataSource`:
.. code-block:: pycon
>>> for layer in ds:
... print('Layer "%s": %i %ss' % (layer.name, len(layer), layer.geom_type.name))
@ -120,7 +126,9 @@ __ https://gdal.org/drivers/vector/
The example output is from the cities data source, loaded above, which
evidently contains one layer, called ``"cities"``, which contains three
point features. For simplicity, the examples below assume that you've
stored that layer in the variable ``layer``::
stored that layer in the variable ``layer``:
.. code-block:: pycon
>>> layer = ds[0]
@ -128,19 +136,25 @@ __ https://gdal.org/drivers/vector/
Returns the name of this layer in the data source.
.. code-block:: pycon
>>> layer.name
'cities'
.. attribute:: num_feat
Returns the number of features in the layer. Same as ``len(layer)``::
Returns the number of features in the layer. Same as ``len(layer)``:
.. code-block:: pycon
>>> layer.num_feat
3
.. attribute:: geom_type
Returns the geometry type of the layer, as an :class:`OGRGeomType` object::
Returns the geometry type of the layer, as an :class:`OGRGeomType` object:
.. code-block:: pycon
>>> layer.geom_type.name
'Point'
@ -148,14 +162,18 @@ __ https://gdal.org/drivers/vector/
.. attribute:: num_fields
Returns the number of fields in the layer, i.e the number of fields of
data associated with each feature in the layer::
data associated with each feature in the layer:
.. code-block:: pycon
>>> layer.num_fields
4
.. attribute:: fields
Returns a list of the names of each of the fields in this layer::
Returns a list of the names of each of the fields in this layer:
.. code-block:: pycon
>>> layer.fields
['Name', 'Population', 'Density', 'Created']
@ -163,7 +181,9 @@ __ https://gdal.org/drivers/vector/
.. attribute field_types
Returns a list of the data types of each of the fields in this layer. These
are subclasses of ``Field``, discussed below::
are subclasses of ``Field``, discussed below:
.. code-block:: pycon
>>> [ft.__name__ for ft in layer.field_types]
['OFTString', 'OFTReal', 'OFTReal', 'OFTDate']
@ -171,7 +191,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: field_widths
Returns a list of the maximum field widths for each of the fields in this
layer::
layer:
.. code-block:: pycon
>>> layer.field_widths
[80, 11, 24, 10]
@ -179,14 +201,18 @@ __ https://gdal.org/drivers/vector/
.. attribute:: field_precisions
Returns a list of the numeric precisions for each of the fields in this
layer. This is meaningless (and set to zero) for non-numeric fields::
layer. This is meaningless (and set to zero) for non-numeric fields:
.. code-block:: pycon
>>> layer.field_precisions
[0, 0, 15, 0]
.. attribute:: extent
Returns the spatial extent of this layer, as an :class:`Envelope` object::
Returns the spatial extent of this layer, as an :class:`Envelope` object:
.. code-block:: pycon
>>> layer.extent.tuple
(-104.609252, 29.763374, -95.23506, 38.971823)
@ -194,7 +220,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: srs
Property that returns the :class:`SpatialReference` associated with this
layer::
layer:
.. code-block:: pycon
>>> print(layer.srs)
GEOGCS["GCS_WGS_1984",
@ -212,7 +240,9 @@ __ https://gdal.org/drivers/vector/
layer. A spatial filter can only be set with an :class:`OGRGeometry`
instance, a 4-tuple extent, or ``None``. When set with something other than
``None``, only features that intersect the filter will be returned when
iterating over the layer::
iterating over the layer:
.. code-block:: pycon
>>> print(layer.spatial_filter)
None
@ -233,7 +263,9 @@ __ https://gdal.org/drivers/vector/
.. method:: get_fields()
A method that returns a list of the values of a given field for each
feature in the layer::
feature in the layer:
.. code-block:: pycon
>>> layer.get_fields('Name')
['Pueblo', 'Lawrence', 'Houston']
@ -243,7 +275,9 @@ __ https://gdal.org/drivers/vector/
A method that returns a list containing the geometry of each feature in the
layer. If the optional argument ``geos`` is set to ``True`` then the
geometries are converted to :class:`~django.contrib.gis.geos.GEOSGeometry`
objects. Otherwise, they are returned as :class:`OGRGeometry` objects::
objects. Otherwise, they are returned as :class:`OGRGeometry` objects:
.. code-block:: pycon
>>> [pt.tuple for pt in layer.get_geoms()]
[(-104.609252, 38.255001), (-95.23506, 38.971823), (-95.363151, 29.763374)]
@ -273,7 +307,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: geom
Returns the geometry for this feature, as an ``OGRGeometry`` object::
Returns the geometry for this feature, as an ``OGRGeometry`` object:
.. code-block:: pycon
>>> city.geom.tuple
(-104.609252, 38.255001)
@ -281,7 +317,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: get
A method that returns the value of the given field (specified by name)
for this feature, **not** a ``Field`` wrapper object::
for this feature, **not** a ``Field`` wrapper object:
.. code-block:: pycon
>>> city.get('Population')
102121
@ -309,7 +347,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: fid
Returns the feature identifier within the layer::
Returns the feature identifier within the layer:
.. code-block:: pycon
>>> city.fid
0
@ -317,7 +357,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: layer_name
Returns the name of the :class:`Layer` that the feature came from. This
will be the same for all features in a given layer::
will be the same for all features in a given layer:
.. code-block:: pycon
>>> city.layer_name
'cities'
@ -325,7 +367,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: index
A method that returns the index of the given field name. This will be the
same for all features in a given layer::
same for all features in a given layer:
.. code-block:: pycon
>>> city.index('Population')
1
@ -337,7 +381,9 @@ __ https://gdal.org/drivers/vector/
.. attribute:: name
Returns the name of this field::
Returns the name of this field:
.. code-block:: pycon
>>> city['Name'].name
'Name'
@ -345,14 +391,18 @@ __ https://gdal.org/drivers/vector/
.. attribute:: type
Returns the OGR type of this field, as an integer. The ``FIELD_CLASSES``
dictionary maps these values onto subclasses of ``Field``::
dictionary maps these values onto subclasses of ``Field``:
.. code-block:: pycon
>>> city['Density'].type
2
.. attribute:: type_name
Returns a string with the name of the data type of this field::
Returns a string with the name of the data type of this field:
.. code-block:: pycon
>>> city['Name'].type_name
'String'
@ -361,14 +411,18 @@ __ https://gdal.org/drivers/vector/
Returns the value of this field. The ``Field`` class itself returns the
value as a string, but each subclass returns the value in the most
appropriate form::
appropriate form:
.. code-block:: pycon
>>> city['Population'].value
102121
.. attribute:: width
Returns the width of this field::
Returns the width of this field:
.. code-block:: pycon
>>> city['Name'].width
80
@ -376,35 +430,45 @@ __ https://gdal.org/drivers/vector/
.. attribute:: precision
Returns the numeric precision of this field. This is meaningless (and set
to zero) for non-numeric fields::
to zero) for non-numeric fields:
.. code-block:: pycon
>>> city['Density'].precision
15
.. method:: as_double()
Returns the value of the field as a double (float)::
Returns the value of the field as a double (float):
.. code-block:: pycon
>>> city['Density'].as_double()
874.7
.. method:: as_int()
Returns the value of the field as an integer::
Returns the value of the field as an integer:
.. code-block:: pycon
>>> city['Population'].as_int()
102121
.. method:: as_string()
Returns the value of the field as a string::
Returns the value of the field as a string:
.. code-block:: pycon
>>> city['Name'].as_string()
'Pueblo'
.. method:: as_datetime()
Returns the value of the field as a tuple of date and time components::
Returns the value of the field as a tuple of date and time components:
.. code-block:: pycon
>>> city['Created'].as_datetime()
(c_long(1999), c_long(5), c_long(23), c_long(0), c_long(0), c_long(0), c_long(0))
@ -432,7 +496,9 @@ OGR Geometries
around OGR's internal geometry representation. Thus, they allow for more
efficient access to data when using :class:`DataSource`. Unlike its GEOS
counterpart, :class:`OGRGeometry` supports spatial reference systems and
coordinate transformation::
coordinate transformation:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import OGRGeometry
>>> polygon = OGRGeometry('POLYGON((0 0, 5 0, 5 5, 0 5))')
@ -478,7 +544,9 @@ coordinate transformation::
.. attribute:: dimension
Returns the number of coordinated dimensions of the geometry, i.e. 0
for points, 1 for lines, and so forth::
for points, 1 for lines, and so forth:
.. code-block:: pycon
>> polygon.dimension
2
@ -490,14 +558,18 @@ coordinate transformation::
.. attribute:: geom_count
Returns the number of elements in this geometry::
Returns the number of elements in this geometry:
.. code-block:: pycon
>>> polygon.geom_count
1
.. attribute:: point_count
Returns the number of points used to describe this geometry::
Returns the number of points used to describe this geometry:
.. code-block:: pycon
>>> polygon.point_count
4
@ -516,7 +588,9 @@ coordinate transformation::
.. attribute:: geom_name
Returns the name of the type of this geometry::
Returns the name of the type of this geometry:
.. code-block:: pycon
>>> polygon.geom_name
'POLYGON'
@ -524,7 +598,9 @@ coordinate transformation::
.. attribute:: area
Returns the area of this geometry, or 0 for geometries that do not contain
an area::
an area:
.. code-block:: pycon
>>> polygon.area
25.0
@ -536,7 +612,9 @@ coordinate transformation::
.. attribute:: extent
Returns the envelope of this geometry as a 4-tuple, instead of as an
:class:`Envelope` object::
:class:`Envelope` object:
.. code-block:: pycon
>>> point.extent
(0.0, 0.0, 5.0, 5.0)
@ -547,7 +625,9 @@ coordinate transformation::
``None`` if no spatial reference system has been assigned to it.
If assigned, accessing this property returns a :class:`SpatialReference`
object. It may be set with another :class:`SpatialReference` object,
or any input that :class:`SpatialReference` accepts. Example::
or any input that :class:`SpatialReference` accepts. Example:
.. code-block:: pycon
>>> city.geom.srs.name
'GCS_WGS_1984'
@ -566,21 +646,27 @@ coordinate transformation::
.. attribute:: gml
Returns a string representation of this geometry in GML format::
Returns a string representation of this geometry in GML format:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').gml
'<gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point>'
.. attribute:: hex
Returns a string representation of this geometry in HEX WKB format::
Returns a string representation of this geometry in HEX WKB format:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').hex
'0101000000000000000000F03F0000000000000040'
.. attribute:: json
Returns a string representation of this geometry in JSON format::
Returns a string representation of this geometry in JSON format:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').json
'{ "type": "Point", "coordinates": [ 1.000000, 2.000000 ] }'
@ -592,7 +678,9 @@ coordinate transformation::
.. attribute:: wkb_size
Returns the size of the WKB buffer needed to hold a WKB representation
of this geometry::
of this geometry:
.. code-block:: pycon
>>> OGRGeometry('POINT(1 2)').wkb_size
21
@ -616,7 +704,9 @@ coordinate transformation::
.. method:: close_rings()
If there are any rings within this geometry that have not been closed,
this routine will do so by adding the starting point to the end::
this routine will do so by adding the starting point to the end:
.. code-block:: pycon
>>> triangle = OGRGeometry('LINEARRING (0 0,0 1,1 0)')
>>> triangle.close_rings()
@ -706,7 +796,9 @@ coordinate transformation::
.. attribute:: tuple
Returns the coordinates of a point geometry as a tuple, the
coordinates of a line geometry as a tuple of tuples, and so forth::
coordinates of a line geometry as a tuple of tuples, and so forth:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2)').tuple
(1.0, 2.0)
@ -721,14 +813,18 @@ coordinate transformation::
.. attribute:: x
Returns the X coordinate of this point::
Returns the X coordinate of this point:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2)').x
1.0
.. attribute:: y
Returns the Y coordinate of this point::
Returns the Y coordinate of this point:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2)').y
2.0
@ -736,7 +832,9 @@ coordinate transformation::
.. attribute:: z
Returns the Z coordinate of this point, or ``None`` if the point does not
have a Z coordinate::
have a Z coordinate:
.. code-block:: pycon
>>> OGRGeometry('POINT (1 2 3)').z
3.0
@ -745,14 +843,18 @@ coordinate transformation::
.. attribute:: x
Returns a list of X coordinates in this line::
Returns a list of X coordinates in this line:
.. code-block:: pycon
>>> OGRGeometry('LINESTRING (1 2,3 4)').x
[1.0, 3.0]
.. attribute:: y
Returns a list of Y coordinates in this line::
Returns a list of Y coordinates in this line:
.. code-block:: pycon
>>> OGRGeometry('LINESTRING (1 2,3 4)').y
[2.0, 4.0]
@ -760,7 +862,9 @@ coordinate transformation::
.. attribute:: z
Returns a list of Z coordinates in this line, or ``None`` if the line does
not have Z coordinates::
not have Z coordinates:
.. code-block:: pycon
>>> OGRGeometry('LINESTRING (1 2 3,4 5 6)').z
[3.0, 6.0]
@ -794,7 +898,9 @@ coordinate transformation::
.. class:: OGRGeomType(type_input)
This class allows for the representation of an OGR geometry type
in any of several ways::
in any of several ways:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import OGRGeomType
>>> gt1 = OGRGeomType(3) # Using an integer for the type
@ -805,14 +911,18 @@ coordinate transformation::
.. attribute:: name
Returns a short-hand string form of the OGR Geometry type::
Returns a short-hand string form of the OGR Geometry type:
.. code-block:: pycon
>>> gt1.name
'Polygon'
.. attribute:: num
Returns the number corresponding to the OGR geometry type::
Returns the number corresponding to the OGR geometry type:
.. code-block:: pycon
>>> gt1.num
3
@ -820,7 +930,9 @@ coordinate transformation::
.. attribute:: django
Returns the Django field type (a subclass of GeometryField) to use for
storing this OGR type, or ``None`` if there is no appropriate Django type::
storing this OGR type, or ``None`` if there is no appropriate Django type:
.. code-block:: pycon
>>> gt1.django
'PolygonField'
@ -885,7 +997,9 @@ Coordinate System Objects
* A shorthand string for well-known standards (``'WGS84'``, ``'WGS72'``,
``'NAD27'``, ``'NAD83'``)
Example::
Example:
.. code-block:: pycon
>>> wgs84 = SpatialReference('WGS84') # shorthand string
>>> wgs84 = SpatialReference(4326) # EPSG code
@ -907,7 +1021,9 @@ Coordinate System Objects
Returns the value of the given string attribute node, ``None`` if the node
doesn't exist. Can also take a tuple as a parameter, (target, child), where
child is the index of the attribute in the WKT. For example::
child is the index of the attribute in the WKT. For example:
.. code-block:: pycon
>>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]')
>>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326
@ -1068,7 +1184,9 @@ Coordinate System Objects
Represents a coordinate system transform. It is initialized with two
:class:`SpatialReference`, representing the source and target coordinate
systems, respectively. These objects should be used when performing the same
coordinate transformation repeatedly on different geometries::
coordinate transformation repeatedly on different geometries:
.. code-block:: pycon
>>> ct = CoordTransform(SpatialReference('WGS84'), SpatialReference('NAD83'))
>>> for feat in layer:
@ -1721,7 +1839,9 @@ Key Default Usage
The following example uses some of the options available for the
`GTiff driver`__. The result is a compressed signed byte raster with an
internal tiling scheme. The internal tiles have a block size of 23 by 23::
internal tiling scheme. The internal tiles have a block size of 23 by 23:
.. code-block:: pycon
>>> GDALRaster({
... 'driver': 'GTiff',
@ -1787,7 +1907,9 @@ from a remote storage or returned from a view without being written to disk.
``/vsimem/``.
Input provided as ``bytes`` has to be a full binary representation of a file.
For instance::
For instance:
.. code-block:: pycon
# Read a raster as a file object from a remote source.
>>> from urllib.request import urlopen
@ -1807,7 +1929,9 @@ dictionary representation and provide a ``name`` argument that starts with
of the raster.
Here's how to create a raster and return it as a file in an
:class:`~django.http.HttpResponse`::
:class:`~django.http.HttpResponse`:
.. code-block:: pycon
>>> from django.http import HttpResponse
>>> rst = GDALRaster({
@ -1838,7 +1962,9 @@ Compressed rasters
Instead decompressing the file and instantiating the resulting raster, GDAL can
directly access compressed files using the ``/vsizip/``, ``/vsigzip/``, or
``/vsitar/`` virtual filesystems::
``/vsitar/`` virtual filesystems:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import GDALRaster
>>> rst = GDALRaster('/vsizip/path/to/your/file.zip/path/to/raster.tif')
@ -1852,7 +1978,9 @@ GDAL can support online resources and storage providers transparently. As long
as it's built with such capabilities.
To access a public raster file with no authentication, you can use
``/vsicurl/``::
``/vsicurl/``:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import GDALRaster
>>> rst = GDALRaster('/vsicurl/https://example.com/raster.tif')

View file

@ -31,7 +31,9 @@ __ https://github.com/maxmind/libmaxminddb/
Example
=======
Here is an example of its usage::
Here is an example of its usage:
.. code-block:: pycon
>>> from django.contrib.gis.geoip2 import GeoIP2
>>> g = GeoIP2()

View file

@ -856,7 +856,9 @@ Keyword Argument Description
__ https://docs.oracle.com/en/database/oracle/oracle-database/21/spatl/
spatial-concepts.html#GUID-CE10AB14-D5EA-43BA-A647-DAC9EEF41EE6
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.db.models import Extent, Union
>>> WorldBorder.objects.aggregate(Extent('mpoly'), Union('mpoly'))
@ -886,7 +888,9 @@ Oracle, SpatiaLite
Returns the extent of all ``geo_field`` in the ``QuerySet`` as a four-tuple,
comprising the lower left coordinate and the upper right coordinate.
Example::
Example:
.. code-block:: pycon
>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(Extent('poly'))
>>> print(qs['poly__extent'])
@ -903,7 +907,9 @@ Returns the 3D extent of all ``geo_field`` in the ``QuerySet`` as a six-tuple,
comprising the lower left coordinate and upper right coordinate (each with x, y,
and z coordinates).
Example::
Example:
.. code-block:: pycon
>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(Extent3D('poly'))
>>> print(qs['poly__extent3d'])
@ -920,7 +926,9 @@ SpatiaLite
Returns a ``LineString`` constructed from the point field geometries in the
``QuerySet``. Currently, ordering the queryset has no effect.
Example::
Example:
.. code-block:: pycon
>>> qs = City.objects.filter(name__in=('Houston', 'Dallas')).aggregate(MakeLine('poly'))
>>> print(qs['poly__makeline'])
@ -944,7 +952,9 @@ large querysets.
If the computation time for using this method is too expensive, consider
using :class:`Collect` instead.
Example::
Example:
.. code-block:: pycon
>>> u = Zipcode.objects.aggregate(Union(poly)) # This may take a long time.
>>> u = Zipcode.objects.filter(poly__within=bbox).aggregate(Union(poly)) # A more sensible approach.

View file

@ -50,7 +50,9 @@ Creating a Geometry
:class:`GEOSGeometry` objects may be created in a few ways. The first is
to simply instantiate the object on some spatial input -- the following
are examples of creating the same geometry from WKT, HEX, WKB, and GeoJSON::
are examples of creating the same geometry from WKT, HEX, WKB, and GeoJSON:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> pnt = GEOSGeometry('POINT(5 23)') # WKT
@ -60,12 +62,16 @@ are examples of creating the same geometry from WKT, HEX, WKB, and GeoJSON::
Another option is to use the constructor for the specific geometry type
that you wish to create. For example, a :class:`Point` object may be
created by passing in the X and Y coordinates into its constructor::
created by passing in the X and Y coordinates into its constructor:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point
>>> pnt = Point(5, 23)
All these constructors take the keyword argument ``srid``. For example::
All these constructors take the keyword argument ``srid``. For example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry, LineString, Point
>>> print(GEOSGeometry('POINT (0 0)', srid=4326))
@ -76,7 +82,9 @@ All these constructors take the keyword argument ``srid``. For example::
SRID=32140;POINT (0 0)
Finally, there is the :func:`fromfile` factory method which returns a
:class:`GEOSGeometry` object from a file::
:class:`GEOSGeometry` object from a file:
.. code-block:: pycon
>>> from django.contrib.gis.geos import fromfile
>>> pnt = fromfile('/path/to/pnt.wkt')
@ -97,14 +105,18 @@ Geometries are Pythonic
-----------------------
:class:`GEOSGeometry` objects are 'Pythonic', in other words components may
be accessed, modified, and iterated over using standard Python conventions.
For example, you can iterate over the coordinates in a :class:`Point`::
For example, you can iterate over the coordinates in a :class:`Point`:
.. code-block:: pycon
>>> pnt = Point(5, 23)
>>> [coord for coord in pnt]
[5.0, 23.0]
With any geometry object, the :attr:`GEOSGeometry.coords` property
may be used to get the geometry coordinates as a Python tuple::
may be used to get the geometry coordinates as a Python tuple:
.. code-block:: pycon
>>> pnt.coords
(5.0, 23.0)
@ -112,7 +124,9 @@ may be used to get the geometry coordinates as a Python tuple::
You can get/set geometry components using standard Python indexing
techniques. However, what is returned depends on the geometry type
of the object. For example, indexing on a :class:`LineString`
returns a coordinate tuple::
returns a coordinate tuple:
.. code-block:: pycon
>>> from django.contrib.gis.geos import LineString
>>> line = LineString((0, 0), (0, 50), (50, 50), (50, 0), (0, 0))
@ -122,7 +136,9 @@ returns a coordinate tuple::
(50.0, 0.0)
Whereas indexing on a :class:`Polygon` will return the ring
(a :class:`LinearRing` object) corresponding to the index::
(a :class:`LinearRing` object) corresponding to the index:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Polygon
>>> poly = Polygon( ((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (0.0, 0.0)) )
@ -132,7 +148,9 @@ Whereas indexing on a :class:`Polygon` will return the ring
(50.0, 0.0)
In addition, coordinates/components of the geometry may added or modified,
just like a Python list::
just like a Python list:
.. code-block:: pycon
>>> line[0] = (1.0, 1.0)
>>> line.pop()
@ -141,7 +159,9 @@ just like a Python list::
>>> line.coords
((1.0, 1.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (1.0, 1.0))
Geometries support set-like operators::
Geometries support set-like operators:
.. code-block:: pycon
>>> from django.contrib.gis.geos import LineString
>>> ls1 = LineString((0, 0), (2, 2))
@ -160,7 +180,9 @@ Geometries support set-like operators::
The :class:`~GEOSGeometry` equality operator uses
:meth:`~GEOSGeometry.equals_exact`, not :meth:`~GEOSGeometry.equals`, i.e.
it requires the compared geometries to have the same coordinates in the
same positions with the same SRIDs::
same positions with the same SRIDs:
.. code-block:: pycon
>>> from django.contrib.gis.geos import LineString
>>> ls1 = LineString((0, 0), (1, 1))
@ -191,7 +213,9 @@ given ``geo_input`` argument, and then assumes the proper geometry subclass
The ``srid`` parameter, if given, is set as the SRID of the created geometry if
``geo_input`` doesn't have an SRID. If different SRIDs are provided through the
``geo_input`` and ``srid`` parameters, ``ValueError`` is raised::
``geo_input`` and ``srid`` parameters, ``ValueError`` is raised:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> GEOSGeometry('POINT EMPTY', srid=4326).ewkt
@ -246,7 +270,9 @@ Properties
.. attribute:: GEOSGeometry.geom_type
Returns a string corresponding to the type of geometry. For example::
Returns a string corresponding to the type of geometry. For example:
.. code-block:: pycon
>>> pnt = GEOSGeometry('POINT(5 23)')
>>> pnt.geom_type
@ -307,7 +333,9 @@ Properties
.. attribute:: GEOSGeometry.srid
Property that may be used to retrieve or set the SRID associated with the
geometry. For example::
geometry. For example:
.. code-block:: pycon
>>> pnt = Point(5, 23)
>>> print(pnt.srid)
@ -669,7 +697,9 @@ Other Properties & Methods
Converts this geometry to canonical form. If the ``clone`` keyword is set,
then the geometry is not modified and a normalized clone of the geometry is
returned instead::
returned instead:
.. code-block:: pycon
>>> g = MultiPoint(Point(0, 0), Point(2, 2), Point(1, 1))
>>> print(g)
@ -685,13 +715,17 @@ Other Properties & Methods
``Point`` objects are instantiated using arguments that represent the
component coordinates of the point or with a single sequence coordinates.
For example, the following are equivalent::
For example, the following are equivalent:
.. code-block:: pycon
>>> pnt = Point(5, 23)
>>> pnt = Point([5, 23])
Empty ``Point`` objects may be instantiated by passing no arguments or an
empty sequence. The following are equivalent::
empty sequence. The following are equivalent:
.. code-block:: pycon
>>> pnt = Point()
>>> pnt = Point([])
@ -703,19 +737,25 @@ Other Properties & Methods
``LineString`` objects are instantiated using arguments that are either a
sequence of coordinates or :class:`Point` objects. For example, the
following are equivalent::
following are equivalent:
.. code-block:: pycon
>>> ls = LineString((0, 0), (1, 1))
>>> ls = LineString(Point(0, 0), Point(1, 1))
In addition, ``LineString`` objects may also be created by passing in a
single sequence of coordinate or :class:`Point` objects::
single sequence of coordinate or :class:`Point` objects:
.. code-block:: pycon
>>> ls = LineString( ((0, 0), (1, 1)) )
>>> ls = LineString( [Point(0, 0), Point(1, 1)] )
Empty ``LineString`` objects may be instantiated by passing no arguments
or an empty sequence. The following are equivalent::
or an empty sequence. The following are equivalent:
.. code-block:: pycon
>>> ls = LineString()
>>> ls = LineString([])
@ -732,7 +772,9 @@ Other Properties & Methods
``LinearRing`` objects are constructed in the exact same way as
:class:`LineString` objects, however the coordinates must be *closed*, in
other words, the first coordinates must be the same as the last
coordinates. For example::
coordinates. For example:
.. code-block:: pycon
>>> ls = LinearRing((0, 0), (0, 1), (1, 1), (0, 0))
@ -751,7 +793,9 @@ Other Properties & Methods
``Polygon`` objects may be instantiated by passing in parameters that
represent the rings of the polygon. The parameters must either be
:class:`LinearRing` instances, or a sequence that may be used to construct a
:class:`LinearRing`::
:class:`LinearRing`:
.. code-block:: pycon
>>> ext_coords = ((0, 0), (0, 1), (1, 1), (1, 0), (0, 0))
>>> int_coords = ((0.4, 0.4), (0.4, 0.6), (0.6, 0.6), (0.6, 0.4), (0.4, 0.4))
@ -773,7 +817,9 @@ Other Properties & Methods
or ``>``, but as the comparison is made through Polygon's
:class:`LineString`, it does not mean much (but is consistent and quick).
You can always force the comparison with the :attr:`~GEOSGeometry.area`
property::
property:
.. code-block:: pycon
>>> if poly_1.area > poly_2.area:
>>> pass
@ -789,7 +835,9 @@ Geometry Collections
.. class:: MultiPoint(*args, **kwargs)
``MultiPoint`` objects may be instantiated by passing in :class:`Point`
objects as arguments, or a single sequence of :class:`Point` objects::
objects as arguments, or a single sequence of :class:`Point` objects:
.. code-block:: pycon
>>> mp = MultiPoint(Point(0, 0), Point(1, 1))
>>> mp = MultiPoint( (Point(0, 0), Point(1, 1)) )
@ -801,7 +849,9 @@ Geometry Collections
``MultiLineString`` objects may be instantiated by passing in
:class:`LineString` objects as arguments, or a single sequence of
:class:`LineString` objects::
:class:`LineString` objects:
.. code-block:: pycon
>>> ls1 = LineString((0, 0), (1, 1))
>>> ls2 = LineString((2, 2), (3, 3))
@ -823,7 +873,9 @@ Geometry Collections
.. class:: MultiPolygon(*args, **kwargs)
``MultiPolygon`` objects may be instantiated by passing :class:`Polygon`
objects as arguments, or a single sequence of :class:`Polygon` objects::
objects as arguments, or a single sequence of :class:`Polygon` objects:
.. code-block:: pycon
>>> p1 = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) )
>>> p2 = Polygon( ((1, 1), (1, 2), (2, 2), (1, 1)) )
@ -837,7 +889,9 @@ Geometry Collections
``GeometryCollection`` objects may be instantiated by passing in other
:class:`GEOSGeometry` as arguments, or a single sequence of
:class:`GEOSGeometry` objects::
:class:`GEOSGeometry` objects:
.. code-block:: pycon
>>> poly = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) )
>>> gc = GeometryCollection(Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly)
@ -856,7 +910,9 @@ geometry can be orders of magnitude faster -- the more complex the geometry
that is prepared, the larger the speedup in the operation. For more information,
please consult the `GEOS wiki page on prepared geometries <https://trac.osgeo.org/geos/wiki/PreparedGeometry>`_.
For example::
For example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, Polygon
>>> poly = Polygon.from_bbox((0, 0, 5, 5))
@ -899,7 +955,9 @@ Geometry Factories
:type file_h: a Python ``file`` object or a string path to the file
:rtype: a :class:`GEOSGeometry` corresponding to the spatial data in the file
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import fromfile
>>> g = fromfile('/home/bob/geom.wkt')
@ -915,7 +973,9 @@ Geometry Factories
``fromstr(string, srid)`` is equivalent to
:class:`GEOSGeometry(string, srid) <GEOSGeometry>`.
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import fromstr
>>> pnt = fromstr('POINT(-90.5 29.5)', srid=4326)
@ -931,7 +991,9 @@ and/or WKT input given to their ``read(geom)`` method.
.. class:: WKBReader
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import WKBReader
>>> wkb_r = WKBReader()
@ -940,7 +1002,9 @@ and/or WKT input given to their ``read(geom)`` method.
.. class:: WKTReader
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import WKTReader
>>> wkt_r = WKTReader()
@ -967,7 +1031,9 @@ include the SRID value (in other words, EWKB).
.. method:: WKBWriter.write(geom)
Returns the WKB of the given geometry as a Python ``buffer`` object.
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> pnt = Point(1, 1)
@ -977,7 +1043,9 @@ include the SRID value (in other words, EWKB).
.. method:: WKBWriter.write_hex(geom)
Returns WKB of the geometry in hexadecimal. Example::
Returns WKB of the geometry in hexadecimal. Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> pnt = Point(1, 1)
@ -997,7 +1065,9 @@ include the SRID value (in other words, EWKB).
1 Little Endian (e.g., compatible with x86 systems)
=============== =================================================
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
@ -1020,7 +1090,9 @@ include the SRID value (in other words, EWKB).
3 Output 3D WKB.
============ ===========================
Example::
Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
@ -1036,7 +1108,9 @@ include the SRID value (in other words, EWKB).
.. attribute:: WKBWriter.srid
Set this property with a boolean to indicate whether the SRID of the
geometry should be included with the WKB representation. Example::
geometry should be included with the WKB representation. Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
@ -1055,7 +1129,9 @@ include the SRID value (in other words, EWKB).
.. method:: WKTWriter.write(geom)
Returns the WKT of the given geometry. Example::
Returns the WKT of the given geometry. Example:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKTWriter
>>> pnt = Point(1, 1)
@ -1072,6 +1148,8 @@ include the SRID value (in other words, EWKB).
This property is used to enable or disable trimming of
unnecessary decimals.
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point, WKTWriter
>>> pnt = Point(1, 1)
>>> wkt_w = WKTWriter()

View file

@ -85,7 +85,9 @@ is required.
.. note::
On Linux platforms, it may be necessary to run the ``ldconfig`` command
after installing each library. For example::
after installing each library. For example:
.. code-block:: shell
$ sudo make install
$ sudo ldconfig
@ -106,19 +108,25 @@ internal geometry representation used by GeoDjango (it's behind the "lazy"
geometries). Specifically, the C API library is called (e.g., ``libgeos_c.so``)
directly from Python using ctypes.
First, download GEOS from the GEOS website and untar the source archive::
First, download GEOS from the GEOS website and untar the source archive:
.. code-block:: shell
$ wget https://download.osgeo.org/geos/geos-X.Y.Z.tar.bz2
$ tar xjf geos-X.Y.Z.tar.bz2
Then step into the GEOS directory, create a ``build`` folder, and step into
it::
it:
.. code-block:: shell
$ cd geos-X.Y.Z
$ mkdir build
$ cd build
Then build and install the package::
Then build and install the package:
.. code-block:: shell
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build .
@ -149,7 +157,9 @@ If using a binary package of GEOS (e.g., on Ubuntu), you may need to :ref:`binut
If your GEOS library is in a non-standard location, or you don't want to
modify the system's library path then the :setting:`GEOS_LIBRARY_PATH`
setting may be added to your Django settings file with the full path to the
GEOS C library. For example::
GEOS C library. For example:
.. code-block:: shell
GEOS_LIBRARY_PATH = '/home/bob/local/lib/libgeos_c.so'
@ -168,18 +178,24 @@ PROJ
`PROJ`_ is a library for converting geospatial data to different coordinate
reference systems.
First, download the PROJ source code::
First, download the PROJ source code:
.. code-block:: shell
$ wget https://download.osgeo.org/proj/proj-X.Y.Z.tar.gz
... and datum shifting files (download ``proj-datumgrid-X.Y.tar.gz`` for
PROJ < 7.x) [#]_::
PROJ < 7.x) [#]_:
.. code-block:: shell
$ wget https://download.osgeo.org/proj/proj-data-X.Y.tar.gz
Next, untar the source code archive, and extract the datum shifting files in the
``data`` subdirectory (use ``nad`` subdirectory for PROJ < 6.x). This must be
done *prior* to configuration::
done *prior* to configuration:
.. code-block:: shell
$ tar xzf proj-X.Y.Z.tar.gz
$ cd proj-X.Y.Z/data
@ -190,13 +206,17 @@ For PROJ 9.x and greater, releases only support builds using ``CMake`` (see
`PROJ RFC-7`_).
To build with ``CMake`` ensure your system meets the `build requirements`_.
Then create a ``build`` folder in the PROJ directory, and step into it::
Then create a ``build`` folder in the PROJ directory, and step into it:
.. code-block:: shell
$ cd proj-X.Y.Z
$ mkdir build
$ cd build
Finally, configure, make and install PROJ::
Finally, configure, make and install PROJ:
.. code-block:: shell
$ cmake ..
$ cmake --build .
@ -215,20 +235,26 @@ reading most vector and raster spatial data formats. Currently, GeoDjango only
supports :doc:`GDAL's vector data <../gdal>` capabilities [#]_.
:ref:`geosbuild` and :ref:`proj4` should be installed prior to building GDAL.
First download the latest GDAL release version and untar the archive::
First download the latest GDAL release version and untar the archive:
.. code-block:: shell
$ wget https://download.osgeo.org/gdal/X.Y.Z/gdal-X.Y.Z.tar.gz
$ tar xzf gdal-X.Y.Z.tar.gz
For GDAL 3.6.x and greater, releases only support builds using ``CMake``. To
build with ``CMake`` create a ``build`` folder in the GDAL directory, and step
into it::
into it:
.. code-block:: shell
$ cd gdal-X.Y.Z
$ mkdir build
$ cd build
Finally, configure, make and install GDAL::
Finally, configure, make and install GDAL:
.. code-block:: shell
$ cmake ..
$ cmake --build .
@ -258,7 +284,9 @@ When GeoDjango can't find the GDAL library, configure your :ref:`libsettings`
If your GDAL library is in a non-standard location, or you don't want to
modify the system's library path then the :setting:`GDAL_LIBRARY_PATH`
setting may be added to your Django settings file with the full path to
the GDAL library. For example::
the GDAL library. For example:
.. code-block:: shell
GDAL_LIBRARY_PATH = '/home/sue/local/lib/libgdal.so'

View file

@ -2,8 +2,6 @@
GeoDjango Installation
======================
.. highlight:: console
Overview
========
In general, GeoDjango installation requires:
@ -141,7 +139,9 @@ A user may set this environment variable to customize the library paths
they want to use. The typical library directory for software
built from source is ``/usr/local/lib``. Thus, ``/usr/local/lib`` needs
to be included in the ``LD_LIBRARY_PATH`` variable. For example, the user
could place the following in their bash profile::
could place the following in their bash profile:
.. code-block:: shell
export LD_LIBRARY_PATH=/usr/local/lib
@ -151,7 +151,9 @@ Setting system library path
On GNU/Linux systems, there is typically a file in ``/etc/ld.so.conf``, which may include
additional paths from files in another directory, such as ``/etc/ld.so.conf.d``.
As the root user, add the custom library path (like ``/usr/local/lib``) on a
new line in ``ld.so.conf``. This is *one* example of how to do so::
new line in ``ld.so.conf``. This is *one* example of how to do so:
.. code-block:: shell
$ sudo echo /usr/local/lib >> /etc/ld.so.conf
$ sudo ldconfig
@ -159,7 +161,9 @@ new line in ``ld.so.conf``. This is *one* example of how to do so::
For OpenSolaris users, the system library path may be modified using the
``crle`` utility. Run ``crle`` with no options to see the current configuration
and use ``crle -l`` to set with the new library path. Be *very* careful when
modifying the system library path::
modifying the system library path:
.. code-block:: shell
# crle -l $OLD_PATH:/usr/local/lib
@ -176,11 +180,15 @@ Linux system then Python's ctypes may not be able to find your library even if
your library path is set correctly and geospatial libraries were built perfectly.
The ``binutils`` package may be installed on Debian and Ubuntu systems using the
following command::
following command:
.. code-block:: shell
$ sudo apt-get install binutils
Similarly, on Red Hat and CentOS systems::
Similarly, on Red Hat and CentOS systems:
.. code-block:: shell
$ sudo yum install binutils
@ -221,7 +229,9 @@ __ https://www.python.org/ftp/python/
You will need to modify the ``PATH`` environment variable in your
``.profile`` file so that the new version of Python is used when
``python`` is entered at the command-line::
``python`` is entered at the command-line:
.. code-block:: shell
export PATH=/Library/Frameworks/Python.framework/Versions/Current/bin:$PATH
@ -255,7 +265,9 @@ It provides recipes for the GeoDjango prerequisites on Macintosh computers
running macOS. Because Homebrew still builds the software from source, `Xcode`_
is required.
Summary::
Summary:
.. code-block:: shell
$ brew install postgresql
$ brew install postgis
@ -287,7 +299,9 @@ MacPorts
running macOS. Because MacPorts still builds the software from source,
`Xcode`_ is required.
Summary::
Summary:
.. code-block:: shell
$ sudo port install postgresql13-server
$ sudo port install geos
@ -299,12 +313,16 @@ Summary::
.. note::
You will also have to modify the ``PATH`` in your ``.profile`` so
that the MacPorts programs are accessible from the command-line::
that the MacPorts programs are accessible from the command-line:
.. code-block:: shell
export PATH=/opt/local/bin:/opt/local/lib/postgresql13/bin
In addition, add the ``DYLD_FALLBACK_LIBRARY_PATH`` setting so that
the libraries can be found by Python::
the libraries can be found by Python:
.. code-block:: shell
export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib:/opt/local/lib/postgresql13
@ -434,7 +452,9 @@ psycopg
The ``psycopg`` Python module provides the interface between Python and the
PostgreSQL database. ``psycopg`` can be installed via pip within your Python
virtual environment::
virtual environment:
.. code-block:: doscon
...\> py -m pip install psycopg

View file

@ -35,7 +35,9 @@ Creating a spatial database
---------------------------
PostGIS 2 includes an extension for PostgreSQL that's used to enable spatial
functionality::
functionality:
.. code-block:: shell
$ createdb <db name>
$ psql <db name>
@ -74,7 +76,9 @@ To administer the database, you can either use the pgAdmin III program
(:menuselection:`Start --> PostgreSQL X --> pgAdmin III`) or the SQL Shell
(:menuselection:`Start --> PostgreSQL X --> SQL Shell`). For example, to create
a ``geodjango`` spatial database and user, the following may be executed from
the SQL Shell as the ``postgres`` user::
the SQL Shell as the ``postgres`` user:
.. code-block:: psql
postgres# CREATE USER geodjango PASSWORD 'my_passwd';
postgres# CREATE DATABASE geodjango OWNER geodjango;

View file

@ -33,7 +33,9 @@ SQLite
------
Check first if SQLite is compiled with the `R*Tree module`__. Run the sqlite3
command line interface and enter the following query::
command line interface and enter the following query:
.. code-block:: sqlite3
sqlite> CREATE VIRTUAL TABLE testrtree USING rtree(id,minX,maxX,minY,maxY);
@ -41,14 +43,18 @@ If you obtain an error, you will have to recompile SQLite from source. Otherwise
skip this section.
To install from sources, download the latest amalgamation source archive from
the `SQLite download page`__, and extract::
the `SQLite download page`__, and extract:
.. code-block:: shell
$ wget https://www.sqlite.org/YYYY/sqlite-amalgamation-XXX0000.zip
$ unzip sqlite-amalgamation-XXX0000.zip
$ cd sqlite-amalgamation-XXX0000
Next, run the ``configure`` script -- however the ``CFLAGS`` environment variable
needs to be customized so that SQLite knows to build the R*Tree module::
needs to be customized so that SQLite knows to build the R*Tree module:
.. code-block:: shell
$ CFLAGS="-DSQLITE_ENABLE_RTREE=1" ./configure
$ make
@ -64,7 +70,9 @@ SpatiaLite library (``libspatialite``)
--------------------------------------
Get the latest SpatiaLite library source bundle from the
`download page`__::
`download page`__:
.. code-block:: shell
$ wget https://www.gaia-gis.it/gaia-sins/libspatialite-sources/libspatialite-X.Y.Z.tar.gz
$ tar xaf libspatialite-X.Y.Z.tar.gz
@ -76,7 +84,9 @@ Get the latest SpatiaLite library source bundle from the
.. note::
For macOS users building from source, the SpatiaLite library *and* tools
need to have their ``target`` configured::
need to have their ``target`` configured:
.. code-block:: shell
$ ./configure --target=macosx
@ -93,7 +103,9 @@ Homebrew
--------
`Homebrew`_ handles all the SpatiaLite related packages on your behalf,
including SQLite, SpatiaLite, PROJ, and GEOS. Install them like this::
including SQLite, SpatiaLite, PROJ, and GEOS. Install them like this:
.. code-block:: shell
$ brew update
$ brew install spatialite-tools

View file

@ -32,7 +32,9 @@ Example
=======
#. You need a GDAL-supported data source, like a shapefile (here we're using
a simple polygon shapefile, ``test_poly.shp``, with three features)::
a simple polygon shapefile, ``test_poly.shp``, with three features):
.. code-block:: pycon
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource('test_poly.shp')
@ -62,7 +64,9 @@ Example
return 'Name: %s' % self.name
#. Use :class:`LayerMapping` to extract all the features and place them in the
database::
database:
.. code-block:: pycon
>>> from django.contrib.gis.utils import LayerMapping
>>> from geoapp.models import TestGeo
@ -206,13 +210,17 @@ should stop excessive memory use when running ``LayerMapping`` scripts.
MySQL: ``max_allowed_packet`` error
-----------------------------------
If you encounter the following error when using ``LayerMapping`` and MySQL::
If you encounter the following error when using ``LayerMapping`` and MySQL:
.. code-block:: pytb
OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")
Then the solution is to increase the value of the ``max_allowed_packet``
setting in your MySQL configuration. For example, the default value may
be something low like one megabyte -- the setting may be modified in MySQL's
configuration file (``my.cnf``) in the ``[mysqld]`` section::
configuration file (``my.cnf``) in the ``[mysqld]`` section:
.. code-block:: ini
max_allowed_packet = 10M

View file

@ -16,7 +16,9 @@ Example
:class:`Distance` objects may be instantiated using a keyword argument indicating the
context of the units. In the example below, two different distance objects are
instantiated in units of kilometers (``km``) and miles (``mi``)::
instantiated in units of kilometers (``km``) and miles (``mi``):
.. code-block:: pycon
>>> from django.contrib.gis.measure import D, Distance
>>> d1 = Distance(km=5)
@ -27,7 +29,9 @@ instantiated in units of kilometers (``km``) and miles (``mi``)::
5.0 mi
For conversions, access the preferred unit attribute to get a converted
distance quantity::
distance quantity:
.. code-block:: pycon
>>> print(d1.mi) # Converting 5 kilometers to miles
3.10685596119
@ -35,7 +39,9 @@ distance quantity::
8.04672
Moreover, arithmetic operations may be performed between the distance
objects::
objects:
.. code-block:: pycon
>>> print(d1 + d2) # Adding 5 miles to 5 kilometers
13.04672 km
@ -43,14 +49,18 @@ objects::
1.89314403881 mi
Two :class:`Distance` objects multiplied together will yield an :class:`Area`
object, which uses squared units of measure::
object, which uses squared units of measure:
.. code-block:: pycon
>>> a = d1 * d2 # Returns an Area object.
>>> print(a)
40.2336 sq_km
To determine what the attribute abbreviation of a unit is, the ``unit_attname``
class method may be used::
class method may be used:
.. code-block:: pycon
>>> print(Distance.unit_attname('US Survey Foot'))
survey_ft
@ -117,14 +127,18 @@ Measurement API
To initialize a distance object, pass in a keyword corresponding to the
desired :ref:`unit attribute name <supported_units>` set with desired
value. For example, the following creates a distance object representing 5
miles::
miles:
.. code-block:: pycon
>>> dist = Distance(mi=5)
.. method:: __getattr__(unit_att)
Returns the distance value in units corresponding to the given unit
attribute. For example::
attribute. For example:
.. code-block:: pycon
>>> print(dist.km)
8.04672
@ -132,7 +146,9 @@ Measurement API
.. classmethod:: unit_attname(unit_name)
Returns the distance unit attribute name for the given full unit name. For
example::
example:
.. code-block:: pycon
>>> Distance.unit_attname('Mile')
'mi'
@ -149,14 +165,18 @@ Measurement API
To initialize an area object, pass in a keyword corresponding to the
desired :ref:`unit attribute name <supported_units>` set with desired
value. For example, the following creates an area object representing 5
square miles::
square miles:
.. code-block:: pycon
>>> a = Area(sq_mi=5)
.. method:: __getattr__(unit_att)
Returns the area value in units corresponding to the given unit attribute.
For example::
For example:
.. code-block:: pycon
>>> print(a.sq_km)
12.949940551680001
@ -164,7 +184,9 @@ Measurement API
.. classmethod:: unit_attname(unit_name)
Returns the area unit attribute name for the given full unit name. For
example::
example:
.. code-block:: pycon
>>> Area.unit_attname('Kilometer')
'sq_km'

View file

@ -46,7 +46,9 @@ Create database user
~~~~~~~~~~~~~~~~~~~~
To make a database user with the ability to create databases, use the
following command::
following command:
.. code-block:: shell
$ createuser --createdb -R -S <user_name>
@ -54,19 +56,25 @@ The ``-R -S`` flags indicate that we do not want the user to have the ability
to create additional users (roles) or to be a superuser, respectively.
Alternatively, you may alter an existing user's role from the SQL shell
(assuming this is done from an existing superuser account)::
(assuming this is done from an existing superuser account):
.. code-block:: psql
postgres# ALTER ROLE <user_name> CREATEDB NOSUPERUSER NOCREATEROLE;
Create database superuser
~~~~~~~~~~~~~~~~~~~~~~~~~
This may be done at the time the user is created, for example::
This may be done at the time the user is created, for example:
.. code-block:: shell
$ createuser --superuser <user_name>
Or you may alter the user's role from the SQL shell (assuming this
is done from an existing superuser account)::
is done from an existing superuser account):
.. code-block:: psql
postgres# ALTER ROLE <user_name> SUPERUSER;
@ -114,10 +122,14 @@ in :mod:`django.contrib.gis`::
Assuming the settings above were in a ``postgis.py`` file in the same
directory as ``runtests.py``, then all Django and GeoDjango tests would
be performed when executing the command::
be performed when executing the command:
.. code-block:: shell
$ ./runtests.py --settings=postgis
To run only the GeoDjango test suite, specify ``gis_tests``::
To run only the GeoDjango test suite, specify ``gis_tests``:
.. code-block:: shell
$ ./runtests.py --settings=postgis gis_tests

View file

@ -321,14 +321,18 @@ First, invoke the Django shell:
$ python manage.py shell
If you downloaded the :ref:`worldborders` data earlier in the tutorial, then
you can determine its path using Python's :class:`pathlib.Path`::
you can determine its path using Python's :class:`pathlib.Path`:
.. code-block:: pycon
>>> from pathlib import Path
>>> import world
>>> world_shp = Path(world.__file__).resolve().parent / 'data' / 'TM_WORLD_BORDERS-0.3.shp'
Now, open the world borders shapefile using GeoDjango's
:class:`~django.contrib.gis.gdal.DataSource` interface::
:class:`~django.contrib.gis.gdal.DataSource` interface:
.. code-block:: pycon
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource(world_shp)
@ -336,7 +340,9 @@ Now, open the world borders shapefile using GeoDjango's
/ ... /geodjango/world/data/TM_WORLD_BORDERS-0.3.shp (ESRI Shapefile)
Data source objects can have different layers of geospatial features; however,
shapefiles are only allowed to have one layer::
shapefiles are only allowed to have one layer:
.. code-block:: pycon
>>> print(len(ds))
1
@ -344,7 +350,9 @@ shapefiles are only allowed to have one layer::
>>> print(lyr)
TM_WORLD_BORDERS-0.3
You can see the layer's geometry type and how many features it contains::
You can see the layer's geometry type and how many features it contains:
.. code-block:: pycon
>>> print(lyr.geom_type)
Polygon
@ -363,7 +371,9 @@ You can see the layer's geometry type and how many features it contains::
The :class:`~django.contrib.gis.gdal.Layer` may also have a spatial reference
system associated with it. If it does, the ``srs`` attribute will return a
:class:`~django.contrib.gis.gdal.SpatialReference` object::
:class:`~django.contrib.gis.gdal.SpatialReference` object:
.. code-block:: pycon
>>> srs = lyr.srs
>>> print(srs)
@ -401,7 +411,9 @@ string) associated with each of the fields:
You can iterate over each feature in the layer and extract information from both
the feature's geometry (accessed via the ``geom`` attribute) as well as the
feature's attribute fields (whose **values** are accessed via ``get()``
method)::
method):
.. code-block:: pycon
>>> for feat in lyr:
... print(feat.get('NAME'), feat.geom.num_points)
@ -411,18 +423,24 @@ method)::
South Georgia South Sandwich Islands 338
Taiwan 363
:class:`~django.contrib.gis.gdal.Layer` objects may be sliced::
:class:`~django.contrib.gis.gdal.Layer` objects may be sliced:
.. code-block:: pycon
>>> lyr[0:2]
[<django.contrib.gis.gdal.feature.Feature object at 0x2f47690>, <django.contrib.gis.gdal.feature.Feature object at 0x2f47650>]
And individual features may be retrieved by their feature ID::
And individual features may be retrieved by their feature ID:
.. code-block:: pycon
>>> feat = lyr[234]
>>> print(feat.get('NAME'))
San Marino
Boundary geometries may be exported as WKT and GeoJSON::
Boundary geometries may be exported as WKT and GeoJSON:
.. code-block:: pycon
>>> geom = feat.geom
>>> print(geom.wkt)
@ -484,7 +502,9 @@ Afterward, invoke the Django shell from the ``geodjango`` project directory:
$ python manage.py shell
Next, import the ``load`` module, call the ``run`` routine, and watch
``LayerMapping`` do the work::
``LayerMapping`` do the work:
.. code-block:: pycon
>>> from world import load
>>> load.run()
@ -576,7 +596,9 @@ a particular point. First, fire up the management shell:
$ python manage.py shell
Now, define a point of interest [#]_::
Now, define a point of interest [#]_:
.. code-block:: pycon
>>> pnt_wkt = 'POINT(-95.3385 29.7245)'
@ -584,7 +606,9 @@ The ``pnt_wkt`` string represents the point at -95.3385 degrees longitude,
29.7245 degrees latitude. The geometry is in a format known as
Well Known Text (WKT), a standard issued by the Open Geospatial
Consortium (OGC). [#]_ Import the ``WorldBorder`` model, and perform
a ``contains`` lookup using the ``pnt_wkt`` as the parameter::
a ``contains`` lookup using the ``pnt_wkt`` as the parameter:
.. code-block:: pycon
>>> from world.models import WorldBorder
>>> WorldBorder.objects.filter(mpoly__contains=pnt_wkt)
@ -596,7 +620,9 @@ United States (exactly what you would expect).
Similarly, you may also use a :doc:`GEOS geometry object <geos>`.
Here, you can combine the ``intersects`` spatial lookup with the ``get``
method to retrieve only the ``WorldBorder`` instance for San Marino instead
of a queryset::
of a queryset:
.. code-block:: pycon
>>> from django.contrib.gis.geos import Point
>>> pnt = Point(12.4604, 43.9420)
@ -614,19 +640,25 @@ When doing spatial queries, GeoDjango automatically transforms
geometries if they're in a different coordinate system. In the following
example, coordinates will be expressed in `EPSG SRID 32140`__,
a coordinate system specific to south Texas **only** and in units of
**meters**, not degrees::
**meters**, not degrees:
.. code-block:: pycon
>>> from django.contrib.gis.geos import GEOSGeometry, Point
>>> pnt = Point(954158.1, 4215137.1, srid=32140)
Note that ``pnt`` may also be constructed with EWKT, an "extended" form of
WKT that includes the SRID::
WKT that includes the SRID:
.. code-block:: pycon
>>> pnt = GEOSGeometry('SRID=32140;POINT(954158.1 4215137.1)')
GeoDjango's ORM will automatically wrap geometry values
in transformation SQL, allowing the developer to work at a higher level
of abstraction::
of abstraction:
.. code-block:: pycon
>>> qs = WorldBorder.objects.filter(mpoly__intersects=pnt)
>>> print(qs.query) # Generating the SQL
@ -646,7 +678,9 @@ __ https://spatialreference.org/ref/epsg/32140/
.. admonition:: Raw queries
When using :doc:`raw queries </topics/db/sql>`, you must wrap your geometry
fields so that the field value can be recognized by GEOS::
fields so that the field value can be recognized by GEOS:
.. code-block:: pycon
from django.db import connection
# or if you're querying a non-default database:
@ -663,7 +697,9 @@ GeoDjango loads geometries in a standardized textual representation. When the
geometry field is first accessed, GeoDjango creates a
:class:`~django.contrib.gis.geos.GEOSGeometry` object, exposing powerful
functionality, such as serialization properties for popular geospatial
formats::
formats:
.. code-block:: pycon
>>> sm = WorldBorder.objects.get(name='San Marino')
>>> sm.mpoly
@ -676,7 +712,9 @@ formats::
'{ "type": "MultiPolygon", "coordinates": [ [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], ...
This includes access to all of the advanced geometric operations provided by
the GEOS library::
the GEOS library:
.. code-block:: pycon
>>> pnt = Point(12.4604, 43.9420)
>>> sm.mpoly.contains(pnt)

View file

@ -180,7 +180,9 @@ Displaying messages
-------------------
.. function:: get_messages(request)
**In your template**, use something like::
**In your template**, use something like:
.. code-block:: html+django
{% if messages %}
<ul class="messages">
@ -199,7 +201,9 @@ Even if you know there is only one message, you should still iterate over the
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::
is a mapping of the message level names to their numeric value:
.. code-block:: html+django
{% if messages %}
<ul class="messages">

View file

@ -12,7 +12,9 @@ module. They are described in more detail in the `PostgreSQL docs
.. note::
All functions come without default aliases, so you must explicitly provide
one. For example::
one. For example:
.. code-block:: pycon
>>> SomeModel.objects.aggregate(arr=ArrayAgg('somefield'))
{'arr': [0, 1, 2]}
@ -97,6 +99,8 @@ General-purpose aggregation functions
published = models.BooleanField()
rank = models.IntegerField()
.. code-block:: pycon
>>> from django.db.models import Q
>>> from django.contrib.postgres.aggregates import BoolAnd
>>> Comment.objects.aggregate(booland=BoolAnd('published'))
@ -119,6 +123,8 @@ General-purpose aggregation functions
published = models.BooleanField()
rank = models.IntegerField()
.. code-block:: pycon
>>> from django.db.models import Q
>>> from django.contrib.postgres.aggregates import BoolOr
>>> Comment.objects.aggregate(boolor=BoolOr('published'))
@ -160,6 +166,8 @@ General-purpose aggregation functions
end = models.DateTimeField()
requirements = models.JSONField(blank=True, null=True)
.. code-block:: pycon
>>> from django.contrib.postgres.aggregates import JSONBAgg
>>> Room.objects.annotate(
... requirements=JSONBAgg(
@ -213,6 +221,8 @@ General-purpose aggregation functions
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
.. code-block:: pycon
>>> article = Article.objects.create(headline="NASA uses Python")
>>> article.publications.create(title="The Python Journal")
<Publication: Publication object (1)>
@ -349,7 +359,9 @@ field or an expression returning a numeric data. Both are required.
Usage examples
==============
We will use this example table::
We will use this example table:
.. code-block:: text
| FIELD1 | FIELD2 | FIELD3 |
|--------|--------|--------|
@ -357,8 +369,9 @@ We will use this example table::
| bar | 2 | (null) |
| test | 3 | 13 |
Here's some examples of some of the general-purpose aggregation functions:
Here's some examples of some of the general-purpose aggregation functions::
.. code-block:: pycon
>>> TestModel.objects.aggregate(result=StringAgg('field1', delimiter=';'))
{'result': 'foo;bar;test'}
@ -369,7 +382,9 @@ Here's some examples of some of the general-purpose aggregation functions::
The next example shows the usage of statistical aggregate functions. The
underlying math will be not described (you can read about this, for example, at
`wikipedia <https://en.wikipedia.org/wiki/Regression_analysis>`_)::
`wikipedia <https://en.wikipedia.org/wiki/Regression_analysis>`_):
.. code-block:: pycon
>>> TestModel.objects.aggregate(count=RegrCount(y='field3', x='field2'))
{'count': 2}

View file

@ -22,7 +22,9 @@ in the way that it does not act as an aggregate function and does not require
an SQL ``GROUP BY`` clause to build the list of values.
For example, if you want to annotate all related books to an author as JSON
objects::
objects:
.. code-block:: pycon
>>> from django.db.models import OuterRef
>>> from django.db.models.functions import JSONObject

View file

@ -127,7 +127,9 @@ We will use the following example model::
The :lookup:`contains` lookup is overridden on :class:`ArrayField`. The
returned objects will be those where the values passed are a subset of the
data. It uses the SQL operator ``@>``. For example::
data. It uses the SQL operator ``@>``. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
@ -149,7 +151,9 @@ data. It uses the SQL operator ``@>``. For example::
This is the inverse of the :lookup:`contains <arrayfield.contains>` lookup -
the objects returned will be those where the data is a subset of the values
passed. It uses the SQL operator ``<@``. For example::
passed. It uses the SQL operator ``<@``. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
@ -167,7 +171,9 @@ passed. It uses the SQL operator ``<@``. For example::
~~~~~~~~~~~
Returns objects where the data shares any results with the values passed. Uses
the SQL operator ``&&``. For example::
the SQL operator ``&&``. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts', 'tutorial'])
@ -193,7 +199,9 @@ the SQL operator ``&&``. For example::
~~~~~~~
Returns the length of the array. The lookups available afterward are those
available for :class:`~django.db.models.IntegerField`. For example::
available for :class:`~django.db.models.IntegerField`. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
@ -209,7 +217,9 @@ Index transforms
Index transforms index into the array. Any non-negative integer can be used.
There are no errors if it exceeds the :attr:`size <ArrayField.size>` of the
array. The lookups available after the transform are those from the
:attr:`base_field <ArrayField.base_field>`. For example::
:attr:`base_field <ArrayField.base_field>`. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
@ -236,7 +246,9 @@ Slice transforms
Slice transforms take a slice of the array. Any two non-negative integers can
be used, separated by a single underscore. The lookups available after the
transform do not change. For example::
transform do not change. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
@ -374,7 +386,9 @@ We will use the following example model::
Key lookups
~~~~~~~~~~~
To query based on a given key, you can use that key as the lookup name::
To query based on a given key, you can use that key as the lookup name:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie'})
@ -382,12 +396,16 @@ To query based on a given key, you can use that key as the lookup name::
>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>
You can chain other lookups after key lookups::
You can chain other lookups after key lookups:
.. code-block:: pycon
>>> Dog.objects.filter(data__breed__contains='l')
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
or use ``F()`` expressions to annotate a key value. For example::
or use ``F()`` expressions to annotate a key value. For example:
.. code-block:: pycon
>>> from django.db.models import F
>>> rufus = Dog.objects.annotate(breed=F("data__breed"))[0]
@ -419,7 +437,9 @@ need to use the :lookup:`hstorefield.contains` lookup instead.
The :lookup:`contains` lookup is overridden on
:class:`~django.contrib.postgres.fields.HStoreField`. The returned objects are
those where the given ``dict`` of key-value pairs are all contained in the
field. It uses the SQL operator ``@>``. For example::
field. It uses the SQL operator ``@>``. For example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
@ -439,7 +459,9 @@ field. It uses the SQL operator ``@>``. For example::
This is the inverse of the :lookup:`contains <hstorefield.contains>` lookup -
the objects returned will be those where the key-value pairs on the object are
a subset of those in the value passed. It uses the SQL operator ``<@``. For
example::
example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
@ -457,7 +479,9 @@ example::
~~~~~~~~~~~
Returns objects where the given key is in the data. Uses the SQL operator
``?``. For example::
``?``. For example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
@ -471,7 +495,9 @@ Returns objects where the given key is in the data. Uses the SQL operator
~~~~~~~~~~~~~~~~
Returns objects where any of the given keys are in the data. Uses the SQL
operator ``?|``. For example::
operator ``?|``. For example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
@ -486,7 +512,9 @@ operator ``?|``. For example::
~~~~~~~~~~~~
Returns objects where all of the given keys are in the data. Uses the SQL operator
``?&``. For example::
``?&``. For example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
@ -503,7 +531,9 @@ Returns objects where the array of keys is the given value. Note that the order
is not guaranteed to be reliable, so this transform is mainly useful for using
in conjunction with lookups on
:class:`~django.contrib.postgres.fields.ArrayField`. Uses the SQL function
``akeys()``. For example::
``akeys()``. For example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'toy': 'bone'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
@ -520,7 +550,9 @@ Returns objects where the array of values is the given value. Note that the
order is not guaranteed to be reliable, so this transform is mainly useful for
using in conjunction with lookups on
:class:`~django.contrib.postgres.fields.ArrayField`. Uses the SQL function
``avals()``. For example::
``avals()``. For example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
@ -642,7 +674,9 @@ model::
def __str__(self):
return self.name
We will also use the following example objects::
We will also use the following example objects:
.. code-block:: pycon
>>> import datetime
>>> from django.utils import timezone
@ -685,7 +719,9 @@ The ``contained_by`` lookup is also available on the non-range field types:
:class:`~django.db.models.BigIntegerField`,
:class:`~django.db.models.DecimalField`, :class:`~django.db.models.FloatField`,
:class:`~django.db.models.DateField`, and
:class:`~django.db.models.DateTimeField`. For example::
:class:`~django.db.models.DateTimeField`. For example:
.. code-block:: pycon
>>> from django.db.backends.postgresql.psycopg_any import DateTimeTZRange
>>> Event.objects.filter(

View file

@ -23,7 +23,9 @@ Fields
It specifies the underlying form field for the array. This is not used
to render any HTML, but it is used to process the submitted data and
validate it. For example::
validate it. For example:
.. code-block:: pycon
>>> from django import forms
>>> from django.contrib.postgres.forms import SimpleArrayField
@ -45,7 +47,9 @@ Fields
This is an optional argument which defaults to a comma: ``,``. This
value is used to split the submitted data. It allows you to chain
``SimpleArrayField`` for multidimensional data::
``SimpleArrayField`` for multidimensional data:
.. code-block:: pycon
>>> from django import forms
>>> from django.contrib.postgres.forms import SimpleArrayField

View file

@ -20,7 +20,9 @@ operation to install it.
.. _pgcrypto extension: https://www.postgresql.org/docs/current/pgcrypto.html
Usage example::
Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.functions import RandomUUID
>>> Article.objects.update(uuid=RandomUUID())
@ -41,7 +43,9 @@ sets up a transaction and thus sets the time that ``TransactionNow()`` will
return; nested calls create savepoints which do not affect the transaction
time.
Usage example::
Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.functions import TransactionNow
>>> Article.objects.filter(published__lte=TransactionNow())

View file

@ -23,7 +23,9 @@ extension using the
operation.
The ``trigram_similar`` lookup can be used on
:class:`~django.db.models.CharField` and :class:`~django.db.models.TextField`::
:class:`~django.db.models.CharField` and :class:`~django.db.models.TextField`:
.. code-block:: pycon
>>> City.objects.filter(name__trigram_similar="Middlesborough")
['<City: Middlesbrough>']
@ -47,7 +49,9 @@ extension using the
operation.
The ``trigram_word_similar`` lookup can be used on
:class:`~django.db.models.CharField` and :class:`~django.db.models.TextField`::
:class:`~django.db.models.CharField` and :class:`~django.db.models.TextField`:
.. code-block:: pycon
>>> Sentence.objects.filter(name__trigram_word_similar='Middlesborough')
['<Sentence: Gumby rides on the path of Middlesbrough>']
@ -91,7 +95,9 @@ operation is available if you want to perform this activation using migrations).
.. _unaccent extension on PostgreSQL: https://www.postgresql.org/docs/current/unaccent.html
The ``unaccent`` lookup can be used on
:class:`~django.db.models.CharField` and :class:`~django.db.models.TextField`::
:class:`~django.db.models.CharField` and :class:`~django.db.models.TextField`:
.. code-block:: pycon
>>> City.objects.filter(name__unaccent="México")
['<City: Mexico>']

View file

@ -22,7 +22,9 @@ The ``search`` lookup
.. fieldlookup:: search
A common way to use full text search is to search a single term against a
single column in the database. For example::
single column in the database. For example:
.. code-block:: pycon
>>> Entry.objects.filter(body_text__search='Cheese')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]
@ -42,7 +44,9 @@ To use the ``search`` lookup, ``'django.contrib.postgres'`` must be in your
Searching against a single field is great but rather limiting. The ``Entry``
instances we're searching belong to a ``Blog``, which has a ``tagline`` field.
To query against both fields, use a ``SearchVector``::
To query against both fields, use a ``SearchVector``:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchVector
>>> Entry.objects.annotate(
@ -56,7 +60,9 @@ arguments will be concatenated together using a space so that the search
document includes them all.
``SearchVector`` objects can be combined together, allowing you to reuse them.
For example::
For example:
.. code-block:: pycon
>>> Entry.objects.annotate(
... search=SearchVector('body_text') + SearchVector('blog__tagline'),
@ -96,7 +102,9 @@ Examples:
>>> SearchQuery("'tomato' & ('red' | 'green')", search_type='raw') # boolean operators
>>> SearchQuery("'tomato' ('red' OR 'green')", search_type='websearch') # websearch operators
``SearchQuery`` terms can be combined logically to provide more flexibility::
``SearchQuery`` terms can be combined logically to provide more flexibility:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchQuery
>>> SearchQuery('meat') & SearchQuery('cheese') # AND
@ -117,7 +125,9 @@ 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
order by relevancy::
order by relevancy:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector('body_text')
@ -134,7 +144,9 @@ account.
Provide an integer to the ``normalization`` parameter to control rank
normalization. This integer is a bit mask, so you can combine multiple
behaviors::
behaviors:
.. code-block:: pycon
>>> from django.db.models import Value
>>> Entry.objects.annotate(
@ -182,7 +194,9 @@ between fragments. PostgreSQL's default is ``" ... "``.
The PostgreSQL documentation has more details on `highlighting search
results`_.
Usage example::
Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchHeadline, SearchQuery
>>> query = SearchQuery('red tomato')
@ -209,7 +223,9 @@ Changing the search configuration
You can specify the ``config`` attribute to a :class:`SearchVector` and
:class:`SearchQuery` to use a different search configuration. This allows using
different language parsers and dictionaries as defined by the database::
different language parsers and dictionaries as defined by the database:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchQuery, SearchVector
>>> Entry.objects.annotate(
@ -217,7 +233,9 @@ different language parsers and dictionaries as defined by the database::
... ).filter(search=SearchQuery('œuf', config='french'))
[<Entry: Pain perdu>]
The value of ``config`` could also be stored in another column::
The value of ``config`` could also be stored in another column:
.. code-block:: pycon
>>> from django.db.models import F
>>> Entry.objects.annotate(
@ -231,7 +249,9 @@ Weighting queries
=================
Every field may not have the same relevance in a query, so you can set weights
of various vectors before you combine them::
of various vectors before you combine them:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector('body_text', weight='A') + SearchVector('blog__tagline', weight='B')
@ -241,7 +261,9 @@ of various vectors before you combine them::
The weight should be one of the following letters: D, C, B, A. By default,
these weights refer to the numbers ``0.1``, ``0.2``, ``0.4``, and ``1.0``,
respectively. If you wish to weight them differently, pass a list of four
floats to :class:`SearchRank` as ``weights`` in the same order above::
floats to :class:`SearchRank` as ``weights`` in the same order above:
.. code-block:: pycon
>>> rank = SearchRank(vector, query, weights=[0.2, 0.4, 0.6, 0.8])
>>> Entry.objects.annotate(rank=rank).filter(rank__gte=0.3).order_by('-rank')
@ -277,7 +299,9 @@ The PostgreSQL documentation has details on
If this approach becomes too slow, you can add a ``SearchVectorField`` to your
model. You'll need to keep it populated with triggers, for example, as
described in the `PostgreSQL documentation`_. You can then query the field as
if it were an annotated ``SearchVector``::
if it were an annotated ``SearchVector``:
.. code-block:: pycon
>>> Entry.objects.update(search_vector=SearchVector('body_text'))
>>> Entry.objects.filter(search_vector='cheese')
@ -307,7 +331,9 @@ operation.
Accepts a field name or expression, and a string or expression. Returns the
trigram similarity between the two arguments.
Usage example::
Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramSimilarity
>>> Author.objects.create(name='Katy Stevens')
@ -326,7 +352,9 @@ Usage example::
Accepts a string or expression, and a field name or expression. Returns the
trigram word similarity between the two arguments.
Usage example::
Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramWordSimilarity
>>> Author.objects.create(name='Katy Stevens')
@ -357,7 +385,9 @@ extent boundaries to match word boundaries.
Accepts a field name or expression, and a string or expression. Returns the
trigram distance between the two arguments.
Usage example::
Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramDistance
>>> Author.objects.create(name='Katy Stevens')
@ -376,7 +406,9 @@ Usage example::
Accepts a string or expression, and a field name or expression. Returns the
trigram word distance between the two arguments.
Usage example::
Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramWordDistance
>>> Author.objects.create(name='Katy Stevens')

View file

@ -74,7 +74,9 @@ Via the Python API
Redirects are represented by a standard :doc:`Django model </topics/db/models>`,
which lives in :source:`django/contrib/redirects/models.py`. You can access
redirect objects via the :doc:`Django database API </topics/db/queries>`.
For example::
For example:
.. code-block:: pycon
>>> from django.conf import settings
>>> from django.contrib.redirects.models import Redirect

View file

@ -623,7 +623,9 @@ Pinging Google via ``manage.py``
.. django-admin:: ping_google [sitemap_url]
Once the sitemaps application is added to your project, you may also
ping Google using the ``ping_google`` management command::
ping Google using the ``ping_google`` management command:
.. code-block:: shell
python manage.py ping_google [/sitemap.xml]

View file

@ -241,7 +241,9 @@ 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. An example::
To do this, you can use the sites framework. An example:
.. code-block:: pycon
>>> from django.contrib.sites.models import Site
>>> obj = MyModel.objects.get(id=3)

View file

@ -1004,7 +1004,9 @@ They share this interface:
:meth:`.SyndicationFeed.writeString`
Returns the feed as a string in the given encoding.
For example, to create an Atom 1.0 feed and print it to standard output::
For example, to create an Atom 1.0 feed and print it to standard output:
.. code-block:: pycon
>>> from django.utils import feedgenerator
>>> from datetime import datetime