diff options
author | Nishanth Amuluru | 2011-01-11 22:41:51 +0530 |
---|---|---|
committer | Nishanth Amuluru | 2011-01-11 22:41:51 +0530 |
commit | b03203c8cb991c16ac8a3d74c8c4078182d0bb48 (patch) | |
tree | 7cf13b2deacbfaaec99edb431b83ddd5ea734a52 /parts/django/docs/ref/contrib | |
parent | 0c50203cd9eb94b819883c3110922e873f003138 (diff) | |
download | pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.gz pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.bz2 pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.zip |
removed all the buildout files
Diffstat (limited to 'parts/django/docs/ref/contrib')
58 files changed, 0 insertions, 15593 deletions
diff --git a/parts/django/docs/ref/contrib/admin/_images/article_actions.png b/parts/django/docs/ref/contrib/admin/_images/article_actions.png Binary files differdeleted file mode 100644 index 78a78ae..0000000 --- a/parts/django/docs/ref/contrib/admin/_images/article_actions.png +++ /dev/null diff --git a/parts/django/docs/ref/contrib/admin/_images/article_actions_message.png b/parts/django/docs/ref/contrib/admin/_images/article_actions_message.png Binary files differdeleted file mode 100644 index 6ea9439..0000000 --- a/parts/django/docs/ref/contrib/admin/_images/article_actions_message.png +++ /dev/null diff --git a/parts/django/docs/ref/contrib/admin/_images/flatfiles_admin.png b/parts/django/docs/ref/contrib/admin/_images/flatfiles_admin.png Binary files differdeleted file mode 100644 index 391a629..0000000 --- a/parts/django/docs/ref/contrib/admin/_images/flatfiles_admin.png +++ /dev/null diff --git a/parts/django/docs/ref/contrib/admin/_images/user_actions.png b/parts/django/docs/ref/contrib/admin/_images/user_actions.png Binary files differdeleted file mode 100644 index fdbe2ad..0000000 --- a/parts/django/docs/ref/contrib/admin/_images/user_actions.png +++ /dev/null diff --git a/parts/django/docs/ref/contrib/admin/_images/users_changelist.png b/parts/django/docs/ref/contrib/admin/_images/users_changelist.png Binary files differdeleted file mode 100644 index d5f9c01..0000000 --- a/parts/django/docs/ref/contrib/admin/_images/users_changelist.png +++ /dev/null diff --git a/parts/django/docs/ref/contrib/admin/actions.txt b/parts/django/docs/ref/contrib/admin/actions.txt deleted file mode 100644 index 0fab59e..0000000 --- a/parts/django/docs/ref/contrib/admin/actions.txt +++ /dev/null @@ -1,351 +0,0 @@ -============= -Admin actions -============= - -.. versionadded:: 1.1 - -.. currentmodule:: django.contrib.admin - -The basic workflow of Django's admin is, in a nutshell, "select an object, -then change it." This works well for a majority of use cases. However, if you -need to make the same change to many objects at once, this workflow can be -quite tedious. - -In these cases, Django's admin lets you write and register "actions" -- simple -functions that get called with a list of objects selected on the change list -page. - -If you look at any change list in the admin, you'll see this feature in -action; Django ships with a "delete selected objects" action available to all -models. For example, here's the user module from Django's built-in -:mod:`django.contrib.auth` app: - -.. image:: _images/user_actions.png - -.. warning:: - - The "delete selected objects" action uses :meth:`QuerySet.delete() - <django.db.models.QuerySet.delete>` for efficiency reasons, which has an - important caveat: your model's ``delete()`` method will not be called. - - If you wish to override this behavior, simply write a custom action which - accomplishes deletion in your preferred manner -- for example, by calling - ``Model.delete()`` for each of the selected items. - - For more background on bulk deletion, see the documentation on :ref:`object - deletion <topics-db-queries-delete>`. - -Read on to find out how to add your own actions to this list. - -Writing actions -=============== - -The easiest way to explain actions is by example, so let's dive in. - -A common use case for admin actions is the bulk updating of a model. Imagine a -simple news application with an ``Article`` model:: - - from django.db import models - - STATUS_CHOICES = ( - ('d', 'Draft'), - ('p', 'Published'), - ('w', 'Withdrawn'), - ) - - class Article(models.Model): - title = models.CharField(max_length=100) - body = models.TextField() - status = models.CharField(max_length=1, choices=STATUS_CHOICES) - - def __unicode__(self): - return self.title - -A common task we might perform with a model like this is to update an -article's status from "draft" to "published". We could easily do this in the -admin one article at a time, but if we wanted to bulk-publish a group of -articles, it'd be tedious. So, let's write an action that lets us change an -article's status to "published." - -Writing action functions ------------------------- - -First, we'll need to write a function that gets called when the action is -trigged from the admin. Action functions are just regular functions that take -three arguments: - - * The current :class:`ModelAdmin` - * An :class:`~django.http.HttpRequest` representing the current request, - * A :class:`~django.db.models.QuerySet` containing the set of objects - selected by the user. - -Our publish-these-articles function won't need the :class:`ModelAdmin` or the -request object, but we will use the queryset:: - - def make_published(modeladmin, request, queryset): - queryset.update(status='p') - -.. note:: - - For the best performance, we're using the queryset's :ref:`update method - <topics-db-queries-update>`. Other types of actions might need to deal - with each object individually; in these cases we'd just iterate over the - queryset:: - - for obj in queryset: - do_something_with(obj) - -That's actually all there is to writing an action! However, we'll take one -more optional-but-useful step and give the action a "nice" title in the admin. -By default, this action would appear in the action list as "Make published" -- -the function name, with underscores replaced by spaces. That's fine, but we -can provide a better, more human-friendly name by giving the -``make_published`` function a ``short_description`` attribute:: - - def make_published(modeladmin, request, queryset): - queryset.update(status='p') - make_published.short_description = "Mark selected stories as published" - -.. note:: - - This might look familiar; the admin's ``list_display`` option uses the - same technique to provide human-readable descriptions for callback - functions registered there, too. - -Adding actions to the :class:`ModelAdmin` ------------------------------------------ - -Next, we'll need to inform our :class:`ModelAdmin` of the action. This works -just like any other configuration option. So, the complete ``admin.py`` with -the action and its registration would look like:: - - from django.contrib import admin - from myapp.models import Article - - def make_published(modeladmin, request, queryset): - queryset.update(status='p') - make_published.short_description = "Mark selected stories as published" - - class ArticleAdmin(admin.ModelAdmin): - list_display = ['title', 'status'] - ordering = ['title'] - actions = [make_published] - - admin.site.register(Article, ArticleAdmin) - -That code will give us an admin change list that looks something like this: - -.. image:: _images/article_actions.png - -That's really all there is to it! If you're itching to write your own actions, -you now know enough to get started. The rest of this document just covers more -advanced techniques. - -Advanced action techniques -========================== - -There's a couple of extra options and possibilities you can exploit for more -advanced options. - -Actions as :class:`ModelAdmin` methods --------------------------------------- - -The example above shows the ``make_published`` action defined as a simple -function. That's perfectly fine, but it's not perfect from a code design point -of view: since the action is tightly coupled to the ``Article`` object, it -makes sense to hook the action to the ``ArticleAdmin`` object itself. - -That's easy enough to do:: - - class ArticleAdmin(admin.ModelAdmin): - ... - - actions = ['make_published'] - - def make_published(self, request, queryset): - queryset.update(status='p') - make_published.short_description = "Mark selected stories as published" - -Notice first that we've moved ``make_published`` into a method and renamed the -`modeladmin` parameter to `self`, and second that we've now put the string -``'make_published'`` in ``actions`` instead of a direct function reference. This -tells the :class:`ModelAdmin` to look up the action as a method. - -Defining actions as methods gives the action more straightforward, idiomatic -access to the :class:`ModelAdmin` itself, allowing the action to call any of the -methods provided by the admin. - -.. _custom-admin-action: - -For example, we can use ``self`` to flash a message to the user informing her -that the action was successful:: - - class ArticleAdmin(admin.ModelAdmin): - ... - - def make_published(self, request, queryset): - rows_updated = queryset.update(status='p') - if rows_updated == 1: - message_bit = "1 story was" - else: - message_bit = "%s stories were" % rows_updated - self.message_user(request, "%s successfully marked as published." % message_bit) - -This make the action match what the admin itself does after successfully -performing an action: - -.. image:: _images/article_actions_message.png - -Actions that provide intermediate pages ---------------------------------------- - -By default, after an action is performed the user is simply redirected back -to the original change list page. However, some actions, especially more -complex ones, will need to return intermediate pages. For example, the -built-in delete action asks for confirmation before deleting the selected -objects. - -To provide an intermediary page, simply return an -:class:`~django.http.HttpResponse` (or subclass) from your action. For -example, you might write a simple export function that uses Django's -:doc:`serialization functions </topics/serialization>` to dump some selected -objects as JSON:: - - from django.http import HttpResponse - from django.core import serializers - - def export_as_json(modeladmin, request, queryset): - response = HttpResponse(mimetype="text/javascript") - serializers.serialize("json", queryset, stream=response) - return response - -Generally, something like the above isn't considered a great idea. Most of the -time, the best practice will be to return an -:class:`~django.http.HttpResponseRedirect` and redirect the user to a view -you've written, passing the list of selected objects in the GET query string. -This allows you to provide complex interaction logic on the intermediary -pages. For example, if you wanted to provide a more complete export function, -you'd want to let the user choose a format, and possibly a list of fields to -include in the export. The best thing to do would be to write a small action -that simply redirects to your custom export view:: - - from django.contrib import admin - from django.contrib.contenttypes.models import ContentType - from django.http import HttpResponseRedirect - - def export_selected_objects(modeladmin, request, queryset): - selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) - ct = ContentType.objects.get_for_model(queryset.model) - return HttpResponseRedirect("/export/?ct=%s&ids=%s" % (ct.pk, ",".join(selected))) - -As you can see, the action is the simple part; all the complex logic would -belong in your export view. This would need to deal with objects of any type, -hence the business with the ``ContentType``. - -Writing this view is left as an exercise to the reader. - -.. _adminsite-actions: - -Making actions available site-wide ----------------------------------- - -.. method:: AdminSite.add_action(action[, name]) - - Some actions are best if they're made available to *any* object in the admin - site -- the export action defined above would be a good candidate. You can - make an action globally available using :meth:`AdminSite.add_action()`. For - example:: - - from django.contrib import admin - - admin.site.add_action(export_selected_objects) - - This makes the `export_selected_objects` action globally available as an - action named `"export_selected_objects"`. You can explicitly give the action - a name -- good if you later want to programatically :ref:`remove the action - <disabling-admin-actions>` -- by passing a second argument to - :meth:`AdminSite.add_action()`:: - - admin.site.add_action(export_selected_objects, 'export_selected') - -.. _disabling-admin-actions: - -Disabling actions ------------------ - -Sometimes you need to disable certain actions -- especially those -:ref:`registered site-wide <adminsite-actions>` -- for particular objects. -There's a few ways you can disable actions: - -Disabling a site-wide action -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. method:: AdminSite.disable_action(name) - - If you need to disable a :ref:`site-wide action <adminsite-actions>` you can - call :meth:`AdminSite.disable_action()`. - - For example, you can use this method to remove the built-in "delete selected - objects" action:: - - admin.site.disable_action('delete_selected') - - Once you've done the above, that action will no longer be available - site-wide. - - If, however, you need to re-enable a globally-disabled action for one - particular model, simply list it explicitly in your ``ModelAdmin.actions`` - list:: - - # Globally disable delete selected - admin.site.disable_action('delete_selected') - - # This ModelAdmin will not have delete_selected available - class SomeModelAdmin(admin.ModelAdmin): - actions = ['some_other_action'] - ... - - # This one will - class AnotherModelAdmin(admin.ModelAdmin): - actions = ['delete_selected', 'a_third_action'] - ... - - -Disabling all actions for a particular :class:`ModelAdmin` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you want *no* bulk actions available for a given :class:`ModelAdmin`, simply -set :attr:`ModelAdmin.actions` to ``None``:: - - class MyModelAdmin(admin.ModelAdmin): - actions = None - -This tells the :class:`ModelAdmin` to not display or allow any actions, -including any :ref:`site-wide actions <adminsite-actions>`. - -Conditionally enabling or disabling actions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. method:: ModelAdmin.get_actions(request) - - Finally, you can conditionally enable or disable actions on a per-request - (and hence per-user basis) by overriding :meth:`ModelAdmin.get_actions`. - - This returns a dictionary of actions allowed. The keys are action names, and - the values are ``(function, name, short_description)`` tuples. - - Most of the time you'll use this method to conditionally remove actions from - the list gathered by the superclass. For example, if I only wanted users - whose names begin with 'J' to be able to delete objects in bulk, I could do - the following:: - - class MyModelAdmin(admin.ModelAdmin): - ... - - def get_actions(self, request): - actions = super(MyModelAdmin, self).get_actions(request) - if request.user.username[0].upper() != 'J': - del actions['delete_selected'] - return actions - - diff --git a/parts/django/docs/ref/contrib/admin/admindocs.txt b/parts/django/docs/ref/contrib/admin/admindocs.txt deleted file mode 100644 index 6743921..0000000 --- a/parts/django/docs/ref/contrib/admin/admindocs.txt +++ /dev/null @@ -1,161 +0,0 @@ -========================================
-The Django admin documentation generator
-========================================
-
-.. module:: django.contrib.admindocs
- :synopsis: Django's admin documentation generator.
-
-.. currentmodule:: django.contrib.admindocs
-
-Django's :mod:`~django.contrib.admindocs` app pulls documentation from the
-docstrings of models, views, template tags, and template filters for any app in
-:setting:`INSTALLED_APPS` and makes that documentation available from the
-:mod:`Django admin <django.contrib.admin>`.
-
-In addition to providing offline documentation for all template tags and
-template filters that ship with Django, you may utilize admindocs to quickly
-document your own code.
-
-Overview
-========
-
-To activate the :mod:`~django.contrib.admindocs`, you will need to do
-the following:
-
- * Add :mod:`django.contrib.admindocs` to your :setting:`INSTALLED_APPS`.
- * Add ``(r'^admin/doc/', include('django.contrib.admindocs.urls'))`` to
- your :data:`urlpatterns`. Make sure it's included *before* the
- ``r'^admin/'`` entry, so that requests to ``/admin/doc/`` don't get
- handled by the latter entry.
- * Install the docutils Python module (http://docutils.sf.net/).
- * **Optional:** Linking to templates requires the :setting:`ADMIN_FOR`
- setting to be configured.
- * **Optional:** Using the admindocs bookmarklets requires the
- :mod:`XViewMiddleware<django.middleware.doc>` to be installed.
-
-Once those steps are complete, you can start browsing the documentation by
-going to your admin interface and clicking the "Documentation" link in the
-upper right of the page.
-
-Documentation helpers
-=====================
-
-The following special markup can be used in your docstrings to easily create
-hyperlinks to other components:
-
-================= =======================
-Django Component reStructuredText roles
-================= =======================
-Models ``:model:`appname.ModelName```
-Views ``:view:`appname.view_name```
-Template tags ``:tag:`tagname```
-Template filters ``:filter:`filtername```
-Templates ``:template:`path/to/template.html```
-================= =======================
-
-Model reference
-===============
-
-The **models** section of the ``admindocs`` page describes each model in the
-system along with all the fields and methods available on it. Relationships to
-other models appear as hyperlinks. Descriptions are pulled from ``help_text``
-attributes on fields or from docstrings on model methods.
-
-A model with useful documentation might look like this::
-
- class BlogEntry(models.Model):
- """
- Stores a single blog entry, related to :model:`blog.Blog` and
- :model:`auth.User`.
-
- """
- slug = models.SlugField(help_text="A short label, generally used in URLs.")
- author = models.ForeignKey(User)
- blog = models.ForeignKey(Blog)
- ...
-
- def publish(self):
- """Makes the blog entry live on the site."""
- ...
-
-View reference
-==============
-
-Each URL in your site has a separate entry in the ``admindocs`` page, and
-clicking on a given URL will show you the corresponding view. Helpful things
-you can document in your view function docstrings include:
-
- * A short description of what the view does.
- * The **context**, or a list of variables available in the view's template.
- * The name of the template or templates that are used for that view.
-
-For example::
-
- from myapp.models import MyModel
-
- def my_view(request, slug):
- """
- Display an individual :model:`myapp.MyModel`.
-
- **Context**
-
- ``RequestContext``
-
- ``mymodel``
- An instance of :model:`myapp.MyModel`.
-
- **Template:**
-
- :template:`myapp/my_template.html`
-
- """
- return render_to_response('myapp/my_template.html', {
- 'mymodel': MyModel.objects.get(slug=slug)
- }, context_instance=RequestContext(request))
-
-
-Template tags and filters reference
-===================================
-
-The **tags** and **filters** ``admindocs`` sections describe all the tags and
-filters that come with Django (in fact, the :ref:`built-in tag reference
-<ref-templates-builtins-tags>` and :ref:`built-in filter reference
-<ref-templates-builtins-filters>` documentation come directly from those
-pages). Any tags or filters that you create or are added by a third-party app
-will show up in these sections as well.
-
-
-Template reference
-==================
-
-While ``admindocs`` does not include a place to document templates by
-themselves, if you use the ``:template:`path/to/template.html``` syntax in a
-docstring the resulting page will verify the path of that template with
-Django's :ref:`template loaders <template-loaders>`. This can be a handy way to
-check if the specified template exists and to show where on the filesystem that
-template is stored.
-
-
-Included Bookmarklets
-=====================
-
-Several useful bookmarklets are available from the ``admindocs`` page:
-
- Documentation for this page
- Jumps you from any page to the documentation for the view that generates
- that page.
-
- Show object ID
- Shows the content-type and unique ID for pages that represent a single
- object.
-
- Edit this object
- Jumps to the admin page for pages that represent a single object.
-
-Using these bookmarklets requires that you are either logged into the
-:mod:`Django admin <django.contrib.admin>` as a
-:class:`~django.contrib.auth.models.User` with
-:attr:`~django.contrib.auth.models.User.is_staff` set to `True`, or
-that the :mod:`django.middleware.doc` middleware and
-:mod:`XViewMiddleware <django.middleware.doc>` are installed and you
-are accessing the site from an IP address listed in :setting:`INTERNAL_IPS`.
diff --git a/parts/django/docs/ref/contrib/admin/index.txt b/parts/django/docs/ref/contrib/admin/index.txt deleted file mode 100644 index b99cfdc..0000000 --- a/parts/django/docs/ref/contrib/admin/index.txt +++ /dev/null @@ -1,1613 +0,0 @@ -===================== -The Django admin site -===================== - -.. module:: django.contrib.admin - :synopsis: Django's admin site. - -One of the most powerful parts of Django is the automatic admin interface. It -reads metadata in your model to provide a powerful and production-ready -interface that content producers can immediately use to start adding content to -the site. In this document, we discuss how to activate, use and customize -Django's admin interface. - -.. admonition:: Note - - The admin site has been refactored significantly since Django 0.96. This - document describes the newest version of the admin site, which allows for - much richer customization. If you follow the development of Django itself, - you may have heard this described as "newforms-admin." - -Overview -======== - -There are six steps in activating the Django admin site: - - 1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS` - setting. - - 2. Admin has two dependencies - ``django.contrib.auth`` and - ``django.contrib.contenttypes``. If these applications are not - in your :setting:`INSTALLED_APPS` list, add them. - - 3. Determine which of your application's models should be editable in the - admin interface. - - 4. For each of those models, optionally create a ``ModelAdmin`` class that - encapsulates the customized admin functionality and options for that - particular model. - - 5. Instantiate an ``AdminSite`` and tell it about each of your models and - ``ModelAdmin`` classes. - - 6. Hook the ``AdminSite`` instance into your URLconf. - -Other topics ------------- - -.. toctree:: - :maxdepth: 1 - - actions - admindocs - -.. seealso:: - - For information about serving the media files (images, JavaScript, and CSS) - associated with the admin in production, see :ref:`serving-media-files`. - -``ModelAdmin`` objects -====================== - -.. class:: ModelAdmin - -The ``ModelAdmin`` class is the representation of a model in the admin -interface. These are stored in a file named ``admin.py`` in your application. -Let's take a look at a very simple example of the ``ModelAdmin``:: - - from django.contrib import admin - from myproject.myapp.models import Author - - class AuthorAdmin(admin.ModelAdmin): - pass - admin.site.register(Author, AuthorAdmin) - -.. admonition:: Do you need a ``ModelAdmin`` object at all? - - In the preceding example, the ``ModelAdmin`` class doesn't define any - custom values (yet). As a result, the default admin interface will be - provided. If you are happy with the default admin interface, you don't - need to define a ``ModelAdmin`` object at all -- you can register the - model class without providing a ``ModelAdmin`` description. The - preceding example could be simplified to:: - - from django.contrib import admin - from myproject.myapp.models import Author - - admin.site.register(Author) - -``ModelAdmin`` Options ----------------------- - -The ``ModelAdmin`` is very flexible. It has several options for dealing with -customizing the interface. All options are defined on the ``ModelAdmin`` -subclass:: - - class AuthorAdmin(admin.ModelAdmin): - date_hierarchy = 'pub_date' - -.. attribute:: ModelAdmin.date_hierarchy - -Set ``date_hierarchy`` to the name of a ``DateField`` or ``DateTimeField`` in -your model, and the change list page will include a date-based drilldown -navigation by that field. - -Example:: - - date_hierarchy = 'pub_date' - -.. attribute:: ModelAdmin.form - -By default a ``ModelForm`` is dynamically created for your model. It is used -to create the form presented on both the add/change pages. You can easily -provide your own ``ModelForm`` to override any default form behavior on the -add/change pages. - -For an example see the section `Adding custom validation to the admin`_. - -.. attribute:: ModelAdmin.fieldsets - -Set ``fieldsets`` to control the layout of admin "add" and "change" pages. - -``fieldsets`` is a list of two-tuples, in which each two-tuple represents a -``<fieldset>`` on the admin form page. (A ``<fieldset>`` is a "section" of the -form.) - -The two-tuples are in the format ``(name, field_options)``, where ``name`` is a -string representing the title of the fieldset and ``field_options`` is a -dictionary of information about the fieldset, including a list of fields to be -displayed in it. - -A full example, taken from the ``django.contrib.flatpages.FlatPage`` model:: - - class FlatPageAdmin(admin.ModelAdmin): - fieldsets = ( - (None, { - 'fields': ('url', 'title', 'content', 'sites') - }), - ('Advanced options', { - 'classes': ('collapse',), - 'fields': ('enable_comments', 'registration_required', 'template_name') - }), - ) - -This results in an admin page that looks like: - - .. image:: _images/flatfiles_admin.png - -If ``fieldsets`` isn't given, Django will default to displaying each field -that isn't an ``AutoField`` and has ``editable=True``, in a single fieldset, -in the same order as the fields are defined in the model. - -The ``field_options`` dictionary can have the following keys: - - * ``fields`` - A tuple of field names to display in this fieldset. This key is - required. - - Example:: - - { - 'fields': ('first_name', 'last_name', 'address', 'city', 'state'), - } - - To display multiple fields on the same line, wrap those fields in - their own tuple. In this example, the ``first_name`` and ``last_name`` - fields will display on the same line:: - - { - 'fields': (('first_name', 'last_name'), 'address', 'city', 'state'), - } - - .. versionadded:: 1.2 - - ``fields`` can contain values defined in - :attr:`ModelAdmin.readonly_fields` to be displayed as read-only. - - * ``classes`` - A list containing extra CSS classes to apply to the fieldset. - - Example:: - - { - 'classes': ['wide', 'extrapretty'], - } - - Two useful classes defined by the default admin site stylesheet are - ``collapse`` and ``wide``. Fieldsets with the ``collapse`` style will - be initially collapsed in the admin and replaced with a small - "click to expand" link. Fieldsets with the ``wide`` style will be - given extra horizontal space. - - * ``description`` - A string of optional extra text to be displayed at the top of each - fieldset, under the heading of the fieldset. - - Note that this value is *not* HTML-escaped when it's displayed in - the admin interface. This lets you include HTML if you so desire. - Alternatively you can use plain text and - ``django.utils.html.escape()`` to escape any HTML special - characters. - -.. attribute:: ModelAdmin.fields - -Use this option as an alternative to ``fieldsets`` if the layout does not -matter and if you want to only show a subset of the available fields in the -form. For example, you could define a simpler version of the admin form for -the ``django.contrib.flatpages.FlatPage`` model as follows:: - - class FlatPageAdmin(admin.ModelAdmin): - fields = ('url', 'title', 'content') - -In the above example, only the fields 'url', 'title' and 'content' will be -displayed, sequentially, in the form. - -.. versionadded:: 1.2 - -``fields`` can contain values defined in :attr:`ModelAdmin.readonly_fields` -to be displayed as read-only. - -.. admonition:: Note - - This ``fields`` option should not be confused with the ``fields`` - dictionary key that is within the ``fieldsets`` option, as described in - the previous section. - -.. attribute:: ModelAdmin.exclude - -This attribute, if given, should be a list of field names to exclude from the -form. - -For example, let's consider the following model:: - - class Author(models.Model): - name = models.CharField(max_length=100) - title = models.CharField(max_length=3) - birth_date = models.DateField(blank=True, null=True) - -If you want a form for the ``Author`` model that includes only the ``name`` -and ``title`` fields, you would specify ``fields`` or ``exclude`` like this:: - - class AuthorAdmin(admin.ModelAdmin): - fields = ('name', 'title') - - class AuthorAdmin(admin.ModelAdmin): - exclude = ('birth_date',) - -Since the Author model only has three fields, ``name``, ``title``, and -``birth_date``, the forms resulting from the above declarations will contain -exactly the same fields. - -.. attribute:: ModelAdmin.filter_horizontal - -Use a nifty unobtrusive JavaScript "filter" interface instead of the -usability-challenged ``<select multiple>`` in the admin form. The value is a -list of fields that should be displayed as a horizontal filter interface. See -``filter_vertical`` to use a vertical interface. - -.. attribute:: ModelAdmin.filter_vertical - -Same as ``filter_horizontal``, but is a vertical display of the filter -interface. - -.. attribute:: ModelAdmin.list_display - -Set ``list_display`` to control which fields are displayed on the change list -page of the admin. - -Example:: - - list_display = ('first_name', 'last_name') - -If you don't set ``list_display``, the admin site will display a single column -that displays the ``__unicode__()`` representation of each object. - -You have four possible values that can be used in ``list_display``: - - * A field of the model. For example:: - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'last_name') - - * A callable that accepts one parameter for the model instance. For - example:: - - def upper_case_name(obj): - return ("%s %s" % (obj.first_name, obj.last_name)).upper() - upper_case_name.short_description = 'Name' - - class PersonAdmin(admin.ModelAdmin): - list_display = (upper_case_name,) - - * A string representing an attribute on the ``ModelAdmin``. This behaves - same as the callable. For example:: - - class PersonAdmin(admin.ModelAdmin): - list_display = ('upper_case_name',) - - def upper_case_name(self, obj): - return ("%s %s" % (obj.first_name, obj.last_name)).upper() - upper_case_name.short_description = 'Name' - - * A string representing an attribute on the model. This behaves almost - the same as the callable, but ``self`` in this context is the model - instance. Here's a full model example:: - - class Person(models.Model): - name = models.CharField(max_length=50) - birthday = models.DateField() - - def decade_born_in(self): - return self.birthday.strftime('%Y')[:3] + "0's" - decade_born_in.short_description = 'Birth decade' - - class PersonAdmin(admin.ModelAdmin): - list_display = ('name', 'decade_born_in') - -A few special cases to note about ``list_display``: - - * If the field is a ``ForeignKey``, Django will display the - ``__unicode__()`` of the related object. - - * ``ManyToManyField`` fields aren't supported, because that would entail - executing a separate SQL statement for each row in the table. If you - want to do this nonetheless, give your model a custom method, and add - that method's name to ``list_display``. (See below for more on custom - methods in ``list_display``.) - - * If the field is a ``BooleanField`` or ``NullBooleanField``, Django will - display a pretty "on" or "off" icon instead of ``True`` or ``False``. - - * If the string given is a method of the model, ``ModelAdmin`` or a - callable, Django will HTML-escape the output by default. If you'd rather - not escape the output of the method, give the method an ``allow_tags`` - attribute whose value is ``True``. - - Here's a full example model:: - - class Person(models.Model): - first_name = models.CharField(max_length=50) - last_name = models.CharField(max_length=50) - color_code = models.CharField(max_length=6) - - def colored_name(self): - return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name) - colored_name.allow_tags = True - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'last_name', 'colored_name') - - * If the string given is a method of the model, ``ModelAdmin`` or a - callable that returns True or False Django will display a pretty "on" or - "off" icon if you give the method a ``boolean`` attribute whose value is - ``True``. - - Here's a full example model:: - - class Person(models.Model): - first_name = models.CharField(max_length=50) - birthday = models.DateField() - - def born_in_fifties(self): - return self.birthday.strftime('%Y')[:3] == '195' - born_in_fifties.boolean = True - - class PersonAdmin(admin.ModelAdmin): - list_display = ('name', 'born_in_fifties') - - - * The ``__str__()`` and ``__unicode__()`` methods are just as valid in - ``list_display`` as any other model method, so it's perfectly OK to do - this:: - - list_display = ('__unicode__', 'some_other_field') - - * Usually, elements of ``list_display`` that aren't actual database fields - can't be used in sorting (because Django does all the sorting at the - database level). - - However, if an element of ``list_display`` represents a certain database - field, you can indicate this fact by setting the ``admin_order_field`` - attribute of the item. - - For example:: - - class Person(models.Model): - first_name = models.CharField(max_length=50) - color_code = models.CharField(max_length=6) - - def colored_first_name(self): - return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name) - colored_first_name.allow_tags = True - colored_first_name.admin_order_field = 'first_name' - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'colored_first_name') - - The above will tell Django to order by the ``first_name`` field when - trying to sort by ``colored_first_name`` in the admin. - -.. attribute:: ModelAdmin.list_display_links - -Set ``list_display_links`` to control which fields in ``list_display`` should -be linked to the "change" page for an object. - -By default, the change list page will link the first column -- the first field -specified in ``list_display`` -- to the change page for each item. But -``list_display_links`` lets you change which columns are linked. Set -``list_display_links`` to a list or tuple of field names (in the same format as -``list_display``) to link. - -``list_display_links`` can specify one or many field names. As long as the -field names appear in ``list_display``, Django doesn't care how many (or how -few) fields are linked. The only requirement is: If you want to use -``list_display_links``, you must define ``list_display``. - -In this example, the ``first_name`` and ``last_name`` fields will be linked on -the change list page:: - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'last_name', 'birthday') - list_display_links = ('first_name', 'last_name') - -.. _admin-list-editable: - -.. attribute:: ModelAdmin.list_editable - -.. versionadded:: 1.1 - -Set ``list_editable`` to a list of field names on the model which will allow -editing on the change list page. That is, fields listed in ``list_editable`` -will be displayed as form widgets on the change list page, allowing users to -edit and save multiple rows at once. - -.. note:: - - ``list_editable`` interacts with a couple of other options in particular - ways; you should note the following rules: - - * Any field in ``list_editable`` must also be in ``list_display``. You - can't edit a field that's not displayed! - - * The same field can't be listed in both ``list_editable`` and - ``list_display_links`` -- a field can't be both a form and a link. - - You'll get a validation error if either of these rules are broken. - -.. attribute:: ModelAdmin.list_filter - -Set ``list_filter`` to activate filters in the right sidebar of the change list -page of the admin. This should be a list of field names, and each specified -field should be either a ``BooleanField``, ``CharField``, ``DateField``, -``DateTimeField``, ``IntegerField`` or ``ForeignKey``. - -This example, taken from the ``django.contrib.auth.models.User`` model, shows -how both ``list_display`` and ``list_filter`` work:: - - class UserAdmin(admin.ModelAdmin): - list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff') - list_filter = ('is_staff', 'is_superuser') - -The above code results in an admin change list page that looks like this: - - .. image:: _images/users_changelist.png - -(This example also has ``search_fields`` defined. See below.) - -.. attribute:: ModelAdmin.list_per_page - -Set ``list_per_page`` to control how many items appear on each paginated admin -change list page. By default, this is set to ``100``. - -.. attribute:: ModelAdmin.list_select_related - -Set ``list_select_related`` to tell Django to use -:meth:`~django.db.models.QuerySet.select_related` in retrieving the list of -objects on the admin change list page. This can save you a bunch of database -queries. - -The value should be either ``True`` or ``False``. Default is ``False``. - -Note that Django will use :meth:`~django.db.models.QuerySet.select_related`, -regardless of this setting, if one of the ``list_display`` fields is a -``ForeignKey``. - -.. attribute:: ModelAdmin.inlines - -See ``InlineModelAdmin`` objects below. - -.. attribute:: ModelAdmin.ordering - -Set ``ordering`` to specify how objects on the admin change list page should be -ordered. This should be a list or tuple in the same format as a model's -``ordering`` parameter. - -If this isn't provided, the Django admin will use the model's default ordering. - -.. admonition:: Note - - Django will only honor the first element in the list/tuple; any others - will be ignored. - -.. attribute:: ModelAdmin.prepopulated_fields - -Set ``prepopulated_fields`` to a dictionary mapping field names to the fields -it should prepopulate from:: - - class ArticleAdmin(admin.ModelAdmin): - prepopulated_fields = {"slug": ("title",)} - -When set, the given fields will use a bit of JavaScript to populate from the -fields assigned. The main use for this functionality is to automatically -generate the value for ``SlugField`` fields from one or more other fields. The -generated value is produced by concatenating the values of the source fields, -and then by transforming that result into a valid slug (e.g. substituting -dashes for spaces). - -``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``, nor -``ManyToManyField`` fields. - -.. attribute:: ModelAdmin.radio_fields - -By default, Django's admin uses a select-box interface (<select>) for -fields that are ``ForeignKey`` or have ``choices`` set. If a field is present -in ``radio_fields``, Django will use a radio-button interface instead. -Assuming ``group`` is a ``ForeignKey`` on the ``Person`` model:: - - class PersonAdmin(admin.ModelAdmin): - radio_fields = {"group": admin.VERTICAL} - -You have the choice of using ``HORIZONTAL`` or ``VERTICAL`` from the -``django.contrib.admin`` module. - -Don't include a field in ``radio_fields`` unless it's a ``ForeignKey`` or has -``choices`` set. - -.. attribute:: ModelAdmin.raw_id_fields - -By default, Django's admin uses a select-box interface (<select>) for -fields that are ``ForeignKey``. Sometimes you don't want to incur the -overhead of having to select all the related instances to display in the -drop-down. - -``raw_id_fields`` is a list of fields you would like to change -into a ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``:: - - class ArticleAdmin(admin.ModelAdmin): - raw_id_fields = ("newspaper",) - -.. attribute:: ModelAdmin.readonly_fields - -.. versionadded:: 1.2 - -By default the admin shows all fields as editable. Any fields in this option -(which should be a ``list`` or ``tuple``) will display its data as-is and -non-editable. This option behaves nearly identical to :attr:`ModelAdmin.list_display`. -Usage is the same, however, when you specify :attr:`ModelAdmin.fields` or -:attr:`ModelAdmin.fieldsets` the read-only fields must be present to be shown -(they are ignored otherwise). - -If ``readonly_fields`` is used without defining explicit ordering through -:attr:`ModelAdmin.fields` or :attr:`ModelAdmin.fieldsets` they will be added -last after all editable fields. - -.. attribute:: ModelAdmin.save_as - -Set ``save_as`` to enable a "save as" feature on admin change forms. - -Normally, objects have three save options: "Save", "Save and continue editing" -and "Save and add another". If ``save_as`` is ``True``, "Save and add another" -will be replaced by a "Save as" button. - -"Save as" means the object will be saved as a new object (with a new ID), -rather than the old object. - -By default, ``save_as`` is set to ``False``. - -.. attribute:: ModelAdmin.save_on_top - -Set ``save_on_top`` to add save buttons across the top of your admin change -forms. - -Normally, the save buttons appear only at the bottom of the forms. If you set -``save_on_top``, the buttons will appear both on the top and the bottom. - -By default, ``save_on_top`` is set to ``False``. - -.. attribute:: ModelAdmin.search_fields - -Set ``search_fields`` to enable a search box on the admin change list page. -This should be set to a list of field names that will be searched whenever -somebody submits a search query in that text box. - -These fields should be some kind of text field, such as ``CharField`` or -``TextField``. You can also perform a related lookup on a ``ForeignKey`` or -``ManyToManyField`` with the lookup API "follow" notation:: - - search_fields = ['foreign_key__related_fieldname'] - -For example, if you have a blog entry with an author, the following definition -would enable search blog entries by the email address of the author:: - - search_fields = ['user__email'] - -When somebody does a search in the admin search box, Django splits the search -query into words and returns all objects that contain each of the words, case -insensitive, where each word must be in at least one of ``search_fields``. For -example, if ``search_fields`` is set to ``['first_name', 'last_name']`` and a -user searches for ``john lennon``, Django will do the equivalent of this SQL -``WHERE`` clause:: - - WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%') - AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%') - -For faster and/or more restrictive searches, prefix the field name -with an operator: - -``^`` - Matches the beginning of the field. For example, if ``search_fields`` is - set to ``['^first_name', '^last_name']`` and a user searches for - ``john lennon``, Django will do the equivalent of this SQL ``WHERE`` - clause:: - - WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%') - AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%') - - This query is more efficient than the normal ``'%john%'`` query, because - the database only needs to check the beginning of a column's data, rather - than seeking through the entire column's data. Plus, if the column has an - index on it, some databases may be able to use the index for this query, - even though it's a ``LIKE`` query. - -``=`` - Matches exactly, case-insensitive. For example, if - ``search_fields`` is set to ``['=first_name', '=last_name']`` and - a user searches for ``john lennon``, Django will do the equivalent - of this SQL ``WHERE`` clause:: - - WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john') - AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon') - - Note that the query input is split by spaces, so, following this example, - it's currently not possible to search for all records in which - ``first_name`` is exactly ``'john winston'`` (containing a space). - -``@`` - Performs a full-text match. This is like the default search method but uses - an index. Currently this is only available for MySQL. - -.. attribute:: ModelAdmin.formfield_overrides - -.. versionadded:: 1.1 - -This provides a quick-and-dirty way to override some of the -:class:`~django.forms.Field` options for use in the admin. -``formfield_overrides`` is a dictionary mapping a field class to a dict of -arguments to pass to the field at construction time. - -Since that's a bit abstract, let's look at a concrete example. The most common -use of ``formfield_overrides`` is to add a custom widget for a certain type of -field. So, imagine we've written a ``RichTextEditorWidget`` that we'd like to -use for large text fields instead of the default ``<textarea>``. Here's how we'd -do that:: - - from django.db import models - from django.contrib import admin - - # Import our custom widget and our model from where they're defined - from myapp.widgets import RichTextEditorWidget - from myapp.models import MyModel - - class MyModelAdmin(admin.ModelAdmin): - formfield_overrides = { - models.TextField: {'widget': RichTextEditorWidget}, - } - -Note that the key in the dictionary is the actual field class, *not* a string. -The value is another dictionary; these arguments will be passed to -:meth:`~django.forms.Field.__init__`. See :doc:`/ref/forms/api` for details. - -.. warning:: - - If you want to use a custom widget with a relation field (i.e. - :class:`~django.db.models.ForeignKey` or - :class:`~django.db.models.ManyToManyField`), make sure you haven't included - that field's name in ``raw_id_fields`` or ``radio_fields``. - - ``formfield_overrides`` won't let you change the widget on relation fields - that have ``raw_id_fields`` or ``radio_fields`` set. That's because - ``raw_id_fields`` and ``radio_fields`` imply custom widgets of their own. - -.. attribute:: ModelAdmin.actions - -.. versionadded:: 1.1 - -A list of actions to make available on the change list page. See -:doc:`/ref/contrib/admin/actions` for details. - -.. attribute:: ModelAdmin.actions_on_top -.. attribute:: ModelAdmin.actions_on_bottom - -.. versionadded:: 1.1 - -Controls where on the page the actions bar appears. By default, the admin -changelist displays actions at the top of the page (``actions_on_top = True; -actions_on_bottom = False``). - -.. attribute:: ModelAdmin.actions_selection_counter - -.. versionadded:: 1.2 - -Controls whether a selection counter is display next to the action dropdown. -By default, the admin changelist will display it -(``actions_selection_counter = True``). - -Custom template options -~~~~~~~~~~~~~~~~~~~~~~~ - -The `Overriding Admin Templates`_ section describes how to override or extend -the default admin templates. Use the following options to override the default -templates used by the :class:`ModelAdmin` views: - -.. attribute:: ModelAdmin.add_form_template - - .. versionadded:: 1.2 - - Path to a custom template, used by :meth:`add_view`. - -.. attribute:: ModelAdmin.change_form_template - - Path to a custom template, used by :meth:`change_view`. - -.. attribute:: ModelAdmin.change_list_template - - Path to a custom template, used by :meth:`changelist_view`. - -.. attribute:: ModelAdmin.delete_confirmation_template - - Path to a custom template, used by :meth:`delete_view` for displaying a - confirmation page when deleting one or more objects. - -.. attribute:: ModelAdmin.delete_selected_confirmation_template - - .. versionadded:: 1.2 - - Path to a custom template, used by the :meth:`delete_selected` - action method for displaying a confirmation page when deleting one - or more objects. See the :doc:`actions - documentation</ref/contrib/admin/actions>`. - -.. attribute:: ModelAdmin.object_history_template - - Path to a custom template, used by :meth:`history_view`. - - -.. _model-admin-methods: - -``ModelAdmin`` methods ----------------------- - -.. method:: ModelAdmin.save_model(self, request, obj, form, change) - -The ``save_model`` method is given the ``HttpRequest``, a model instance, -a ``ModelForm`` instance and a boolean value based on whether it is adding or -changing the object. Here you can do any pre- or post-save operations. - -For example to attach ``request.user`` to the object prior to saving:: - - class ArticleAdmin(admin.ModelAdmin): - def save_model(self, request, obj, form, change): - obj.user = request.user - obj.save() - -.. method:: ModelAdmin.save_formset(self, request, form, formset, change) - -The ``save_formset`` method is given the ``HttpRequest``, the parent -``ModelForm`` instance and a boolean value based on whether it is adding or -changing the parent object. - -For example to attach ``request.user`` to each changed formset -model instance:: - - class ArticleAdmin(admin.ModelAdmin): - def save_formset(self, request, form, formset, change): - instances = formset.save(commit=False) - for instance in instances: - instance.user = request.user - instance.save() - formset.save_m2m() - -.. method:: ModelAdmin.get_readonly_fields(self, request, obj=None) - -.. versionadded:: 1.2 - -The ``get_readonly_fields`` method is given the ``HttpRequest`` and the -``obj`` being edited (or ``None`` on an add form) and is expected to return a -``list`` or ``tuple`` of field names that will be displayed as read-only, as -described above in the :attr:`ModelAdmin.readonly_fields` section. - -.. method:: ModelAdmin.get_urls(self) - -.. versionadded:: 1.1 - -The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for -that ModelAdmin in the same way as a URLconf. Therefore you can extend them as -documented in :doc:`/topics/http/urls`:: - - class MyModelAdmin(admin.ModelAdmin): - def get_urls(self): - urls = super(MyModelAdmin, self).get_urls() - my_urls = patterns('', - (r'^my_view/$', self.my_view) - ) - return my_urls + urls - -.. note:: - - Notice that the custom patterns are included *before* the regular admin - URLs: the admin URL patterns are very permissive and will match nearly - anything, so you'll usually want to prepend your custom URLs to the built-in - ones. - -However, the ``self.my_view`` function registered above suffers from two -problems: - - * It will *not* perform any permission checks, so it will be accessible to - the general public. - * It will *not* provide any header details to prevent caching. This means if - the page retrieves data from the database, and caching middleware is - active, the page could show outdated information. - -Since this is usually not what you want, Django provides a convenience wrapper -to check permissions and mark the view as non-cacheable. This wrapper is -:meth:`AdminSite.admin_view` (i.e. ``self.admin_site.admin_view`` inside a -``ModelAdmin`` instance); use it like so:: - - class MyModelAdmin(admin.ModelAdmin): - def get_urls(self): - urls = super(MyModelAdmin, self).get_urls() - my_urls = patterns('', - (r'^my_view/$', self.admin_site.admin_view(self.my_view)) - ) - return my_urls + urls - -Notice the wrapped view in the fifth line above:: - - (r'^my_view/$', self.admin_site.admin_view(self.my_view)) - -This wrapping will protect ``self.my_view`` from unauthorized access and will -apply the ``django.views.decorators.cache.never_cache`` decorator to make sure -it is not cached if the cache middleware is active. - -If the page is cacheable, but you still want the permission check to be performed, -you can pass a ``cacheable=True`` argument to :meth:`AdminSite.admin_view`:: - - (r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True)) - -.. method:: ModelAdmin.formfield_for_foreignkey(self, db_field, request, **kwargs) - -.. versionadded:: 1.1 - -The ``formfield_for_foreignkey`` method on a ``ModelAdmin`` allows you to -override the default formfield for a foreign key field. For example, to -return a subset of objects for this foreign key field based on the user:: - - class MyModelAdmin(admin.ModelAdmin): - def formfield_for_foreignkey(self, db_field, request, **kwargs): - if db_field.name == "car": - kwargs["queryset"] = Car.objects.filter(owner=request.user) - return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) - -This uses the ``HttpRequest`` instance to filter the ``Car`` foreign key field -to only display the cars owned by the ``User`` instance. - -.. method:: ModelAdmin.formfield_for_manytomany(self, db_field, request, **kwargs) - -.. versionadded:: 1.1 - -Like the ``formfield_for_foreignkey`` method, the ``formfield_for_manytomany`` -method can be overridden to change the default formfield for a many to many -field. For example, if an owner can own multiple cars and cars can belong -to multiple owners -- a many to many relationship -- you could filter the -``Car`` foreign key field to only display the cars owned by the ``User``:: - - class MyModelAdmin(admin.ModelAdmin): - def formfield_for_manytomany(self, db_field, request, **kwargs): - if db_field.name == "cars": - kwargs["queryset"] = Car.objects.filter(owner=request.user) - return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs) - -.. method:: ModelAdmin.queryset(self, request) - -The ``queryset`` method on a ``ModelAdmin`` returns a -:class:`~django.db.models.QuerySet` of all model instances that can be -edited by the admin site. One use case for overriding this method is -to show objects owned by the logged-in user:: - - class MyModelAdmin(admin.ModelAdmin): - def queryset(self, request): - qs = super(MyModelAdmin, self).queryset(request) - if request.user.is_superuser: - return qs - return qs.filter(author=request.user) - -.. method:: ModelAdmin.message_user(request, message) - - Sends a message to the user. The default implementation creates a message - using the :mod:`django.contrib.messages` backend. See the - :ref:`custom ModelAdmin example <custom-admin-action>`. - -Other methods -~~~~~~~~~~~~~ - -.. method:: ModelAdmin.add_view(self, request, form_url='', extra_context=None) - -Django view for the model instance addition page. See note below. - -.. method:: ModelAdmin.change_view(self, request, object_id, extra_context=None) - -Django view for the model instance edition page. See note below. - -.. method:: ModelAdmin.changelist_view(self, request, extra_context=None) - -Django view for the model instances change list/actions page. See note below. - -.. method:: ModelAdmin.delete_view(self, request, object_id, extra_context=None) - -Django view for the model instance(s) deletion confirmation page. See note below. - -.. method:: ModelAdmin.history_view(self, request, object_id, extra_context=None) - -Django view for the page that shows the modification history for a given model -instance. - -Unlike the hook-type ``ModelAdmin`` methods detailed in the previous section, -these five methods are in reality designed to be invoked as Django views from -the admin application URL dispatching handler to render the pages that deal -with model instances CRUD operations. As a result, completely overriding these -methods will significantly change the behavior of the admin application. - -One common reason for overriding these methods is to augment the context data -that is provided to the template that renders the view. In the following -example, the change view is overridden so that the rendered template is -provided some extra mapping data that would not otherwise be available:: - - class MyModelAdmin(admin.ModelAdmin): - - # A template for a very customized change view: - change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html' - - def get_osm_info(self): - # ... - - def change_view(self, request, object_id, extra_context=None): - my_context = { - 'osm_data': self.get_osm_info(), - } - return super(MyModelAdmin, self).change_view(request, object_id, - extra_context=my_context) - -``ModelAdmin`` media definitions --------------------------------- - -There are times where you would like add a bit of CSS and/or JavaScript to -the add/change views. This can be accomplished by using a Media inner class -on your ``ModelAdmin``:: - - class ArticleAdmin(admin.ModelAdmin): - class Media: - css = { - "all": ("my_styles.css",) - } - js = ("my_code.js",) - -Keep in mind that this will be prepended with ``MEDIA_URL``. The same rules -apply as :doc:`regular media definitions on forms </topics/forms/media>`. - -Django admin Javascript makes use of the `jQuery`_ library. To avoid -conflict with user scripts, Django's jQuery is namespaced as -``django.jQuery``. If you want to use jQuery in your own admin -JavaScript without including a second copy, you can use the -``django.jQuery`` object on changelist and add/edit views. - -.. _jQuery: http://jquery.com - -Adding custom validation to the admin -------------------------------------- - -Adding custom validation of data in the admin is quite easy. The automatic admin -interface reuses :mod:`django.forms`, and the ``ModelAdmin`` class gives you -the ability define your own form:: - - class ArticleAdmin(admin.ModelAdmin): - form = MyArticleAdminForm - -``MyArticleAdminForm`` can be defined anywhere as long as you import where -needed. Now within your form you can add your own custom validation for -any field:: - - class MyArticleAdminForm(forms.ModelForm): - class Meta: - model = Article - - def clean_name(self): - # do something that validates your data - return self.cleaned_data["name"] - -It is important you use a ``ModelForm`` here otherwise things can break. See the -:doc:`forms </ref/forms/index>` documentation on :doc:`custom validation -</ref/forms/validation>` and, more specifically, the -:ref:`model form validation notes <overriding-modelform-clean-method>` for more -information. - -.. _admin-inlines: - -``InlineModelAdmin`` objects -============================ - -.. class:: InlineModelAdmin - -The admin interface has the ability to edit models on the same page as a -parent model. These are called inlines. Suppose you have these two models:: - - class Author(models.Model): - name = models.CharField(max_length=100) - - class Book(models.Model): - author = models.ForeignKey(Author) - title = models.CharField(max_length=100) - -You can edit the books authored by an author on the author page. You add -inlines to a model by specifying them in a ``ModelAdmin.inlines``:: - - class BookInline(admin.TabularInline): - model = Book - - class AuthorAdmin(admin.ModelAdmin): - inlines = [ - BookInline, - ] - -Django provides two subclasses of ``InlineModelAdmin`` and they are: - - * ``TabularInline`` - * ``StackedInline`` - -The difference between these two is merely the template used to render them. - -``InlineModelAdmin`` options ------------------------------ - -The ``InlineModelAdmin`` class is a subclass of ``ModelAdmin`` so it inherits -all the same functionality as well as some of its own: - -.. attribute:: InlineModelAdmin.model - - The model in which the inline is using. This is required. - -.. attribute:: InlineModelAdmin.fk_name - - The name of the foreign key on the model. In most cases this will be dealt - with automatically, but ``fk_name`` must be specified explicitly if there - are more than one foreign key to the same parent model. - -.. attribute:: InlineModelAdmin.formset - - This defaults to ``BaseInlineFormSet``. Using your own formset can give you - many possibilities of customization. Inlines are built around - :ref:`model formsets <model-formsets>`. - -.. attribute:: InlineModelAdmin.form - - The value for ``form`` defaults to ``ModelForm``. This is what is passed - through to ``inlineformset_factory`` when creating the formset for this - inline. - -.. _ref-contrib-admin-inline-extra: - -.. attribute:: InlineModelAdmin.extra - - - This controls the number of extra forms the formset will display in addition - to the initial forms. See the - :doc:`formsets documentation </topics/forms/formsets>` for more information. - - .. versionadded:: 1.2 - - For users with JavaScript-enabled browsers, an "Add another" link is - provided to enable any number of additional inlines to be added in addition - to those provided as a result of the ``extra`` argument. - - The dynamic link will not appear if the number of currently displayed forms - exceeds ``max_num``, or if the user does not have JavaScript enabled. - -.. _ref-contrib-admin-inline-max-num: - -.. attribute:: InlineModelAdmin.max_num - - This controls the maximum number of forms to show in the inline. This - doesn't directly correlate to the number of objects, but can if the value - is small enough. See :ref:`model-formsets-max-num` for more information. - -.. attribute:: InlineModelAdmin.raw_id_fields - - By default, Django's admin uses a select-box interface (<select>) for - fields that are ``ForeignKey``. Sometimes you don't want to incur the - overhead of having to select all the related instances to display in the - drop-down. - - ``raw_id_fields`` is a list of fields you would like to change into a - ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``:: - - class BookInline(admin.TabularInline): - model = Book - raw_id_fields = ("pages",) - - -.. attribute:: InlineModelAdmin.template - - The template used to render the inline on the page. - -.. attribute:: InlineModelAdmin.verbose_name - - An override to the ``verbose_name`` found in the model's inner ``Meta`` - class. - -.. attribute:: InlineModelAdmin.verbose_name_plural - - An override to the ``verbose_name_plural`` found in the model's inner - ``Meta`` class. - -.. attribute:: InlineModelAdmin.can_delete - - Specifies whether or not inline objects can be deleted in the inline. - Defaults to ``True``. - - -Working with a model with two or more foreign keys to the same parent model ---------------------------------------------------------------------------- - -It is sometimes possible to have more than one foreign key to the same model. -Take this model for instance:: - - class Friendship(models.Model): - to_person = models.ForeignKey(Person, related_name="friends") - from_person = models.ForeignKey(Person, related_name="from_friends") - -If you wanted to display an inline on the ``Person`` admin add/change pages -you need to explicitly define the foreign key since it is unable to do so -automatically:: - - class FriendshipInline(admin.TabularInline): - model = Friendship - fk_name = "to_person" - - class PersonAdmin(admin.ModelAdmin): - inlines = [ - FriendshipInline, - ] - -Working with Many-to-Many Models --------------------------------- - -.. versionadded:: 1.2 - -By default, admin widgets for many-to-many relations will be displayed -on whichever model contains the actual reference to the ``ManyToManyField``. -Depending on your ``ModelAdmin`` definition, each many-to-many field in your -model will be represented by a standard HTML ``<select multiple>``, a -horizontal or vertical filter, or a ``raw_id_admin`` widget. However, it is -also possible to to replace these widgets with inlines. - -Suppose we have the following models:: - - class Person(models.Model): - name = models.CharField(max_length=128) - - class Group(models.Model): - name = models.CharField(max_length=128) - members = models.ManyToManyField(Person, related_name='groups') - -If you want to display many-to-many relations using an inline, you can do -so by defining an ``InlineModelAdmin`` object for the relationship:: - - class MembershipInline(admin.TabularInline): - model = Group.members.through - - class PersonAdmin(admin.ModelAdmin): - inlines = [ - MembershipInline, - ] - - class GroupAdmin(admin.ModelAdmin): - inlines = [ - MembershipInline, - ] - exclude = ('members',) - -There are two features worth noting in this example. - -Firstly - the ``MembershipInline`` class references ``Group.members.through``. -The ``through`` attribute is a reference to the model that manages the -many-to-many relation. This model is automatically created by Django when you -define a many-to-many field. - -Secondly, the ``GroupAdmin`` must manually exclude the ``members`` field. -Django displays an admin widget for a many-to-many field on the model that -defines the relation (in this case, ``Group``). If you want to use an inline -model to represent the many-to-many relationship, you must tell Django's admin -to *not* display this widget - otherwise you will end up with two widgets on -your admin page for managing the relation. - -In all other respects, the ``InlineModelAdmin`` is exactly the same as any -other. You can customize the appearance using any of the normal -``ModelAdmin`` properties. - -Working with Many-to-Many Intermediary Models ----------------------------------------------- - -When you specify an intermediary model using the ``through`` argument to a -``ManyToManyField``, the admin will not display a widget by default. This is -because each instance of that intermediary model requires more information -than could be displayed in a single widget, and the layout required for -multiple widgets will vary depending on the intermediate model. - -However, we still want to be able to edit that information inline. Fortunately, -this is easy to do with inline admin models. Suppose we have the following -models:: - - class Person(models.Model): - name = models.CharField(max_length=128) - - class Group(models.Model): - name = models.CharField(max_length=128) - members = models.ManyToManyField(Person, through='Membership') - - class Membership(models.Model): - person = models.ForeignKey(Person) - group = models.ForeignKey(Group) - date_joined = models.DateField() - invite_reason = models.CharField(max_length=64) - -The first step in displaying this intermediate model in the admin is to -define an inline class for the ``Membership`` model:: - - class MembershipInline(admin.TabularInline): - model = Membership - extra = 1 - -This simple example uses the default ``InlineModelAdmin`` values for the -``Membership`` model, and limits the extra add forms to one. This could be -customized using any of the options available to ``InlineModelAdmin`` classes. - -Now create admin views for the ``Person`` and ``Group`` models:: - - class PersonAdmin(admin.ModelAdmin): - inlines = (MembershipInline,) - - class GroupAdmin(admin.ModelAdmin): - inlines = (MembershipInline,) - -Finally, register your ``Person`` and ``Group`` models with the admin site:: - - admin.site.register(Person, PersonAdmin) - admin.site.register(Group, GroupAdmin) - -Now your admin site is set up to edit ``Membership`` objects inline from -either the ``Person`` or the ``Group`` detail pages. - -Using generic relations as an inline ------------------------------------- - -It is possible to use an inline with generically related objects. Let's say -you have the following models:: - - class Image(models.Model): - image = models.ImageField(upload_to="images") - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey("content_type", "object_id") - - class Product(models.Model): - name = models.CharField(max_length=100) - -If you want to allow editing and creating ``Image`` instance on the ``Product`` -add/change views you can simply use ``GenericInlineModelAdmin`` provided by -``django.contrib.contenttypes.generic``. In your ``admin.py`` for this -example app:: - - from django.contrib import admin - from django.contrib.contenttypes import generic - - from myproject.myapp.models import Image, Product - - class ImageInline(generic.GenericTabularInline): - model = Image - - class ProductAdmin(admin.ModelAdmin): - inlines = [ - ImageInline, - ] - - admin.site.register(Product, ProductAdmin) - -``django.contrib.contenttypes.generic`` provides both a ``GenericTabularInline`` -and ``GenericStackedInline`` and behave just like any other inline. See the -:doc:`contenttypes documentation </ref/contrib/contenttypes>` for more specific -information. - -Overriding Admin Templates -========================== - -It is relatively easy to override many of the templates which the admin module -uses to generate the various pages of an admin site. You can even override a few -of these templates for a specific app, or a specific model. - -Set up your projects admin template directories ------------------------------------------------ - -The admin template files are located in the ``contrib/admin/templates/admin`` -directory. - -In order to override one or more of them, first create an ``admin`` directory in -your project's ``templates`` directory. This can be any of the directories you -specified in ``TEMPLATE_DIRS``. - -Within this ``admin`` directory, create sub-directories named after your app. -Within these app subdirectories create sub-directories named after your models. -Note, that the admin app will lowercase the model name when looking for the -directory, so make sure you name the directory in all lowercase if you are going -to run your app on a case-sensitive filesystem. - -To override an admin template for a specific app, copy and edit the template -from the ``django/contrib/admin/templates/admin`` directory, and save it to one -of the directories you just created. - -For example, if we wanted to add a tool to the change list view for all the -models in an app named ``my_app``, we would copy -``contrib/admin/templates/admin/change_list.html`` to the -``templates/admin/my_app/`` directory of our project, and make any necessary -changes. - -If we wanted to add a tool to the change list view for only a specific model -named 'Page', we would copy that same file to the -``templates/admin/my_app/page`` directory of our project. - -Overriding vs. replacing an admin template ------------------------------------------- - -Because of the modular design of the admin templates, it is usually neither -necessary nor advisable to replace an entire template. It is almost always -better to override only the section of the template which you need to change. - -To continue the example above, we want to add a new link next to the ``History`` -tool for the ``Page`` model. After looking at ``change_form.html`` we determine -that we only need to override the ``object-tools`` block. Therefore here is our -new ``change_form.html`` : - -.. code-block:: html+django - - {% extends "admin/change_form.html" %} - {% load i18n %} - {% block object-tools %} - {% if change %}{% if not is_popup %} - <ul class="object-tools"> - <li><a href="history/" class="historylink">{% trans "History" %}</a></li> - <li><a href="mylink/" class="historylink">My Link</a></li> - {% if has_absolute_url %} - <li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink"> - {% trans "View on site" %}</a> - </li> - {% endif%} - </ul> - {% endif %}{% endif %} - {% endblock %} - -And that's it! If we placed this file in the ``templates/admin/my_app`` -directory, our link would appear on every model's change form. - -Templates which may be overridden per app or model --------------------------------------------------- - -Not every template in ``contrib/admin/templates/admin`` may be overridden per -app or per model. The following can: - - * ``app_index.html`` - * ``change_form.html`` - * ``change_list.html`` - * ``delete_confirmation.html`` - * ``object_history.html`` - -For those templates that cannot be overridden in this way, you may still -override them for your entire project. Just place the new version in your -``templates/admin`` directory. This is particularly useful to create custom 404 -and 500 pages. - -.. note:: - - Some of the admin templates, such as ``change_list_request.html`` are used - to render custom inclusion tags. These may be overridden, but in such cases - you are probably better off creating your own version of the tag in question - and giving it a different name. That way you can use it selectively. - -Root and login templates ------------------------- - -If you wish to change the index, login or logout templates, you are better off -creating your own ``AdminSite`` instance (see below), and changing the -:attr:`AdminSite.index_template` , :attr:`AdminSite.login_template` or -:attr:`AdminSite.logout_template` properties. - -``AdminSite`` objects -===================== - -.. class:: AdminSite(name=None) - -A Django administrative site is represented by an instance of -``django.contrib.admin.sites.AdminSite``; by default, an instance of -this class is created as ``django.contrib.admin.site`` and you can -register your models and ``ModelAdmin`` instances with it. - -If you'd like to set up your own administrative site with custom -behavior, however, you're free to subclass ``AdminSite`` and override -or add anything you like. Then, simply create an instance of your -``AdminSite`` subclass (the same way you'd instantiate any other -Python class), and register your models and ``ModelAdmin`` subclasses -with it instead of using the default. - -.. versionadded:: 1.1 - -When constructing an instance of an ``AdminSite``, you are able to provide -a unique instance name using the ``name`` argument to the constructor. This -instance name is used to identify the instance, especially when -:ref:`reversing admin URLs <admin-reverse-urls>`. If no instance name is -provided, a default instance name of ``admin`` will be used. - -``AdminSite`` attributes ------------------------- - -Templates can override or extend base admin templates as described in -`Overriding Admin Templates`_. - -.. attribute:: AdminSite.index_template - -Path to a custom template that will be used by the admin site main index view. - -.. attribute:: AdminSite.login_template - -Path to a custom template that will be used by the admin site login view. - -.. attribute:: AdminSite.logout_template - -.. versionadded:: 1.2 - -Path to a custom template that will be used by the admin site logout view. - -.. attribute:: AdminSite.password_change_template - -.. versionadded:: 1.2 - -Path to a custom template that will be used by the admin site password change -view. - -.. attribute:: AdminSite.password_change_done_template - -.. versionadded:: 1.2 - -Path to a custom template that will be used by the admin site password change -done view. - -Hooking ``AdminSite`` instances into your URLconf -------------------------------------------------- - -The last step in setting up the Django admin is to hook your ``AdminSite`` -instance into your URLconf. Do this by pointing a given URL at the -``AdminSite.urls`` method. - -In this example, we register the default ``AdminSite`` instance -``django.contrib.admin.site`` at the URL ``/admin/`` :: - - # urls.py - from django.conf.urls.defaults import * - from django.contrib import admin - - admin.autodiscover() - - urlpatterns = patterns('', - (r'^admin/', include(admin.site.urls)), - ) - -Above we used ``admin.autodiscover()`` to automatically load the -``INSTALLED_APPS`` admin.py modules. - -In this example, we register the ``AdminSite`` instance -``myproject.admin.admin_site`` at the URL ``/myadmin/`` :: - - # urls.py - from django.conf.urls.defaults import * - from myproject.admin import admin_site - - urlpatterns = patterns('', - (r'^myadmin/', include(admin_site.urls)), - ) - -There is really no need to use autodiscover when using your own ``AdminSite`` -instance since you will likely be importing all the per-app admin.py modules -in your ``myproject.admin`` module. - -Multiple admin sites in the same URLconf ----------------------------------------- - -It's easy to create multiple instances of the admin site on the same -Django-powered Web site. Just create multiple instances of ``AdminSite`` and -root each one at a different URL. - -.. versionchanged:: 1.1 - The method for hooking ``AdminSite`` instances into urls has changed in - Django 1.1. - -In this example, the URLs ``/basic-admin/`` and ``/advanced-admin/`` feature -separate versions of the admin site -- using the ``AdminSite`` instances -``myproject.admin.basic_site`` and ``myproject.admin.advanced_site``, -respectively:: - - # urls.py - from django.conf.urls.defaults import * - from myproject.admin import basic_site, advanced_site - - urlpatterns = patterns('', - (r'^basic-admin/', include(basic_site.urls)), - (r'^advanced-admin/', include(advanced_site.urls)), - ) - -``AdminSite`` instances take a single argument to their constructor, their -name, which can be anything you like. This argument becomes the prefix to the -URL names for the purposes of :ref:`reversing them<admin-reverse-urls>`. This -is only necessary if you are using more than one ``AdminSite``. - -Adding views to admin sites ---------------------------- - -.. versionadded:: 1.1 - -Just like :class:`ModelAdmin`, :class:`AdminSite` provides a -:meth:`~django.contrib.admin.ModelAdmin.get_urls()` method -that can be overridden to define additional views for the site. To add -a new view to your admin site, extend the base -:meth:`~django.contrib.admin.ModelAdmin.get_urls()` method to include -a pattern for your new view. - -.. note:: - Any view you render that uses the admin templates, or extends the base - admin template, should provide the ``current_app`` argument to - ``RequestContext`` or ``Context`` when rendering the template. It should - be set to either ``self.name`` if your view is on an ``AdminSite`` or - ``self.admin_site.name`` if your view is on a ``ModelAdmin``. - -.. _admin-reverse-urls: - -Reversing Admin URLs -==================== - -.. versionadded:: 1.1 - -When an :class:`AdminSite` is deployed, the views provided by that site are -accessible using Django's :ref:`URL reversing system <naming-url-patterns>`. - -The :class:`AdminSite` provides the following named URL patterns: - - ====================== ======================== ============= - Page URL name Parameters - ====================== ======================== ============= - Index ``index`` - Logout ``logout`` - Password change ``password_change`` - Password change done ``password_change_done`` - i18n javascript ``jsi18n`` - Application index page ``app_list`` ``app_label`` - ====================== ======================== ============= - -Each :class:`ModelAdmin` instance provides an additional set of named URLs: - - ====================== =============================================== ============= - Page URL name Parameters - ====================== =============================================== ============= - Changelist ``{{ app_label }}_{{ model_name }}_changelist`` - Add ``{{ app_label }}_{{ model_name }}_add`` - History ``{{ app_label }}_{{ model_name }}_history`` ``object_id`` - Delete ``{{ app_label }}_{{ model_name }}_delete`` ``object_id`` - Change ``{{ app_label }}_{{ model_name }}_change`` ``object_id`` - ====================== =============================================== ============= - -These named URLs are registered with the application namespace ``admin``, and -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:: - - >>> from django.core import urlresolvers - >>> c = Choice.objects.get(...) - >>> change_url = urlresolvers.reverse('admin:polls_choice_change', args=(c.id,)) - -This will find the first registered instance of the admin application (whatever the instance -name), and resolve to the view for changing ``poll.Choice`` instances in that instance. - -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:: - - >>> change_url = urlresolvers.reverse('custom:polls_choice_change', args=(c.id,)) - -For more details, see the documentation on :ref:`reversing namespaced URLs -<topics-http-reversing-url-namespaces>`. diff --git a/parts/django/docs/ref/contrib/auth.txt b/parts/django/docs/ref/contrib/auth.txt deleted file mode 100644 index 619b38e..0000000 --- a/parts/django/docs/ref/contrib/auth.txt +++ /dev/null @@ -1,4 +0,0 @@ -``django.contrib.auth`` -======================= - -See :doc:`/topics/auth`. diff --git a/parts/django/docs/ref/contrib/comments/custom.txt b/parts/django/docs/ref/contrib/comments/custom.txt deleted file mode 100644 index 5411d9c..0000000 --- a/parts/django/docs/ref/contrib/comments/custom.txt +++ /dev/null @@ -1,202 +0,0 @@ -================================== -Customizing the comments framework -================================== - -.. currentmodule:: django.contrib.comments - -If the built-in comment framework doesn't quite fit your needs, you can extend -the comment app's behavior to add custom data and logic. The comments framework -lets you extend the built-in comment model, the built-in comment form, and the -various comment views. - -The :setting:`COMMENTS_APP` setting is where this customization begins. Set -:setting:`COMMENTS_APP` to the name of the app you'd like to use to provide -custom behavior. You'll use the same syntax as you'd use for -:setting:`INSTALLED_APPS`, and the app given must also be in the -:setting:`INSTALLED_APPS` list. - -For example, if you wanted to use an app named ``my_comment_app``, your -settings file would contain:: - - INSTALLED_APPS = [ - ... - 'my_comment_app', - ... - ] - - COMMENTS_APP = 'my_comment_app' - -The app named in :setting:`COMMENTS_APP` provides its custom behavior by -defining some module-level functions in the app's ``__init__.py``. The -:ref:`complete list of these functions <custom-comment-app-api>` can be found -below, but first let's look at a quick example. - -An example custom comments app -============================== - -One of the most common types of customization is modifying the set of fields -provided on the built-in comment model. For example, some sites that allow -comments want the commentator to provide a title for their comment; the built-in -comment model has no field for that title. - -To make this kind of customization, we'll need to do three things: - - #. Create a custom comment :class:`~django.db.models.Model` that adds on the - "title" field. - - #. Create a custom comment :class:`~django.forms.Form` that also adds this - "title" field. - - #. Inform Django of these objects by defining a few functions in a - custom :setting:`COMMENTS_APP`. - -So, carrying on the example above, we're dealing with a typical app structure in -the ``my_custom_app`` directory:: - - my_custom_app/ - __init__.py - models.py - forms.py - -In the ``models.py`` we'll define a ``CommentWithTitle`` model:: - - from django.db import models - from django.contrib.comments.models import Comment - - class CommentWithTitle(Comment): - title = models.CharField(max_length=300) - -Most custom comment models will subclass the :class:`Comment` model. However, -if you want to substantially remove or change the fields available in the -:class:`Comment` model, but don't want to rewrite the templates, you could -try subclassing from :class:`BaseCommentAbstractModel`. - -Next, we'll define a custom comment form in ``forms.py``. This is a little more -tricky: we have to both create a form and override -:meth:`CommentForm.get_comment_model` and -:meth:`CommentForm.get_comment_create_data` to return deal with our custom title -field:: - - from django import forms - from django.contrib.comments.forms import CommentForm - from my_comment_app.models import CommentWithTitle - - class CommentFormWithTitle(CommentForm): - title = forms.CharField(max_length=300) - - def get_comment_model(self): - # Use our custom comment model instead of the built-in one. - return CommentWithTitle - - def get_comment_create_data(self): - # Use the data of the superclass, and add in the title field - data = super(CommentFormWithTitle, self).get_comment_create_data() - data['title'] = self.cleaned_data['title'] - return data - -Django provides a couple of "helper" classes to make writing certain types of -custom comment forms easier; see :mod:`django.contrib.comments.forms` for -more. - -Finally, we'll define a couple of methods in ``my_custom_app/__init__.py`` to -point Django at these classes we've created:: - - from my_comments_app.models import CommentWithTitle - from my_comments_app.forms import CommentFormWithTitle - - def get_model(): - return CommentWithTitle - - def get_form(): - return CommentFormWithTitle - - -.. warning:: - - Be careful not to create cyclic imports in your custom comments app. - If you feel your comment configuration isn't being used as defined -- - for example, if your comment moderation policy isn't being applied -- - you may have a cyclic import problem. - - If you are having unexplained problems with comments behavior, check - if your custom comments application imports (even indirectly) - any module that itself imports Django's comments module. - -The above process should take care of most common situations. For more -advanced usage, there are additional methods you can define. Those are -explained in the next section. - -.. _custom-comment-app-api: - -Custom comment app API -====================== - -The :mod:`django.contrib.comments` app defines the following methods; any -custom comment app must define at least one of them. All are optional, -however. - -.. function:: get_model() - - Return the :class:`~django.db.models.Model` class to use for comments. This - model should inherit from - :class:`django.contrib.comments.models.BaseCommentAbstractModel`, which - defines necessary core fields. - - The default implementation returns - :class:`django.contrib.comments.models.Comment`. - -.. function:: get_form() - - Return the :class:`~django.forms.Form` class you want to use for - creating, validating, and saving your comment model. Your custom - comment form should accept an additional first argument, - ``target_object``, which is the object the comment will be - attached to. - - The default implementation returns - :class:`django.contrib.comments.forms.CommentForm`. - - .. note:: - - The default comment form also includes a number of unobtrusive - spam-prevention features (see - :ref:`notes-on-the-comment-form`). If replacing it with your - own form, you may want to look at the source code for the - built-in form and consider incorporating similar features. - -.. function:: get_form_target() - - Return the URL for POSTing comments. This will be the ``<form action>`` - attribute when rendering your comment form. - - The default implementation returns a reverse-resolved URL pointing - to the :func:`post_comment` view. - - .. note:: - - If you provide a custom comment model and/or form, but you - want to use the default :func:`post_comment` view, you will - need to be aware that it requires the model and form to have - certain additional attributes and methods: see the - :func:`post_comment` view documentation for details. - -.. function:: get_flag_url() - - Return the URL for the "flag this comment" view. - - The default implementation returns a reverse-resolved URL pointing - to the :func:`django.contrib.comments.views.moderation.flag` view. - -.. function:: get_delete_url() - - Return the URL for the "delete this comment" view. - - The default implementation returns a reverse-resolved URL pointing - to the :func:`django.contrib.comments.views.moderation.delete` view. - -.. function:: get_approve_url() - - Return the URL for the "approve this comment from moderation" view. - - The default implementation returns a reverse-resolved URL pointing - to the :func:`django.contrib.comments.views.moderation.approve` view. diff --git a/parts/django/docs/ref/contrib/comments/example.txt b/parts/django/docs/ref/contrib/comments/example.txt deleted file mode 100644 index 424bdb1..0000000 --- a/parts/django/docs/ref/contrib/comments/example.txt +++ /dev/null @@ -1,208 +0,0 @@ -.. highlightlang:: html+django - -=========================================== -Example of using the in-built comments app -=========================================== - -Follow the first three steps of the quick start guide in the -:doc:`documentation </ref/contrib/comments/index>`. - -Now suppose, you have an app (``blog``) with a model (``Post``) -to which you want to attach comments. Let us also suppose that -you have a template called ``blog_detail.html`` where you want -to display the comments list and comment form. - -Template -======== - -First, we should load the ``comment`` template tags in the -``blog_detail.html`` so that we can use it's functionality. So -just like all other custom template tag libraries:: - - {% load comments %} - -Next, let us add the number of comments attached to the particular -model instance of ``Post``. For this we assume that a context -variable ``object_pk`` is present which gives the ``id`` of the -instance of ``Post``. - -The usage of the :ttag:`get_comment_count` tag is like below:: - - {% get_comment_count for blog.post object_pk as comment_count %} - <p>{{ comment_count }} comments have been posted.</p> - -If you have the instance (say ``entry``) of the model (``Post``) -available in the context, then you can refer to it directly:: - - {% get_comment_count for entry as comment_count %} - <p>{{ comment_count }} comments have been posted.</p> - -.. versionadded:: 1.2 - -Next, we can use the :ttag:`render_comment_list` tag, to render all comments -to the given instance (``entry``) by using the ``comments/list.html`` template. - - {% render_comment_list for entry %} - -Django will will look for the ``list.html`` under the following directories -(for our example):: - - comments/blog/post/list.html - comments/blog/list.html - comments/list.html - -To get a list of comments, we make use of the :ttag:`get_comment_list` tag. -This tag's usage is very similar to the :ttag:`get_comment_count` tag. We -need to remember that the :ttag:`get_comment_list` returns a list of comments -and hence we will have to iterate through them to display them:: - - {% get_comment_list for blog.post object_pk as comment_list %} - {% for comment in comment_list %} - <p>Posted by: {{ comment.user_name }} on {{ comment.submit_date }}</p> - ... - <p>Comment: {{ comment.comment }}</p> - ... - {% endfor %} - -Finally, we display the comment form, enabling users to enter their -comments. There are two ways of doing so. The first is when you want to -display the comments template available under your ``comments/form.html``. -The other method gives you a chance to customize the form. - -The first method makes use of the :ttag:`render_comment_form` tag. It's usage -too is similar to the other three tags we have discussed above:: - - {% render_comment_form for entry %} - -It looks for the ``form.html`` under the following directories -(for our example):: - - comments/blog/post/form.html - comments/blog/form.html - comments/form.html - -Since we customize the form in the second method, we make use of another -tag called :ttag:`comment_form_target`. This tag on rendering gives the URL -where the comment form is posted. Without any :doc:`customization -</ref/contrib/comments/custom>`, :ttag:`comment_form_target` evaluates to -``/comments/post/``. We use this tag in the form's ``action`` attribute. - -The :ttag:`get_comment_form` tag renders a ``form`` for a model instance by -creating a context variable. One can iterate over the ``form`` object to -get individual fields. This gives you fine-grain control over the form:: - - {% for field in form %} - {% ifequal field.name "comment" %} - <!-- Customize the "comment" field, say, make CSS changes --> - ... - {% endfor %} - -But let's look at a simple example:: - - {% get_comment_form for entry as form %} - <!-- A context variable called form is created with the necessary hidden - fields, timestamps and security hashes --> - <table> - <form action="{% comment_form_target %}" method="post"> - {{ form }} - <tr> - <td></td> - <td><input type="submit" name="preview" class="submit-post" value="Preview"></td> - </tr> - </form> - </table> - -Flagging -======== - -If you want your users to be able to flag comments (say for profanity), you -can just direct them (by placing a link in your comment list) to ``/flag/{{ -comment.id }}/``. Similarly, a user with requisite permissions (``"Can -moderate comments"``) can approve and delete comments. This can also be -done through the ``admin`` as you'll see later. You might also want to -customize the following templates: - - * ``flag.html`` - * ``flagged.html`` - * ``approve.html`` - * ``approved.html`` - * ``delete.html`` - * ``deleted.html`` - -found under the directory structure we saw for ``form.html``. - -Feeds -===== - -Suppose you want to export a :doc:`feed </ref/contrib/syndication>` of the -latest comments, you can use the in-built :class:`LatestCommentFeed`. Just -enable it in your project's ``urls.py``: - -.. code-block:: python - - from django.conf.urls.defaults import * - from django.contrib.comments.feeds import LatestCommentFeed - - feeds = { - 'latest': LatestCommentFeed, - } - - urlpatterns = patterns('', - # ... - (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', - {'feed_dict': feeds}), - # ... - ) - -Now you should have the latest comment feeds being served off ``/feeds/latest/``. - -Moderation -========== - -Now that we have the comments framework working, we might want to have some -moderation setup to administer the comments. The comments framework comes -in-built with :doc:`generic comment moderation -</ref/contrib/comments/moderation>`. The comment moderation has the following -features (all of which or only certain can be enabled): - - * Enable comments for a particular model instance. - * Close comments after a particular (user-defined) number of days. - * Email new comments to the site-staff. - -To enable comment moderation, we subclass the :class:`CommentModerator` and -register it with the moderation features we want. Let us suppose we want to -close comments after 7 days of posting and also send out an email to the -site staff. In ``blog/models.py``, we register a comment moderator in the -following way: - -.. code-block:: python - - from django.contrib.comments.moderation import CommentModerator, moderator - from django.db import models - - class Post(models.Model): - title = models.CharField(max_length = 255) - content = models.TextField() - posted_date = models.DateTimeField() - - class PostModerator(CommentModerator): - email_notification = True - auto_close_field = 'posted_date' - # Close the comments after 7 days. - close_after = 7 - - moderator.register(Post, PostModerator) - -The generic comment moderation also has the facility to remove comments. -These comments can then be moderated by any user who has access to the -``admin`` site and the ``Can moderate comments`` permission (can be set -under the ``Users`` page in the ``admin``). - -The moderator can ``Flag``, ``Approve`` or ``Remove`` comments using the -``Action`` drop-down in the ``admin`` under the ``Comments`` page. - -.. note:: - - Only a super-user will be able to delete comments from the database. - ``Remove Comments`` only sets the ``is_public`` attribute to - ``False``. diff --git a/parts/django/docs/ref/contrib/comments/forms.txt b/parts/django/docs/ref/contrib/comments/forms.txt deleted file mode 100644 index c21a27b..0000000 --- a/parts/django/docs/ref/contrib/comments/forms.txt +++ /dev/null @@ -1,46 +0,0 @@ -==================== -Comment form classes -==================== - -.. module:: django.contrib.comments.forms - :synopsis: Forms for dealing with the built-in comment model. - -The ``django.contrib.comments.forms`` module contains a handful of forms -you'll use when writing custom views dealing with comments, or when writing -:doc:`custom comment apps </ref/contrib/comments/custom>`. - -.. class:: CommentForm - - The main comment form representing the standard, built-in way of handling - submitted comments. This is the class used by all the views - :mod:`django.contrib.comments` to handle submitted comments. - - If you want to build custom views that are similar to Django's built-in - comment handling views, you'll probably want to use this form. - -Abstract comment forms for custom comment apps ----------------------------------------------- - -If you're building a :doc:`custom comment app </ref/contrib/comments/custom>`, -you might want to replace *some* of the form logic but still rely on parts of -the existing form. - -:class:`CommentForm` is actually composed of a couple of abstract base class -forms that you can subclass to reuse pieces of the form handling logic: - -.. class:: CommentSecurityForm - - Handles the anti-spoofing protection aspects of the comment form handling. - - This class contains the ``content_type`` and ``object_pk`` fields pointing - to the object the comment is attached to, along with a ``timestamp`` and a - ``security_hash`` of all the form data. Together, the timestamp and the - security hash ensure that spammers can't "replay" form submissions and - flood you with comments. - -.. class:: CommentDetailsForm - - Handles the details of the comment itself. - - This class contains the ``name``, ``email``, ``url``, and the ``comment`` - field itself, along with the associated validation logic.
\ No newline at end of file diff --git a/parts/django/docs/ref/contrib/comments/index.txt b/parts/django/docs/ref/contrib/comments/index.txt deleted file mode 100644 index 817871e..0000000 --- a/parts/django/docs/ref/contrib/comments/index.txt +++ /dev/null @@ -1,302 +0,0 @@ -=========================== -Django's comments framework -=========================== - -.. module:: django.contrib.comments - :synopsis: Django's comment framework - -.. highlightlang:: html+django - -Django includes a simple, yet customizable comments framework. The built-in -comments framework can be used to attach comments to any model, so you can use -it for comments on blog entries, photos, book chapters, or anything else. - -.. note:: - - If you used to use Django's older (undocumented) comments framework, you'll - need to upgrade. See the :doc:`upgrade guide </ref/contrib/comments/upgrade>` - for instructions. - -Quick start guide -================= - -To get started using the ``comments`` app, follow these steps: - - #. Install the comments framework by adding ``'django.contrib.comments'`` to - :setting:`INSTALLED_APPS`. - - #. Run ``manage.py syncdb`` so that Django will create the comment tables. - - #. Add the comment app's URLs to your project's ``urls.py``: - - .. code-block:: python - - urlpatterns = patterns('', - ... - (r'^comments/', include('django.contrib.comments.urls')), - ... - ) - - #. Use the `comment template tags`_ below to embed comments in your - templates. - -You might also want to examine :doc:`/ref/contrib/comments/settings`. - -Comment template tags -===================== - -You'll primarily interact with the comment system through a series of template -tags that let you embed comments and generate forms for your users to post them. - -Like all custom template tag libraries, you'll need to :ref:`load the custom -tags <loading-custom-template-libraries>` before you can use them:: - - {% load comments %} - -Once loaded you can use the template tags below. - -Specifying which object comments are attached to ------------------------------------------------- - -Django's comments are all "attached" to some parent object. This can be any -instance of a Django model. Each of the tags below gives you a couple of -different ways you can specify which object to attach to: - - #. Refer to the object directly -- the more common method. Most of the - time, you'll have some object in the template's context you want - to attach the comment to; you can simply use that object. - - For example, in a blog entry page that has a variable named ``entry``, - you could use the following to load the number of comments:: - - {% get_comment_count for entry as comment_count %}. - - #. Refer to the object by content-type and object id. You'd use this method - if you, for some reason, don't actually have direct access to the object. - - Following the above example, if you knew the object ID was ``14`` but - didn't have access to the actual object, you could do something like:: - - {% get_comment_count for blog.entry 14 as comment_count %} - - In the above, ``blog.entry`` is the app label and (lower-cased) model - name of the model class. - -Displaying comments -------------------- - -To display a list of comments, you can use the template tags -:ttag:`render_comment_list` or :ttag:`get_comment_list`. - -.. templatetag:: render_comment_list - -Quickly rendering a comment list -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The easiest way to display a list of comments for some object is by using -:ttag:`render_comment_list`:: - - {% render_comment_list for [object] %} - -For example:: - - {% render_comment_list for event %} - -This will render comments using a template named ``comments/list.html``, a -default version of which is included with Django. - -.. templatetag:: get_comment_list - -Rendering a custom comment list -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To get the list of comments for some object, use :ttag:`get_comment_list`:: - - {% get_comment_list for [object] as [varname] %} - -For example:: - - {% get_comment_list for event as comment_list %} - {% for comment in comment_list %} - ... - {% endfor %} - -This returns a list of :class:`~django.contrib.comments.models.Comment` objects; -see :doc:`the comment model documentation </ref/contrib/comments/models>` for -details. - -.. templatetag:: get_comment_permalink - -Linking to comments -------------------- - -.. versionadded:: 1.2 - -To provide a permalink to a specific comment, use :ttag:`get_comment_permalink`:: - - {% get_comment_permalink comment_obj [format_string] %} - -By default, the named anchor that will be appended to the URL will be the letter -'c' followed by the comment id, for example 'c82'. You may specify a custom -format string if you wish to override this behavior:: - - {% get_comment_permalink comment "#c%(id)s-by-%(user_name)s"%} - -The format string is a standard python format string. Valid mapping keys -include any attributes of the comment object. - -Regardless of whether you specify a custom anchor pattern, you must supply a -matching named anchor at a suitable place in your template. - -For example:: - - {% for comment in comment_list %} - <a name="c{{ comment.id }}"></a> - <a href="{% get_comment_permalink comment %}"> - permalink for comment #{{ forloop.counter }} - </a> - ... - {% endfor %} - -.. warning:: - - There's a known bug in Safari/Webkit which causes the named anchor to be - forgotten following a redirect. The practical impact for comments is that - the Safari/webkit browsers will arrive at the correct page but will not - scroll to the named anchor. - -.. templatetag:: get_comment_count - -Counting comments ------------------ - -To count comments attached to an object, use :ttag:`get_comment_count`:: - - {% get_comment_count for [object] as [varname] %} - -For example:: - - {% get_comment_count for event as comment_count %} - - <p>This event has {{ comment_count }} comments.</p> - - -Displaying the comment post form --------------------------------- - -To show the form that users will use to post a comment, you can use -:ttag:`render_comment_form` or :ttag:`get_comment_form` - -.. templatetag:: render_comment_form - -Quickly rendering the comment form -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The easiest way to display a comment form is by using -:ttag:`render_comment_form`:: - - {% render_comment_form for [object] %} - -For example:: - - {% render_comment_form for event %} - -This will render comments using a template named ``comments/form.html``, a -default version of which is included with Django. - -.. templatetag:: get_comment_form - -Rendering a custom comment form -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you want more control over the look and feel of the comment form, you use use -:ttag:`get_comment_form` to get a :doc:`form object </topics/forms/index>` that -you can use in the template:: - - {% get_comment_form for [object] as [varname] %} - -A complete form might look like:: - - {% get_comment_form for event as form %} - <form action="{% comment_form_target %}" method="post"> - {{ form }} - <tr> - <td></td> - <td><input type="submit" name="preview" class="submit-post" value="Preview"></td> - </tr> - </form> - -Be sure to read the `notes on the comment form`_, below, for some special -considerations you'll need to make if you're using this approach. - -.. templatetag:: comment_form_target - -Getting the comment form target -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You may have noticed that the above example uses another template tag -- -:ttag:`comment_form_target` -- to actually get the ``action`` attribute of the -form. This will always return the correct URL that comments should be posted to; -you'll always want to use it like above:: - - <form action="{% comment_form_target %}" method="post"> - -Redirecting after the comment post -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To specify the URL you want to redirect to after the comment has been posted, -you can include a hidden form input called ``next`` in your comment form. For example:: - - <input type="hidden" name="next" value="{% url my_comment_was_posted %}" /> - -.. _notes-on-the-comment-form: - -Notes on the comment form -------------------------- - -The form used by the comment system has a few important anti-spam attributes you -should know about: - - * It contains a number of hidden fields that contain timestamps, information - about the object the comment should be attached to, and a "security hash" - used to validate this information. If someone tampers with this data -- - something comment spammers will try -- the comment submission will fail. - - If you're rendering a custom comment form, you'll need to make sure to - pass these values through unchanged. - - * The timestamp is used to ensure that "reply attacks" can't continue very - long. Users who wait too long between requesting the form and posting a - comment will have their submissions refused. - - * The comment form includes a "honeypot_" field. It's a trap: if any data is - entered in that field, the comment will be considered spam (spammers often - automatically fill in all fields in an attempt to make valid submissions). - - The default form hides this field with a piece of CSS and further labels - it with a warning field; if you use the comment form with a custom - template you should be sure to do the same. - -The comments app also depends on the more general :doc:`Cross Site Request -Forgery protection </ref/contrib/csrf>` that comes with Django. As described in -the documentation, it is best to use ``CsrfViewMiddleware``. However, if you -are not using that, you will need to use the ``csrf_protect`` decorator on any -views that include the comment form, in order for those views to be able to -output the CSRF token and cookie. - -.. _honeypot: http://en.wikipedia.org/wiki/Honeypot_(computing) - -More information -================ - -.. toctree:: - :maxdepth: 1 - - models - settings - signals - upgrade - custom - forms - moderation - example diff --git a/parts/django/docs/ref/contrib/comments/models.txt b/parts/django/docs/ref/contrib/comments/models.txt deleted file mode 100644 index e773790..0000000 --- a/parts/django/docs/ref/contrib/comments/models.txt +++ /dev/null @@ -1,80 +0,0 @@ -=========================== -The built-in comment models -=========================== - -.. module:: django.contrib.comments.models - :synopsis: The built-in comment models - -.. class:: Comment - - Django's built-in comment model. Has the following fields: - - .. attribute:: content_object - - A :class:`~django.contrib.contettypes.generic.GenericForeignKey` - attribute pointing to the object the comment is attached to. You can use - this to get at the related object (i.e. ``my_comment.content_object``). - - Since this field is a - :class:`~django.contrib.contettypes.generic.GenericForeignKey`, it's - actually syntactic sugar on top of two underlying attributes, described - below. - - .. attribute:: content_type - - A :class:`~django.db.models.ForeignKey` to - :class:`~django.contrib.contenttypes.models.ContentType`; this is the - type of the object the comment is attached to. - - .. attribute:: object_pk - - A :class:`~django.db.models.TextField` containing the primary - key of the object the comment is attached to. - - .. attribute:: site - - A :class:`~django.db.models.ForeignKey` to the - :class:`~django.contrib.sites.models.Site` on which the comment was - posted. - - .. attribute:: user - - A :class:`~django.db.models.ForeignKey` to the - :class:`~django.contrib.auth.models.User` who posted the comment. - May be blank if the comment was posted by an unauthenticated user. - - .. attribute:: user_name - - The name of the user who posted the comment. - - .. attribute:: user_email - - The email of the user who posted the comment. - - .. attribute:: user_url - - The URL entered by the person who posted the comment. - - .. attribute:: comment - - The actual content of the comment itself. - - .. attribute:: submit_date - - The date the comment was submitted. - - .. attribute:: ip_address - - The IP address of the user posting the comment. - - .. attribute:: is_public - - ``False`` if the comment is in moderation (see - :doc:`/ref/contrib/comments/moderation`); If ``True``, the comment will - be displayed on the site. - - .. attribute:: is_removed - - ``True`` if the comment was removed. Used to keep track of removed - comments instead of just deleting them. - diff --git a/parts/django/docs/ref/contrib/comments/moderation.txt b/parts/django/docs/ref/contrib/comments/moderation.txt deleted file mode 100644 index 519bc5e..0000000 --- a/parts/django/docs/ref/contrib/comments/moderation.txt +++ /dev/null @@ -1,230 +0,0 @@ -========================== -Generic comment moderation -========================== - -.. module:: django.contrib.comments.moderation - :synopsis: Support for automatic comment moderation. - -Django's bundled comments application is extremely useful on its own, -but the amount of comment spam circulating on the Web today -essentially makes it necessary to have some sort of automatic -moderation system in place for any application which makes use of -comments. To make this easier to handle in a consistent fashion, -``django.contrib.comments.moderation`` provides a generic, extensible -comment-moderation system which can be applied to any model or set of -models which want to make use of Django's comment system. - - -Overview -======== - -The entire system is contained within ``django.contrib.comments.moderation``, -and uses a two-step process to enable moderation for any given model: - -1. A subclass of :class:`CommentModerator` - is defined which specifies the moderation options the model wants to - enable. - -2. The model is registered with the moderation system, passing in the - model class and the class which specifies its moderation options. - -A simple example is the best illustration of this. Suppose we have the -following model, which would represent entries in a Weblog:: - - from django.db import models - - class Entry(models.Model): - title = models.CharField(maxlength=250) - body = models.TextField() - pub_date = models.DateTimeField() - enable_comments = models.BooleanField() - -Now, suppose that we want the following steps to be applied whenever a -new comment is posted on an ``Entry``: - -1. If the ``Entry``'s ``enable_comments`` field is ``False``, the - comment will simply be disallowed (i.e., immediately deleted). - -2. If the ``enable_comments`` field is ``True``, the comment will be - allowed to save. - -3. Once the comment is saved, an email should be sent to site staff - notifying them of the new comment. - -Accomplishing this is fairly straightforward and requires very little -code:: - - from django.contrib.comments.moderation import CommentModerator, moderator - - class EntryModerator(CommentModerator): - email_notification = True - enable_field = 'enable_comments' - - moderator.register(Entry, EntryModerator) - -The :class:`CommentModerator` class pre-defines a number of useful moderation -options which subclasses can enable or disable as desired, and ``moderator`` -knows how to work with them to determine whether to allow a comment, whether -to moderate a comment which will be allowed to post, and whether to email -notifications of new comments. - -Built-in moderation options ---------------------------- - -.. class:: CommentModerator - - Most common comment-moderation needs can be handled by subclassing - :class:`CommentModerator` and - changing the values of pre-defined attributes; the full range of built-in - options is as follows. - - .. attribute:: auto_close_field - - If this is set to the name of a - :class:`~django.db.models.fields.DateField` or - :class:`~django.db.models.fields.DateTimeField` on the model for which - comments are being moderated, new comments for objects of that model - will be disallowed (immediately deleted) when a certain number of days - have passed after the date specified in that field. Must be - used in conjunction with :attr:`close_after`, which specifies the - number of days past which comments should be - disallowed. Default value is ``None``. - - .. attribute:: auto_moderate_field - - Like :attr:`auto_close_field`, but instead of outright deleting - new comments when the requisite number of days have elapsed, - it will simply set the ``is_public`` field of new comments to - ``False`` before saving them. Must be used in conjunction with - :attr:`moderate_after`, which specifies the number of days past - which comments should be moderated. Default value is ``None``. - - .. attribute:: close_after - - If :attr:`auto_close_field` is used, this must specify the number - of days past the value of the field specified by - :attr:`auto_close_field` after which new comments for an object - should be disallowed. Default value is ``None``. - - .. attribute:: email_notification - - If ``True``, any new comment on an object of this model which - survives moderation (i.e., is not deleted) will generate an - email to site staff. Default value is ``False``. - - .. attribute:: enable_field - - If this is set to the name of a - :class:`~django.db.models.fields.BooleanField` on the model - for which comments are being moderated, new comments on - objects of that model will be disallowed (immediately deleted) - whenever the value of that field is ``False`` on the object - the comment would be attached to. Default value is ``None``. - - .. attribute:: moderate_after - - If :attr:`auto_moderate_field` is used, this must specify the number - of days past the value of the field specified by - :attr:`auto_moderate_field` after which new comments for an object - should be marked non-public. Default value is ``None``. - -Simply subclassing :class:`CommentModerator` and changing the values of these -options will automatically enable the various moderation methods for any -models registered using the subclass. - -Adding custom moderation methods --------------------------------- - -For situations where the built-in options listed above are not -sufficient, subclasses of :class:`CommentModerator` can also override -the methods which actually perform the moderation, and apply any logic -they desire. :class:`CommentModerator` defines three methods which -determine how moderation will take place; each method will be called -by the moderation system and passed two arguments: ``comment``, which -is the new comment being posted, ``content_object``, which is the -object the comment will be attached to, and ``request``, which is the -:class:`~django.http.HttpRequest` in which the comment is being submitted: - -.. method:: CommentModerator.allow(comment, content_object, request) - - Should return ``True`` if the comment should be allowed to - post on the content object, and ``False`` otherwise (in which - case the comment will be immediately deleted). - -.. method:: CommentModerator.email(comment, content_object, request) - - If email notification of the new comment should be sent to - site staff or moderators, this method is responsible for - sending the email. - -.. method:: CommentModerator.moderate(comment, content_object, request) - - Should return ``True`` if the comment should be moderated (in - which case its ``is_public`` field will be set to ``False`` - before saving), and ``False`` otherwise (in which case the - ``is_public`` field will not be changed). - - -Registering models for moderation ---------------------------------- - -The moderation system, represented by -``django.contrib.comments.moderation.moderator`` is an instance of the class -:class:`Moderator`, which allows registration and "unregistration" of models -via two methods: - -.. function:: moderator.register(model_or_iterable, moderation_class) - - Takes two arguments: the first should be either a model class - or list of model classes, and the second should be a subclass - of ``CommentModerator``, and register the model or models to - be moderated using the options defined in the - ``CommentModerator`` subclass. If any of the models are - already registered for moderation, the exception - :exc:`AlreadyModerated` will be raised. - -.. function:: moderator.unregister(model_or_iterable) - - Takes one argument: a model class or list of model classes, - and removes the model or models from the set of models which - are being moderated. If any of the models are not currently - being moderated, the exception - :exc:`NotModerated` will be raised. - - -Customizing the moderation system ---------------------------------- - -Most use cases will work easily with simple subclassing of -:class:`CommentModerator` and registration with the provided -:class:`Moderator` instance, but customization of global moderation behavior -can be achieved by subclassing :class:`Moderator` and instead registering -models with an instance of the subclass. - -.. class:: Moderator - - In addition to the :meth:`Moderator.register` and - :meth:`Moderator.unregister` methods detailed above, the following methods - on :class:`Moderator` can be overridden to achieve customized behavior: - - .. method:: connect - - Determines how moderation is set up globally. The base - implementation in - :class:`Moderator` does this by - attaching listeners to the :data:`~django.contrib.comments.signals.comment_will_be_posted` - and :data:`~django.contrib.comments.signals.comment_was_posted` signals from the - comment models. - - .. method:: pre_save_moderation(sender, comment, request, **kwargs) - - In the base implementation, applies all pre-save moderation - steps (such as determining whether the comment needs to be - deleted, or whether it needs to be marked as non-public or - generate an email). - - .. method:: post_save_moderation(sender, comment, request, **kwargs) - - In the base implementation, applies all post-save moderation - steps (currently this consists entirely of deleting comments - which were disallowed). diff --git a/parts/django/docs/ref/contrib/comments/settings.txt b/parts/django/docs/ref/contrib/comments/settings.txt deleted file mode 100644 index 1f1aeca..0000000 --- a/parts/django/docs/ref/contrib/comments/settings.txt +++ /dev/null @@ -1,33 +0,0 @@ -================ -Comment settings -================ - -These settings configure the behavior of the comments framework: - -.. setting:: COMMENTS_HIDE_REMOVED - -COMMENTS_HIDE_REMOVED ---------------------- - -If ``True`` (default), removed comments will be excluded from comment -lists/counts (as taken from template tags). Otherwise, the template author is -responsible for some sort of a "this comment has been removed by the site staff" -message. - -.. setting:: COMMENT_MAX_LENGTH - -COMMENT_MAX_LENGTH ------------------- - -The maximum length of the comment field, in characters. Comments longer than -this will be rejected. Defaults to 3000. - -.. setting:: COMMENTS_APP - -COMMENTS_APP ------------- - -An app which provides :doc:`customization of the comments framework -</ref/contrib/comments/custom>`. Use the same dotted-string notation -as in :setting:`INSTALLED_APPS`. Your custom :setting:`COMMENTS_APP` -must also be listed in :setting:`INSTALLED_APPS`. diff --git a/parts/django/docs/ref/contrib/comments/signals.txt b/parts/django/docs/ref/contrib/comments/signals.txt deleted file mode 100644 index 7ae34a1..0000000 --- a/parts/django/docs/ref/contrib/comments/signals.txt +++ /dev/null @@ -1,91 +0,0 @@ -================================ -Signals sent by the comments app -================================ - -.. module:: django.contrib.comments.signals - :synopsis: Signals sent by the comment module. - -The comment app sends a series of :doc:`signals </topics/signals>` to allow for -comment moderation and similar activities. See :doc:`the introduction to signals -</topics/signals>` for information about how to register for and receive these -signals. - -comment_will_be_posted -====================== - -.. data:: django.contrib.comments.signals.comment_will_be_posted - :module: - -Sent just before a comment will be saved, after it's been sanity checked and -submitted. This can be used to modify the comment (in place) with posting -details or other such actions. - -If any receiver returns ``False`` the comment will be discarded and a 403 (not -allowed) response will be returned. - -This signal is sent at more or less the same time (just before, actually) as the -``Comment`` object's :data:`~django.db.models.signals.pre_save` signal. - -Arguments sent with this signal: - - ``sender`` - The comment model. - - ``comment`` - The comment instance about to be posted. Note that it won't have been - saved into the database yet, so it won't have a primary key, and any - relations might not work correctly yet. - - ``request`` - The :class:`~django.http.HttpRequest` that posted the comment. - -comment_was_posted -================== - -.. data:: django.contrib.comments.signals.comment_was_posted - :module: - -Sent just after the comment is saved. - -Arguments sent with this signal: - - ``sender`` - The comment model. - - ``comment`` - The comment instance that was posted. Note that it will have already - been saved, so if you modify it you'll need to call - :meth:`~django.db.models.Model.save` again. - - ``request`` - The :class:`~django.http.HttpRequest` that posted the comment. - -comment_was_flagged -=================== - -.. data:: django.contrib.comments.signals.comment_was_flagged - :module: - -Sent after a comment was "flagged" in some way. Check the flag to see if this -was a user requesting removal of a comment, a moderator approving/removing a -comment, or some other custom user flag. - -Arguments sent with this signal: - - ``sender`` - The comment model. - - ``comment`` - The comment instance that was posted. Note that it will have already - been saved, so if you modify it you'll need to call - :meth:`~django.db.models.Model.save` again. - - ``flag`` - The :class:`~django.contrib.comments.models.CommentFlag` that's been - attached to the comment. - - ``created`` - ``True`` if this is a new flag; ``False`` if it's a duplicate flag. - - ``request`` - The :class:`~django.http.HttpRequest` that posted the comment. diff --git a/parts/django/docs/ref/contrib/comments/upgrade.txt b/parts/django/docs/ref/contrib/comments/upgrade.txt deleted file mode 100644 index 3d6b5af..0000000 --- a/parts/django/docs/ref/contrib/comments/upgrade.txt +++ /dev/null @@ -1,78 +0,0 @@ -=============================================== -Upgrading from Django's previous comment system -=============================================== - -Prior versions of Django included an outdated, undocumented comment system. Users who reverse-engineered this framework will need to upgrade to use the -new comment system; this guide explains how. - -The main changes from the old system are: - - * This new system is documented. - - * It uses modern Django features like :doc:`forms </topics/forms/index>` and - :doc:`modelforms </topics/forms/modelforms>`. - - * It has a single ``Comment`` model instead of separate ``FreeComment`` and - ``Comment`` models. - - * Comments have "email" and "URL" fields. - - * No ratings, photos and karma. This should only effect World Online. - - * The ``{% comment_form %}`` tag no longer exists. Instead, there's now two - functions: ``{% get_comment_form %}``, which returns a form for posting a - new comment, and ``{% render_comment_form %}``, which renders said form - using the ``comments/form.html`` template. - - * The way comments are include in your URLconf have changed; you'll need to - replace:: - - (r'^comments/', include('django.contrib.comments.urls.comments')), - - with:: - - (r'^comments/', include('django.contrib.comments.urls')), - -Upgrading data --------------- - -The data models for Django's comment system have changed, as have the -table names. Before you transfer your existing data into the new comments -system, make sure that you have installed the new comments system as -explained in the -:doc:`quick start guide </ref/contrib/comments/index>`. -This will ensure that the new tables have been properly created. - -To transfer your data into the new comments system, you'll need to directly -run the following SQL: - -.. code-block:: sql - - BEGIN; - - INSERT INTO django_comments - (content_type_id, object_pk, site_id, user_name, user_email, user_url, - comment, submit_date, ip_address, is_public, is_removed) - SELECT - content_type_id, object_id, site_id, person_name, '', '', comment, - submit_date, ip_address, is_public, not approved - FROM comments_freecomment; - - INSERT INTO django_comments - (content_type_id, object_pk, site_id, user_id, user_name, user_email, - user_url, comment, submit_date, ip_address, is_public, is_removed) - SELECT - content_type_id, object_id, site_id, user_id, '', '', '', comment, - submit_date, ip_address, is_public, is_removed - FROM comments_comment; - - UPDATE django_comments SET user_name = ( - SELECT username FROM auth_user - WHERE django_comments.user_id = auth_user.id - ) WHERE django_comments.user_id is not NULL; - UPDATE django_comments SET user_email = ( - SELECT email FROM auth_user - WHERE django_comments.user_id = auth_user.id - ) WHERE django_comments.user_id is not NULL; - - COMMIT; diff --git a/parts/django/docs/ref/contrib/contenttypes.txt b/parts/django/docs/ref/contrib/contenttypes.txt deleted file mode 100644 index b695651..0000000 --- a/parts/django/docs/ref/contrib/contenttypes.txt +++ /dev/null @@ -1,385 +0,0 @@ -========================== -The contenttypes framework -========================== - -.. module:: django.contrib.contenttypes - :synopsis: Provides generic interface to installed models. - -Django includes a :mod:`contenttypes` application that can track all of -the models installed in your Django-powered project, providing a -high-level, generic interface for working with your models. - -Overview -======== - -At the heart of the contenttypes application is the -:class:`~django.contrib.contenttypes.models.ContentType` model, which lives at -``django.contrib.contenttypes.models.ContentType``. Instances of -:class:`~django.contrib.contenttypes.models.ContentType` represent and store -information about the models installed in your project, and new instances of -:class:`~django.contrib.contenttypes.models.ContentType` are automatically -created whenever new models are installed. - -Instances of :class:`~django.contrib.contenttypes.models.ContentType` have -methods for returning the model classes they represent and for querying objects -from those models. :class:`~django.contrib.contenttypes.models.ContentType` -also has a :ref:`custom manager <custom-managers>` that adds methods for -working with :class:`~django.contrib.contenttypes.models.ContentType` and for -obtaining instances of :class:`~django.contrib.contenttypes.models.ContentType` -for a particular model. - -Relations between your models and -:class:`~django.contrib.contenttypes.models.ContentType` can also be used to -enable "generic" relationships between an instance of one of your -models and instances of any model you have installed. - -Installing the contenttypes framework -===================================== - -The contenttypes framework is included in the default -:setting:`INSTALLED_APPS` list created by ``django-admin.py startproject``, -but if you've removed it or if you manually set up your -:setting:`INSTALLED_APPS` list, you can enable it by adding -``'django.contrib.contenttypes'`` to your :setting:`INSTALLED_APPS` setting. - -It's generally a good idea to have the contenttypes framework -installed; several of Django's other bundled applications require it: - - * The admin application uses it to log the history of each object - added or changed through the admin interface. - - * Django's :mod:`authentication framework <django.contrib.auth>` uses it - to tie user permissions to specific models. - - * Django's comments system (:mod:`django.contrib.comments`) uses it to - "attach" comments to any installed model. - -The ``ContentType`` model -========================= - -.. class:: models.ContentType - - Each instance of :class:`~django.contrib.contenttypes.models.ContentType` - has three fields which, taken together, uniquely describe an installed model: - - .. attribute:: models.ContentType.app_label - - The name of the application the model is part of. This is taken from - the :attr:`app_label` attribute of the model, and includes only the *last* - part of the application's Python import path; - "django.contrib.contenttypes", for example, becomes an :attr:`app_label` - of "contenttypes". - - .. attribute:: models.ContentType.model - - The name of the model class. - - .. attribute:: models.ContentType.name - - The human-readable name of the model. This is taken from the - :attr:`verbose_name <django.db.models.fields.Field.verbose_name>` - attribute of the model. - -Let's look at an example to see how this works. If you already have -the contenttypes application installed, and then add -:mod:`the sites application <django.contrib.sites>` to your -:setting:`INSTALLED_APPS` setting and run ``manage.py syncdb`` to install it, -the model :class:`django.contrib.sites.models.Site` will be installed into -your database. Along with it a new instance of -:class:`~django.contrib.contenttypes.models.ContentType` will be -created with the following values: - - * :attr:`app_label` will be set to ``'sites'`` (the last part of the Python - path "django.contrib.sites"). - - * :attr:`model` will be set to ``'site'``. - - * :attr:`name` will be set to ``'site'``. - -.. _the verbose_name attribute: ../model-api/#verbose_name - -Methods on ``ContentType`` instances -==================================== - -.. class:: models.ContentType - - Each :class:`~django.contrib.contenttypes.models.ContentType` instance has - methods that allow you to get from a - :class:`~django.contrib.contenttypes.models.ContentType` instance to the model - it represents, or to retrieve objects from that model: - -.. method:: models.ContentType.get_object_for_this_type(**kwargs) - - Takes a set of valid :ref:`lookup arguments <field-lookups-intro>` for the - model the :class:`~django.contrib.contenttypes.models.ContentType` - represents, and does :lookup:`a get() lookup <get>` on that model, - returning the corresponding object. - -.. method:: models.ContentType.model_class() - - Returns the model class represented by this - :class:`~django.contrib.contenttypes.models.ContentType` instance. - -For example, we could look up the -:class:`~django.contrib.contenttypes.models.ContentType` for the -:class:`~django.contrib.auth.models.User` model:: - - >>> from django.contrib.contenttypes.models import ContentType - >>> user_type = ContentType.objects.get(app_label="auth", model="user") - >>> user_type - <ContentType: user> - -And then use it to query for a particular ``User``, or to get access -to the ``User`` model class:: - - >>> user_type.model_class() - <class 'django.contrib.auth.models.User'> - >>> user_type.get_object_for_this_type(username='Guido') - <User: Guido> - -Together, -:meth:`~django.contrib.contenttypes.models.ContentType.get_object_for_this_type` -and :meth:`~django.contrib.contenttypes.models.ContentType.model_class` -enable two extremely important use cases: - - 1. Using these methods, you can write high-level generic code that - performs queries on any installed model -- instead of importing and using - a single specific model class, you can pass an ``app_label`` and - ``model`` into a :class:`~django.contrib.contenttypes.models.ContentType` - lookup at runtime, and then work with the model class or retrieve objects - from it. - - 2. You can relate another model to - :class:`~django.contrib.contenttypes.models.ContentType` as a way of - tying instances of it to particular model classes, and use these methods - to get access to those model classes. - -Several of Django's bundled applications make use of the latter technique. -For example, -:class:`the permissions system <django.contrib.auth.models.Permission` in -Django's authentication framework uses a -:class:`~django.contrib.auth.models.Permission` model with a foreign -key to :class:`~django.contrib.contenttypes.models.ContentType`; this lets -:class:`~django.contrib.auth.models.Permission` represent concepts like -"can add blog entry" or "can delete news story". - -The ``ContentTypeManager`` --------------------------- - -.. class:: models.ContentTypeManager - - :class:`~django.contrib.contenttypes.models.ContentType` also has a custom - manager, :class:`~django.contrib.contenttypes.models.ContentTypeManager`, - which adds the following methods: - - .. method:: models.ContentTypeManager.clear_cache() - - Clears an internal cache used by - :class:`~django.contrib.contenttypes.models.ContentType` to keep track - of which models for which it has created - :class:`django.contrib.contenttypes.models.ContentType` instances. You - probably won't ever need to call this method yourself; Django will call - it automatically when it's needed. - - .. method:: models.ContentTypeManager.get_for_model(model) - - Takes either a model class or an instance of a model, and returns the - :class:`~django.contrib.contenttypes.models.ContentType` instance - representing that model. - -The :meth:`~models.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:: - - >>> from django.contrib.auth.models import User - >>> user_type = ContentType.objects.get_for_model(User) - >>> user_type - <ContentType: user> - -.. _generic-relations: - -Generic relations -================= - -Adding a foreign key from one of your own models to -:class:`~django.contrib.contenttypes.models.ContentType` allows your model to -effectively tie itself to another model class, as in the example of the -:class:`~django.contrib.auth.models.Permission` model above. But it's possible -to go one step further and use -:class:`~django.contrib.contenttypes.models.ContentType` to enable truly -generic (sometimes called "polymorphic") relationships between models. - -A simple example is a tagging system, which might look like this:: - - from django.db import models - from django.contrib.contenttypes.models import ContentType - from django.contrib.contenttypes import generic - - class TaggedItem(models.Model): - tag = models.SlugField() - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey('content_type', 'object_id') - - def __unicode__(self): - return self.tag - -A normal :class:`~django.db.models.fields.related.ForeignKey` can only "point -to" one other model, which means that if the ``TaggedItem`` model used a -:class:`~django.db.models.fields.related.ForeignKey` it would have to -choose one and only one model to store tags for. The contenttypes -application provides a special field type -- -:class:`django.contrib.contenttypes.generic.GenericForeignKey` -- which -works around this and allows the relationship to be with any -model. There are three parts to setting up a -:class:`~django.contrib.contenttypes.generic.GenericForeignKey`: - - 1. Give your model a :class:`~django.db.models.fields.related.ForeignKey` - to :class:`~django.contrib.contenttypes.models.ContentType`. - - 2. Give your model a field that can store a primary-key value from the - models you'll be relating to. (For most models, this means an - :class:`~django.db.models.fields.IntegerField` or - :class:`~django.db.models.fields.PositiveIntegerField`.) - - This field must be of the same type as the primary key of the models - that will be involved in the generic relation. For example, if you use - :class:`~django.db.models.fields.IntegerField`, you won't be able to - form a generic relation with a model that uses a - :class:`~django.db.models.fields.CharField` as a primary key. - - 3. Give your model a - :class:`~django.contrib.contenttypes.generic.GenericForeignKey`, and - pass it the names of the two fields described above. If these fields - are named "content_type" and "object_id", you can omit this -- those - are the default field names - :class:`~django.contrib.contenttypes.generic.GenericForeignKey` will - look for. - -This will enable an API similar to the one used for a normal -:class:`~django.db.models.fields.related.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``:: - - >>> from django.contrib.auth.models import User - >>> guido = User.objects.get(username='Guido') - >>> t = TaggedItem(content_object=guido, tag='bdfl') - >>> t.save() - >>> t.content_object - <User: Guido> - -Due to the way :class:`~django.contrib.contenttypes.generic.GenericForeignKey` -is implemented, you cannot use such fields directly with filters (``filter()`` -and ``exclude()``, for example) via the database API. They aren't normal field -objects. These examples will *not* work:: - - # This will fail - >>> TaggedItem.objects.filter(content_object=guido) - # This will also fail - >>> TaggedItem.objects.get(content_object=guido) - -Reverse generic relations -------------------------- - -If you know which models you'll be using most often, you can also add -a "reverse" generic relationship to enable an additional API. For example:: - - class Bookmark(models.Model): - url = models.URLField() - tags = generic.GenericRelation(TaggedItem) - -``Bookmark`` instances will each have a ``tags`` attribute, which can -be used to retrieve their associated ``TaggedItems``:: - - >>> b = Bookmark(url='http://www.djangoproject.com/') - >>> b.save() - >>> t1 = TaggedItem(content_object=b, tag='django') - >>> t1.save() - >>> t2 = TaggedItem(content_object=b, tag='python') - >>> t2.save() - >>> b.tags.all() - [<TaggedItem: django>, <TaggedItem: python>] - -Just as :class:`django.contrib.contenttypes.generic.GenericForeignKey` -accepts the names of the content-type and object-ID fields as -arguments, so too does ``GenericRelation``; if the model which has the -generic foreign key is using non-default names for those fields, you -must pass the names of the fields when setting up a -``GenericRelation`` to it. For example, if the ``TaggedItem`` model -referred to above used fields named ``content_type_fk`` and -``object_primary_key`` to create its generic foreign key, then a -``GenericRelation`` back to it would need to be defined like so:: - - tags = generic.GenericRelation(TaggedItem, content_type_field='content_type_fk', object_id_field='object_primary_key') - -Of course, if you don't add the reverse relationship, you can do the -same types of lookups manually:: - - >>> b = Bookmark.objects.get(url='http://www.djangoproject.com/') - >>> bookmark_type = ContentType.objects.get_for_model(b) - >>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id, - ... object_id=b.id) - [<TaggedItem: django>, <TaggedItem: python>] - -Note that if the model in a -:class:`~django.contrib.contenttypes.generic.GenericRelation` uses a -non-default value for ``ct_field`` or ``fk_field`` in its -:class:`~django.contrib.contenttypes.generic.GenericForeignKey` (e.g. the -:mod:`django.contrib.comments` app uses ``ct_field="object_pk"``), -you'll need to set ``content_type_field`` and/or ``object_id_field`` in -the :class:`~django.contrib.contenttypes.generic.GenericRelation` to -match the ``ct_field`` and ``fk_field``, respectively, in the -:class:`~django.contrib.contenttypes.generic.GenericForeignKey`:: - - comments = generic.GenericRelation(Comment, object_id_field="object_pk") - -Note also, that if you delete an object that has a -:class:`~django.contrib.contenttypes.generic.GenericRelation`, any objects -which have a :class:`~django.contrib.contenttypes.generic.GenericForeignKey` -pointing at it will be deleted as well. In the example above, this means that -if a ``Bookmark`` object were deleted, any ``TaggedItem`` objects pointing at -it would be deleted at the same time. - -Generic relations and aggregation ---------------------------------- - -:doc:`Django's database aggregation API </topics/db/aggregation>` -doesn't work with a -:class:`~django.contrib.contenttypes.generic.GenericRelation`. For example, you -might be tempted to try something like:: - - Bookmark.objects.aggregate(Count('tags')) - -This will not work correctly, however. The generic relation adds extra filters -to the queryset to ensure the correct content type, but the ``aggregate`` method -doesn't take them into account. For now, if you need aggregates on generic -relations, you'll need to calculate them without using the aggregation API. - -Generic relations in forms and admin ------------------------------------- - -:mod:`django.contrib.contenttypes.generic` provides both a -:class:`~django.contrib.contenttypes.generic.GenericInlineFormSet` -and :class:`~django.contrib.contenttypes.generic.GenericInlineModelAdmin`. -This enables the use of generic relations in forms and the admin. See the -:doc:`model formset </topics/forms/modelforms>` and -:doc:`admin </ref/contrib/admin/index>` documentation for more information. - -.. class:: generic.GenericInlineModelAdmin - - The :class:`~django.contrib.contenttypes.generic.GenericInlineModelAdmin` - class inherits all properties from an - :class:`~django.contrib.admin.InlineModelAdmin` class. However, - it adds a couple of its own for working with the generic relation: - - .. attribute:: generic.GenericInlineModelAdmin.ct_field - - The name of the - :class:`~django.contrib.contenttypes.models.ContentType` foreign key - field on the model. Defaults to ``content_type``. - - .. attribute:: generic.GenericInlineModelAdmin.ct_fk_field - - The name of the integer field that represents the ID of the related - object. Defaults to ``object_id``. diff --git a/parts/django/docs/ref/contrib/csrf.txt b/parts/django/docs/ref/contrib/csrf.txt deleted file mode 100644 index c32dd73..0000000 --- a/parts/django/docs/ref/contrib/csrf.txt +++ /dev/null @@ -1,433 +0,0 @@ -===================================== -Cross Site Request Forgery protection -===================================== - -.. module:: django.middleware.csrf - :synopsis: Protects against Cross Site Request Forgeries - -The CSRF middleware and template tag provides easy-to-use protection against -`Cross Site Request Forgeries`_. This type of attack occurs when a malicious -Web site contains a link, a form button or some javascript that is intended to -perform some action on your Web site, using the credentials of a logged-in user -who visits the malicious site in their browser. A related type of attack, -'login CSRF', where an attacking site tricks a user's browser into logging into -a site with someone else's credentials, is also covered. - -The first defense against CSRF attacks is to ensure that GET requests are -side-effect free. POST requests can then be protected by following the steps -below. - -.. versionadded:: 1.2 - The 'contrib' apps, including the admin, use the functionality described - here. Because it is security related, a few things have been added to core - functionality to allow this to happen without any required upgrade steps. - -.. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF - -How to use it -============= - -.. versionchanged:: 1.2 - The template tag functionality (the recommended way to use this) was added - in version 1.2. The previous method (still available) is described under - `Legacy method`_. - -To enable CSRF protection for your views, follow these steps: - - 1. Add the middleware - ``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of - middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come - before ``CsrfResponseMiddleware`` if that is being used, and before any - view middleware that assume that CSRF attacks have been dealt with.) - - Alternatively, you can use the decorator - ``django.views.decorators.csrf.csrf_protect`` on particular views you - want to protect (see below). - - 2. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside - the ``<form>`` element if the form is for an internal URL, e.g.:: - - <form action="" method="post">{% csrf_token %} - - This should not be done for POST forms that target external URLs, since - that would cause the CSRF token to be leaked, leading to a vulnerability. - - 3. In the corresponding view functions, ensure that the - ``'django.core.context_processors.csrf'`` context processor is - being used. Usually, this can be done in one of two ways: - - 1. Use RequestContext, which always uses - ``'django.core.context_processors.csrf'`` (no matter what your - TEMPLATE_CONTEXT_PROCESSORS setting). If you are using - generic views or contrib apps, you are covered already, since these - apps use RequestContext throughout. - - 2. Manually import and use the processor to generate the CSRF token and - add it to the template context. e.g.:: - - from django.core.context_processors import csrf - from django.shortcuts import render_to_response - - def my_view(request): - c = {} - c.update(csrf(request)) - # ... view code here - return render_to_response("a_template.html", c) - - You may want to write your own ``render_to_response`` wrapper that - takes care of this step for you. - -The utility script ``extras/csrf_migration_helper.py`` can help to automate the -finding of code and templates that may need to be upgraded. It contains full -help on how to use it. - -The decorator method --------------------- - -Rather than adding ``CsrfViewMiddleware`` as a blanket protection, you can use -the ``csrf_protect`` decorator, which has exactly the same functionality, on -particular views that need the protection. It must be used **both** on views -that insert the CSRF token in the output, and on those that accept the POST form -data. (These are often the same view function, but not always). It is used like -this:: - - from django.views.decorators.csrf import csrf_protect - from django.template import RequestContext - - @csrf_protect - def my_view(request): - c = {} - # ... - return render_to_response("a_template.html", c, - context_instance=RequestContext(request)) - -Use of the decorator is **not recommended** by itself, since if you forget to -use it, you will have a security hole. The 'belt and braces' strategy of using -both is fine, and will incur minimal overhead. - -Legacy method -------------- - -In Django 1.1, the template tag did not exist. Instead, a post-processing -middleware that re-wrote POST forms to include the CSRF token was used. If you -are upgrading a site from version 1.1 or earlier, please read this section and -the `Upgrading notes`_ below. The post-processing middleware is still available -as ``CsrfResponseMiddleware``, and it can be used by following these steps: - - 1. Follow step 1 above to install ``CsrfViewMiddleware``. - - 2. Add ``'django.middleware.csrf.CsrfResponseMiddleware'`` to your - :setting:`MIDDLEWARE_CLASSES` setting. - - ``CsrfResponseMiddleware`` needs to process the response before things - like compression or setting ofETags happen to the response, so it must - come after ``GZipMiddleware``, ``CommonMiddleware`` and - ``ConditionalGetMiddleware`` in the list. It also must come after - ``CsrfViewMiddleware``. - -Use of the ``CsrfResponseMiddleware`` is not recommended because of the -performance hit it imposes, and because of a potential security problem (see -below). It can be used as an interim measure until applications have been -updated to use the :ttag:`csrf_token` tag. It is deprecated and will be -removed in Django 1.4. - -Django 1.1 and earlier provided a single ``CsrfMiddleware`` class. This is also -still available for backwards compatibility. It combines the functions of the -two middleware. - -Note also that previous versions of these classes depended on the sessions -framework, but this dependency has now been removed, with backward compatibility -support so that upgrading will not produce any issues. - -Security of legacy method -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The post-processing ``CsrfResponseMiddleware`` adds the CSRF token to all POST -forms (unless the view has been decorated with ``csrf_response_exempt``). If -the POST form has an external untrusted site as its target, rather than an -internal page, that site will be sent the CSRF token when the form is submitted. -Armed with this leaked information, that site will then be able to successfully -launch a CSRF attack on your site against that user. The -``@csrf_response_exempt`` decorator can be used to fix this, but only if the -page doesn't also contain internal forms that require the token. - -.. _ref-csrf-upgrading-notes: - -Upgrading notes ---------------- - -When upgrading to version 1.2 or later, you may have applications that rely on -the old post-processing functionality for CSRF protection, or you may not have -enabled any CSRF protection. This section outlines the steps necessary for a -smooth upgrade, without having to fix all the applications to use the new -template tag method immediately. - -First of all, the location of the middleware and related functions have -changed. There are backwards compatible stub files so that old imports will -continue to work for now, but they are deprecated and will be removed in Django -1.4. The following changes have been made: - - * Middleware have been moved to ``django.middleware.csrf`` - * Decorators have been moved to ``django.views.decorators.csrf`` - -====================================================== ============================================== - Old New -====================================================== ============================================== -django.contrib.csrf.middleware.CsrfMiddleware django.middleware.csrf.CsrfMiddleware -django.contrib.csrf.middleware.CsrfViewMiddleware django.middleware.csrf.CsrfViewMiddleware -django.contrib.csrf.middleware.CsrfResponseMiddleware django.middleware.csrf.CsrfResponseMiddleware -django.contrib.csrf.middleware.csrf_exempt django.views.decorators.csrf.csrf_exempt -django.contrib.csrf.middleware.csrf_view_exempt django.views.decorators.csrf.csrf_view_exempt -django.contrib.csrf.middleware.csrf_response_exempt django.views.decorators.csrf.csrf_response_exempt -====================================================== ============================================== - -You should update any imports, and also the paths in your -:setting:`MIDDLEWARE_CLASSES`. - -If you have ``CsrfMiddleware`` in your :setting:`MIDDLEWARE_CLASSES`, you will now -have a working installation with CSRF protection. It is recommended at this -point that you replace ``CsrfMiddleware`` with its two components, -``CsrfViewMiddleware`` and ``CsrfResponseMiddleware`` (in that order). - -If you do not have any of the middleware in your :setting:`MIDDLEWARE_CLASSES`, -you will have a working installation but without any CSRF protection for your -views (just as you had before). It is strongly recommended to install -``CsrfViewMiddleware`` and ``CsrfResponseMiddleware``, as described above. - -Note that contrib apps, such as the admin, have been updated to use the -``csrf_protect`` decorator, so that they are secured even if you do not add the -``CsrfViewMiddleware`` to your settings. However, if you have supplied -customised templates to any of the view functions of contrib apps (whether -explicitly via a keyword argument, or by overriding built-in templates), **you -MUST update them** to include the :ttag:`csrf_token` template tag as described -above, or they will stop working. (If you cannot update these templates for -some reason, you will be forced to use ``CsrfResponseMiddleware`` for these -views to continue working). - -Note also, if you are using the comments app, and you are not going to add -``CsrfViewMiddleware`` to your settings (not recommended), you will need to add -the ``csrf_protect`` decorator to any views that include the comment forms and -target the comment views (usually using the :ttag:`comment_form_target` template -tag). - -Assuming you have followed the above, all views in your Django site will now be -protected by the ``CsrfViewMiddleware``. Contrib apps meet the requirements -imposed by the ``CsrfViewMiddleware`` using the template tag, and other -applications in your project will meet its requirements by virtue of the -``CsrfResponseMiddleware``. - -The next step is to update all your applications to use the template tag, as -described in `How to use it`_, steps 2-3. This can be done as soon as is -practical. Any applications that are updated will now require Django 1.1.2 or -later, since they will use the CSRF template tag which was not available in -earlier versions. (The template tag in 1.1.2 is actually a no-op that exists -solely to ease the transition to 1.2 — it allows apps to be created that have -CSRF protection under 1.2 without requiring users of the apps to upgrade to the -Django 1.2.X series). - -The utility script ``extras/csrf_migration_helper.py`` can help to automate the -finding of code and templates that may need to be upgraded. It contains full -help on how to use it. - -Finally, once all applications are upgraded, ``CsrfResponseMiddleware`` can be -removed from your settings. - -While ``CsrfResponseMiddleware`` is still in use, the ``csrf_response_exempt`` -decorator, described in `Exceptions`_, may be useful. The post-processing -middleware imposes a performance hit and a potential vulnerability, and any -views that have been upgraded to use the new template tag method no longer need -it. - -Exceptions ----------- - -.. versionadded:: 1.1 -.. versionchanged:: 1.2 - Import paths for the decorators below were changed. - -To manually exclude a view function from being handled by either of the two CSRF -middleware, you can use the ``csrf_exempt`` decorator, found in the -``django.views.decorators.csrf`` module. For example:: - - from django.views.decorators.csrf import csrf_exempt - - @csrf_exempt - def my_view(request): - return HttpResponse('Hello world') - -Like the middleware, the ``csrf_exempt`` decorator is composed of two parts: a -``csrf_view_exempt`` decorator and a ``csrf_response_exempt`` decorator, found -in the same module. These disable the view protection mechanism -(``CsrfViewMiddleware``) and the response post-processing -(``CsrfResponseMiddleware``) respectively. They can be used individually if -required. - -You don't have to worry about doing this for most AJAX views. Any request sent -with "X-Requested-With: XMLHttpRequest" is automatically exempt. (See the `How -it works`_ section.) - -Subdomains ----------- - -By default, CSRF cookies are specific to the subdomain they are set for. This -means that a form served from one subdomain (e.g. server1.example.com) will not -be able to have a target on another subdomain (e.g. server2.example.com). This -restriction can be removed by setting :setting:`CSRF_COOKIE_DOMAIN` to be -something like ``".example.com"``. - -Please note that, with or without use of this setting, this CSRF protection -mechanism is not safe against cross-subdomain attacks -- see `Limitations`_. - -Rejected requests -================= - -By default, a '403 Forbidden' response is sent to the user if an incoming -request fails the checks performed by ``CsrfViewMiddleware``. This should -usually only be seen when there is a genuine Cross Site Request Forgery, or -when, due to a programming error, the CSRF token has not been included with a -POST form. - -No logging is done, and the error message is not very friendly, so you may want -to provide your own page for handling this condition. To do this, simply set -the :setting:`CSRF_FAILURE_VIEW` setting to a dotted path to your own view -function, which should have the following signature:: - - def csrf_failure(request, reason="") - -where ``reason`` is a short message (intended for developers or logging, not for -end users) indicating the reason the request was rejected. - -How it works -============ - -The CSRF protection is based on the following things: - -1. A CSRF cookie that is set to a random value (a session independent nonce, as - it is called), which other sites will not have access to. - - This cookie is set by ``CsrfViewMiddleware``. It is meant to be permanent, - but since there is no way to set a cookie that never expires, it is sent with - every response that has called ``django.middleware.csrf.get_token()`` - (the function used internally to retrieve the CSRF token). - -2. A hidden form field with the name 'csrfmiddlewaretoken' present in all - outgoing POST forms. The value of this field is the value of the CSRF - cookie. - - This part is done by the template tag (and with the legacy method, it is done - by ``CsrfResponseMiddleware``). - -3. For all incoming POST requests, a CSRF cookie must be present, and the - 'csrfmiddlewaretoken' field must be present and correct. If it isn't, the - user will get a 403 error. - - This check is done by ``CsrfViewMiddleware``. - -4. In addition, for HTTPS requests, strict referer checking is done by - ``CsrfViewMiddleware``. This is necessary to address a Man-In-The-Middle - attack that is possible under HTTPS when using a session independent nonce, - due to the fact that HTTP 'Set-Cookie' headers are (unfortunately) accepted - by clients that are talking to a site under HTTPS. (Referer checking is not - done for HTTP requests because the presence of the Referer header is not - reliable enough under HTTP.) - -This ensures that only forms that have originated from your Web site can be used -to POST data back. - -It deliberately only targets HTTP POST requests (and the corresponding POST -forms). GET requests ought never to have any potentially dangerous side effects -(see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a CSRF attack with a GET -request ought to be harmless. - -``CsrfResponseMiddleware`` checks the Content-Type before modifying the -response, and only pages that are served as 'text/html' or -'application/xml+xhtml' are modified. - -AJAX ----- - -The middleware tries to be smart about requests that come in via AJAX. Most -modern JavaScript toolkits send an "X-Requested-With: XMLHttpRequest" HTTP -header; these requests are detected and automatically *not* handled by this -middleware. We can do this safely because, in the context of a browser, the -header can only be added by using ``XMLHttpRequest``, and browsers already -implement a same-domain policy for ``XMLHttpRequest``. - -For the more recent browsers that relax this same-domain policy, custom headers -like "X-Requested-With" are only allowed after the browser has done a -'preflight' check to the server to see if the cross-domain request is allowed, -using a strictly 'opt in' mechanism, so the exception for AJAX is still safe—if -the developer has specifically opted in to allowing cross-site AJAX POST -requests on a specific URL, they obviously don't want the middleware to disallow -exactly that. - -.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html - -Caching -======= - -If the :ttag:`csrf_token` template tag is used by a template (or the ``get_token`` -function is called some other way), ``CsrfViewMiddleware`` will add a cookie and -a ``Vary: Cookie`` header to the response. Similarly, -``CsrfResponseMiddleware`` will send the ``Vary: Cookie`` header if it inserted -a token. This means that these middleware will play well with the cache -middleware if it is used as instructed (``UpdateCacheMiddleware`` goes before -all other middleware). - -However, if you use cache decorators on individual views, the CSRF middleware -will not yet have been able to set the Vary header. In this case, on any views -that will require a CSRF token to be inserted you should use the -:func:`django.views.decorators.vary.vary_on_cookie` decorator first:: - - from django.views.decorators.cache import cache_page - from django.views.decorators.vary import vary_on_cookie - - @cache_page(60 * 15) - @vary_on_cookie - def my_view(request): - # ... - - -Testing -======= - -The ``CsrfViewMiddleware`` will usually be a big hindrance to testing view -functions, due to the need for the CSRF token which must be sent with every POST -request. For this reason, Django's HTTP client for tests has been modified to -set a flag on requests which relaxes the middleware and the ``csrf_protect`` -decorator so that they no longer rejects requests. In every other respect -(e.g. sending cookies etc.), they behave the same. - -If, for some reason, you *want* the test client to perform CSRF -checks, you can create an instance of the test client that enforces -CSRF checks:: - - >>> from django.test import Client - >>> csrf_client = Client(enforce_csrf_checks=True) - -Limitations -=========== - -Subdomains within a site will be able to set cookies on the client for the whole -domain. By setting the cookie and using a corresponding token, subdomains will -be able to circumvent the CSRF protection. The only way to avoid this is to -ensure that subdomains are controlled by trusted users (or, are at least unable -to set cookies). Note that even without CSRF, there are other vulnerabilities, -such as session fixation, that make giving subdomains to untrusted parties a bad -idea, and these vulnerabilities cannot easily be fixed with current browsers. - -If you are using ``CsrfResponseMiddleware`` and your app creates HTML pages and -forms in some unusual way, (e.g. it sends fragments of HTML in JavaScript -document.write statements) you might bypass the filter that adds the hidden -field to the form, in which case form submission will always fail. You should -use the template tag or :meth:`django.middleware.csrf.get_token` to get -the CSRF token and ensure it is included when your form is submitted. - -Contrib and reusable apps -========================= - -Because it is possible for the developer to turn off the ``CsrfViewMiddleware``, -all relevant views in contrib apps use the ``csrf_protect`` decorator to ensure -the security of these applications against CSRF. It is recommended that the -developers of other reusable apps that want the same guarantees also use the -``csrf_protect`` decorator on their views. diff --git a/parts/django/docs/ref/contrib/databrowse.txt b/parts/django/docs/ref/contrib/databrowse.txt deleted file mode 100644 index 33c8228..0000000 --- a/parts/django/docs/ref/contrib/databrowse.txt +++ /dev/null @@ -1,90 +0,0 @@ -========== -Databrowse -========== - -.. module:: django.contrib.databrowse - :synopsis: Databrowse is a Django application that lets you browse your data. - -Databrowse is a Django application that lets you browse your data. - -As the Django admin dynamically creates an admin interface by introspecting -your models, Databrowse dynamically creates a rich, browsable Web site by -introspecting your models. - -.. admonition:: Note - - Databrowse is **very** new and is currently under active development. It - may change substantially before the next Django release. - - With that said, it's easy to use, and it doesn't require writing any - code. So you can play around with it today, with very little investment in - time or coding. - -How to use Databrowse -===================== - - 1. Point Django at the default Databrowse templates. There are two ways to - do this: - - * Add ``'django.contrib.databrowse'`` to your :setting:`INSTALLED_APPS` - setting. This will work if your :setting:`TEMPLATE_LOADERS` setting - includes the ``app_directories`` template loader (which is the case by - default). See the :ref:`template loader docs <template-loaders>` for - more. - - * Otherwise, determine the full filesystem path to the - :file:`django/contrib/databrowse/templates` directory, and add that - directory to your :setting:`TEMPLATE_DIRS` setting. - - 2. Register a number of models with the Databrowse site:: - - from django.contrib import databrowse - from myapp.models import SomeModel, SomeOtherModel - - databrowse.site.register(SomeModel) - databrowse.site.register(SomeOtherModel) - - Note that you should register the model *classes*, not instances. - - It doesn't matter where you put this, as long as it gets executed at some - point. A good place for it is in your :doc:`URLconf file - </topics/http/urls>` (``urls.py``). - - 3. Change your URLconf to import the :mod:`~django.contrib.databrowse` module:: - - from django.contrib import databrowse - - ...and add the following line to your URLconf:: - - (r'^databrowse/(.*)', databrowse.site.root), - - The prefix doesn't matter -- you can use ``databrowse/`` or ``db/`` or - whatever you'd like. - - 4. Run the Django server and visit ``/databrowse/`` in your browser. - -Requiring user login -==================== - -You can restrict access to logged-in users with only a few extra lines of -code. Simply add the following import to your URLconf:: - - from django.contrib.auth.decorators import login_required - -Then modify the :doc:`URLconf </topics/http/urls>` so that the -:func:`databrowse.site.root` view is decorated with -:func:`django.contrib.auth.decorators.login_required`:: - - (r'^databrowse/(.*)', login_required(databrowse.site.root)), - -If you haven't already added support for user logins to your :doc:`URLconf -</topics/http/urls>`, as described in the :doc:`user authentication docs -</ref/contrib/auth>`, then you will need to do so now with the following -mapping:: - - (r'^accounts/login/$', 'django.contrib.auth.views.login'), - -The final step is to create the login form required by -:func:`django.contrib.auth.views.login`. The -:doc:`user authentication docs </ref/contrib/auth>` provide full details and a -sample template that can be used for this purpose. diff --git a/parts/django/docs/ref/contrib/flatpages.txt b/parts/django/docs/ref/contrib/flatpages.txt deleted file mode 100644 index 46b28dc..0000000 --- a/parts/django/docs/ref/contrib/flatpages.txt +++ /dev/null @@ -1,167 +0,0 @@ -================= -The flatpages app -================= - -.. module:: django.contrib.flatpages - :synopsis: A framework for managing simple ?flat? HTML content in a database. - -Django comes with an optional "flatpages" application. It lets you store simple -"flat" HTML content in a database and handles the management for you via -Django's admin interface and a Python API. - -A flatpage is a simple object with a URL, title and content. Use it for -one-off, special-case pages, such as "About" or "Privacy Policy" pages, that -you want to store in a database but for which you don't want to develop a -custom Django application. - -A flatpage can use a custom template or a default, systemwide flatpage -template. It can be associated with one, or multiple, sites. - -.. versionadded:: 1.0 - -The content field may optionally be left blank if you prefer to put your -content in a custom template. - -Here are some examples of flatpages on Django-powered sites: - - * http://www.lawrence.com/about/contact/ - * http://www2.ljworld.com/site/rules/ - -Installation -============ - -To install the flatpages app, follow these steps: - - 1. Install the :mod:`sites framework <django.contrib.sites>` by adding - ``'django.contrib.sites'`` to your :setting:`INSTALLED_APPS` setting, - if it's not already in there. - - Also make sure you've correctly set :setting:`SITE_ID` to the ID of the - site the settings file represents. This will usually be ``1`` (i.e. - ``SITE_ID = 1``, but if you're using the sites framework to manage - multiple sites, it could be the ID of a different site. - - 2. Add ``'django.contrib.flatpages'`` to your :setting:`INSTALLED_APPS` - setting. - - 3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'`` - to your :setting:`MIDDLEWARE_CLASSES` setting. - - 4. Run the command :djadmin:`manage.py syncdb <syncdb>`. - -How it works -============ - -``manage.py syncdb`` creates two tables in your database: ``django_flatpage`` -and ``django_flatpage_sites``. ``django_flatpage`` is a simple lookup table -that simply maps a URL to a title and bunch of text content. -``django_flatpage_sites`` associates a flatpage with a site. - -The :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` -does all of the work. Each time any Django application raises a 404 error, this -middleware checks the flatpages database for the requested URL as a last resort. -Specifically, it checks for a flatpage with the given URL with a site ID that -corresponds to the :setting:`SITE_ID` setting. - -If it finds a match, it follows this algorithm: - - * If the flatpage has a custom template, it loads that template. Otherwise, - it loads the template :file:`flatpages/default.html`. - - * It passes that template a single context variable, :data:`flatpage`, which - is the flatpage object. It uses - :class:`~django.template.context.RequestContext` in rendering the - template. - -If it doesn't find a match, the request continues to be processed as usual. - -The middleware only gets activated for 404s -- not for 500s or responses of any -other status code. - -.. admonition:: Flatpages will not apply view middleware - - Because the ``FlatpageFallbackMiddleware`` is applied only after - URL resolution has failed and produced a 404, the response it - returns will not apply any :ref:`view middleware <view-middleware>` - methods. Only requests which are successfully routed to a view via - normal URL resolution apply view middleware. - -Note that the order of :setting:`MIDDLEWARE_CLASSES` matters. Generally, you can -put :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` at -the end of the list, because it's a last resort. - -For more on middleware, read the :doc:`middleware docs -</topics/http/middleware>`. - -.. admonition:: Ensure that your 404 template works - - Note that the - :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` - only steps in once another view has successfully produced a 404 response. - If another view or middleware class attempts to produce a 404 but ends up - raising an exception instead (such as a ``TemplateDoesNotExist`` - exception if your site does not have an appropriate template to - use for HTTP 404 responses), the response will become an HTTP 500 - ("Internal Server Error") and the - :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` - will not attempt to serve a flat page. - -How to add, change and delete flatpages -======================================= - -Via the admin interface ------------------------ - -If you've activated the automatic Django admin interface, you should see a -"Flatpages" section on the admin index page. Edit flatpages as you edit any -other object in the system. - -Via the Python API ------------------- - -.. class:: models.FlatPage - - Flatpages are represented by a standard - :doc:`Django model </topics/db/models>`, - which lives in `django/contrib/flatpages/models.py`_. You can access - flatpage objects via the :doc:`Django database API </topics/db/queries>`. - -.. _django/contrib/flatpages/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/flatpages/models.py - -Flatpage templates -================== - -By default, flatpages are rendered via the template -:file:`flatpages/default.html`, but you can override that for a -particular flatpage: in the admin, a collapsed fieldset titled -"Advanced options" (clicking will expand it) contains a field for -specifying a template name. If you're creating a flat page via the -Python API you can simply set the template name as the field -``template_name`` on the ``FlatPage`` object. - -Creating the :file:`flatpages/default.html` template is your responsibility; -in your template directory, just create a :file:`flatpages` directory -containing a file :file:`default.html`. - -Flatpage templates are passed a single context variable, :data:`flatpage`, -which is the flatpage object. - -Here's a sample :file:`flatpages/default.html` template: - -.. code-block:: html+django - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" - "http://www.w3.org/TR/REC-html40/loose.dtd"> - <html> - <head> - <title>{{ flatpage.title }}</title> - </head> - <body> - {{ flatpage.content }} - </body> - </html> - -Since you're already entering raw HTML into the admin page for a flatpage, -both ``flatpage.title`` and ``flatpage.content`` are marked as **not** -requiring :ref:`automatic HTML escaping <automatic-html-escaping>` in the -template. diff --git a/parts/django/docs/ref/contrib/formtools/form-preview.txt b/parts/django/docs/ref/contrib/formtools/form-preview.txt deleted file mode 100644 index a2cbea7..0000000 --- a/parts/django/docs/ref/contrib/formtools/form-preview.txt +++ /dev/null @@ -1,121 +0,0 @@ -============ -Form preview -============ - -.. module:: django.contrib.formtools - :synopsis: Displays an HTML form, forces a preview, then does something - with the submission. - -Django comes with an optional "form preview" application that helps automate -the following workflow: - -"Display an HTML form, force a preview, then do something with the submission." - -To force a preview of a form submission, all you have to do is write a short -Python class. - -Overview -========= - -Given a :class:`django.forms.Form` subclass that you define, this -application takes care of the following workflow: - - 1. Displays the form as HTML on a Web page. - 2. Validates the form data when it's submitted via POST. - a. If it's valid, displays a preview page. - b. If it's not valid, redisplays the form with error messages. - 3. When the "confirmation" form is submitted from the preview page, calls - a hook that you define -- a - :meth:`~django.contrib.formtools.FormPreview.done()` method that gets - passed the valid data. - -The framework enforces the required preview by passing a shared-secret hash to -the preview page via hidden form fields. If somebody tweaks the form parameters -on the preview page, the form submission will fail the hash-comparison test. - -How to use ``FormPreview`` -========================== - - 1. Point Django at the default FormPreview templates. There are two ways to - do this: - - * Add ``'django.contrib.formtools'`` to your - :setting:`INSTALLED_APPS` setting. This will work if your - :setting:`TEMPLATE_LOADERS` setting includes the - ``app_directories`` template loader (which is the case by - default). See the :ref:`template loader docs <template-loaders>` - for more. - - * Otherwise, determine the full filesystem path to the - :file:`django/contrib/formtools/templates` directory, and add that - directory to your :setting:`TEMPLATE_DIRS` setting. - - 2. Create a :class:`~django.contrib.formtools.FormPreview` subclass that - overrides the :meth:`~django.contrib.formtools.FormPreview.done()` - method:: - - from django.contrib.formtools.preview import FormPreview - from myapp.models import SomeModel - - class SomeModelFormPreview(FormPreview): - - def done(self, request, cleaned_data): - # Do something with the cleaned_data, then redirect - # to a "success" page. - return HttpResponseRedirect('/form/success') - - This method takes an :class:`~django.http.HttpRequest` object and a - dictionary of the form data after it has been validated and cleaned. - It should return an :class:`~django.http.HttpResponseRedirect` that - is the end result of the form being submitted. - - 3. Change your URLconf to point to an instance of your - :class:`~django.contrib.formtools.FormPreview` subclass:: - - from myapp.preview import SomeModelFormPreview - from myapp.forms import SomeModelForm - from django import forms - - ...and add the following line to the appropriate model in your URLconf:: - - (r'^post/$', SomeModelFormPreview(SomeModelForm)), - - where ``SomeModelForm`` is a Form or ModelForm class for the model. - - 4. Run the Django server and visit :file:`/post/` in your browser. - -``FormPreview`` classes -======================= - -.. class:: FormPreview - -A :class:`~django.contrib.formtools.FormPreview` class is a simple Python class -that represents the preview workflow. -:class:`~django.contrib.formtools.FormPreview` classes must subclass -``django.contrib.formtools.preview.FormPreview`` and override the -:meth:`~django.contrib.formtools.FormPreview.done()` method. They can live -anywhere in your codebase. - -``FormPreview`` templates -========================= - -By default, the form is rendered via the template :file:`formtools/form.html`, -and the preview page is rendered via the template :file:`formtools/preview.html`. -These values can be overridden for a particular form preview by setting -:attr:`~django.contrib.formtools.FormPreview.preview_template` and -:attr:`~django.contrib.formtools.FormPreview.form_template` attributes on the -FormPreview subclass. See :file:`django/contrib/formtools/templates` for the -default templates. - -Advanced ``FormPreview`` methods -================================ - -.. versionadded:: 1.2 - -.. method:: FormPreview.process_preview - - Given a validated form, performs any extra processing before displaying the - preview page, and saves any extra data in context. - - By default, this method is empty. It is called after the form is validated, - but before the context is modified with hash information and rendered. diff --git a/parts/django/docs/ref/contrib/formtools/form-wizard.txt b/parts/django/docs/ref/contrib/formtools/form-wizard.txt deleted file mode 100644 index 390d575..0000000 --- a/parts/django/docs/ref/contrib/formtools/form-wizard.txt +++ /dev/null @@ -1,312 +0,0 @@ -=========== -Form wizard -=========== - -.. module:: django.contrib.formtools.wizard - :synopsis: Splits forms across multiple Web pages. - -.. versionadded:: 1.0 - -Django comes with an optional "form wizard" application that splits -:doc:`forms </topics/forms/index>` across multiple Web pages. It maintains -state in hashed HTML :samp:`<input type="hidden">` fields, and the data isn't -processed server-side until the final form is submitted. - -You might want to use this if you have a lengthy form that would be too -unwieldy for display on a single page. The first page might ask the user for -core information, the second page might ask for less important information, -etc. - -The term "wizard," in this context, is `explained on Wikipedia`_. - -.. _explained on Wikipedia: http://en.wikipedia.org/wiki/Wizard_%28software%29 -.. _forms: ../forms/ - -How it works -============ - -Here's the basic workflow for how a user would use a wizard: - - 1. The user visits the first page of the wizard, fills in the form and - submits it. - 2. The server validates the data. If it's invalid, the form is displayed - again, with error messages. If it's valid, the server calculates a - secure hash of the data and presents the user with the next form, - saving the validated data and hash in :samp:`<input type="hidden">` - fields. - 3. Step 1 and 2 repeat, for every subsequent form in the wizard. - 4. Once the user has submitted all the forms and all the data has been - validated, the wizard processes the data -- saving it to the database, - sending an e-mail, or whatever the application needs to do. - -Usage -===== - -This application handles as much machinery for you as possible. Generally, you -just have to do these things: - - 1. Define a number of :class:`~django.forms.Form` classes -- one per wizard - page. - - 2. Create a :class:`FormWizard` class that specifies what to do once all of - your forms have been submitted and validated. This also lets you - override some of the wizard's behavior. - - 3. Create some templates that render the forms. You can define a single, - generic template to handle every one of the forms, or you can define a - specific template for each form. - - 4. Point your URLconf at your :class:`FormWizard` class. - -Defining ``Form`` classes -========================= - -The first step in creating a form wizard is to create the -:class:`~django.forms.Form` classes. These should be standard -:class:`django.forms.Form` classes, covered in the :doc:`forms documentation -</topics/forms/index>`. These classes can live anywhere in your codebase, but -convention is to put them in a file called :file:`forms.py` in your -application. - -For example, let's write a "contact form" wizard, where the first page's form -collects the sender's e-mail address and subject, and the second page collects -the message itself. Here's what the :file:`forms.py` might look like:: - - from django import forms - - class ContactForm1(forms.Form): - subject = forms.CharField(max_length=100) - sender = forms.EmailField() - - class ContactForm2(forms.Form): - message = forms.CharField(widget=forms.Textarea) - -**Important limitation:** Because the wizard uses HTML hidden fields to store -data between pages, you may not include a :class:`~django.forms.FileField` -in any form except the last one. - -Creating a ``FormWizard`` class -=============================== - -The next step is to create a -:class:`django.contrib.formtools.wizard.FormWizard` subclass. As with your -:class:`~django.forms.Form` classes, this :class:`FormWizard` class can live -anywhere in your codebase, but convention is to put it in :file:`forms.py`. - -The only requirement on this subclass is that it implement a -:meth:`~FormWizard.done()` method. - -.. method:: FormWizard.done - - This method specifies what should happen when the data for *every* form is - submitted and validated. This method is passed two arguments: - - * ``request`` -- an :class:`~django.http.HttpRequest` object - * ``form_list`` -- a list of :class:`~django.forms.Form` classes - -In this simplistic example, rather than perform any database operation, the -method simply renders a template of the validated data:: - - from django.shortcuts import render_to_response - from django.contrib.formtools.wizard import FormWizard - - class ContactWizard(FormWizard): - def done(self, request, form_list): - return render_to_response('done.html', { - 'form_data': [form.cleaned_data for form in form_list], - }) - -Note that this method will be called via ``POST``, so it really ought to be a -good Web citizen and redirect after processing the data. Here's another -example:: - - from django.http import HttpResponseRedirect - from django.contrib.formtools.wizard import FormWizard - - class ContactWizard(FormWizard): - def done(self, request, form_list): - do_something_with_the_form_data(form_list) - return HttpResponseRedirect('/page-to-redirect-to-when-done/') - -See the section `Advanced FormWizard methods`_ below to learn about more -:class:`FormWizard` hooks. - -Creating templates for the forms -================================ - -Next, you'll need to create a template that renders the wizard's forms. By -default, every form uses a template called :file:`forms/wizard.html`. (You can -change this template name by overriding :meth:`~FormWizard.get_template()`, -which is documented below. This hook also allows you to use a different -template for each form.) - -This template expects the following context: - - * ``step_field`` -- The name of the hidden field containing the step. - * ``step0`` -- The current step (zero-based). - * ``step`` -- The current step (one-based). - * ``step_count`` -- The total number of steps. - * ``form`` -- The :class:`~django.forms.Form` instance for the current step - (either empty or with errors). - * ``previous_fields`` -- A string representing every previous data field, - plus hashes for completed forms, all in the form of hidden fields. Note - that you'll need to run this through the :tfilter:`safe` template filter, - to prevent auto-escaping, because it's raw HTML. - -You can supply extra context to this template in two ways: - - * Set the :attr:`~FormWizard.extra_context` attribute on your - :class:`FormWizard` subclass to a dictionary. - - * Pass a dictionary as a parameter named ``extra_context`` to your wizard's - URL pattern in your URLconf. See :ref:`hooking-wizard-into-urlconf`. - -Here's a full example template: - -.. code-block:: html+django - - {% extends "base.html" %} - - {% block content %} - <p>Step {{ step }} of {{ step_count }}</p> - <form action="." method="post">{% csrf_token %} - <table> - {{ form }} - </table> - <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" /> - {{ previous_fields|safe }} - <input type="submit"> - </form> - {% endblock %} - -Note that ``previous_fields``, ``step_field`` and ``step0`` are all required -for the wizard to work properly. - -.. _hooking-wizard-into-urlconf: - -Hooking the wizard into a URLconf -================================= - -Finally, we need to specify which forms to use in the wizard, and then -deploy the new :class:`FormWizard` object a URL in ``urls.py``. The -wizard takes a list of your :class:`~django.forms.Form` objects as -arguments when you instantiate the Wizard:: - - from django.conf.urls.defaults import * - from testapp.forms import ContactForm1, ContactForm2, ContactWizard - - urlpatterns = patterns('', - (r'^contact/$', ContactWizard([ContactForm1, ContactForm2])), - ) - -Advanced ``FormWizard`` methods -=============================== - -.. class:: FormWizard - - Aside from the :meth:`~done()` method, :class:`FormWizard` offers a few - advanced method hooks that let you customize how your wizard works. - - Some of these methods take an argument ``step``, which is a zero-based - counter representing the current step of the wizard. (E.g., the first form - is ``0`` and the second form is ``1``.) - -.. method:: FormWizard.prefix_for_step - - Given the step, returns a form prefix to use. By default, this simply uses - the step itself. For more, see the :ref:`form prefix documentation - <form-prefix>`. - - Default implementation:: - - def prefix_for_step(self, step): - return str(step) - -.. method:: FormWizard.render_hash_failure - - Renders a template if the hash check fails. It's rare that you'd need to - override this. - - Default implementation:: - - def render_hash_failure(self, request, step): - return self.render(self.get_form(step), request, step, - context={'wizard_error': - 'We apologize, but your form has expired. Please' - ' continue filling out the form from this page.'}) - -.. method:: FormWizard.security_hash - - Calculates the security hash for the given request object and - :class:`~django.forms.Form` instance. - - By default, this uses an MD5 hash of the form data and your - :setting:`SECRET_KEY` setting. It's rare that somebody would need to - override this. - - Example:: - - def security_hash(self, request, form): - return my_hash_function(request, form) - -.. method:: FormWizard.parse_params - - A hook for saving state from the request object and ``args`` / ``kwargs`` - that were captured from the URL by your URLconf. - - By default, this does nothing. - - Example:: - - def parse_params(self, request, *args, **kwargs): - self.my_state = args[0] - -.. method:: FormWizard.get_template - - Returns the name of the template that should be used for the given step. - - By default, this returns :file:`'forms/wizard.html'`, regardless of step. - - Example:: - - def get_template(self, step): - return 'myapp/wizard_%s.html' % step - - If :meth:`~FormWizard.get_template` returns a list of strings, then the - wizard will use the template system's - :func:`~django.template.loader.select_template` function. - This means the system will use the first template that exists on the - filesystem. For example:: - - def get_template(self, step): - return ['myapp/wizard_%s.html' % step, 'myapp/wizard.html'] - -.. method:: FormWizard.render_template - - Renders the template for the given step, returning an - :class:`~django.http.HttpResponse` object. - - Override this method if you want to add a custom context, return a - different MIME type, etc. If you only need to override the template name, - use :meth:`~FormWizard.get_template` instead. - - The template will be rendered with the context documented in the - "Creating templates for the forms" section above. - -.. method:: FormWizard.process_step - - Hook for modifying the wizard's internal state, given a fully validated - :class:`~django.forms.Form` object. The Form is guaranteed to have clean, - valid data. - - This method should *not* modify any of that data. Rather, it might want to - set ``self.extra_context`` or dynamically alter ``self.form_list``, based - on previously submitted forms. - - Note that this method is called every time a page is rendered for *all* - submitted steps. - - The function signature:: - - def process_step(self, request, form, step): - # ... diff --git a/parts/django/docs/ref/contrib/formtools/index.txt b/parts/django/docs/ref/contrib/formtools/index.txt deleted file mode 100644 index f364706..0000000 --- a/parts/django/docs/ref/contrib/formtools/index.txt +++ /dev/null @@ -1,10 +0,0 @@ -django.contrib.formtools -======================== - -A set of high-level abstractions for Django forms (:mod:`django.forms`). - -.. toctree:: - :maxdepth: 1 - - form-preview - form-wizard diff --git a/parts/django/docs/ref/contrib/gis/admin.txt b/parts/django/docs/ref/contrib/gis/admin.txt deleted file mode 100644 index 011bb6b..0000000 --- a/parts/django/docs/ref/contrib/gis/admin.txt +++ /dev/null @@ -1,72 +0,0 @@ -.. _ref-gis-admin: - -====================== -GeoDjango's admin site -====================== - -.. module:: django.contrib.gis.admin - :synopsis: GeoDjango's extensions to the admin site. - - -``GeoModelAdmin`` -================= - -.. class:: GeoModelAdmin - - .. attribute:: default_lon - - The default center longitude. - - .. attribute:: default_lat - - The default center latitude. - - .. attribute:: default_zoom - - The default zoom level to use. Defaults to 18. - - .. attribute:: extra_js - - Sequence of URLs to any extra JavaScript to include. - - .. attribute:: map_template - - Override the template used to generate the JavaScript slippy map. - Default is ``'gis/admin/openlayers.html'``. - - .. attribute:: map_width - - Width of the map, in pixels. Defaults to 600. - - .. attribute:: map_height - - Height of the map, in pixels. Defaults to 400. - - .. attribute:: openlayers_url - - Link to the URL of the OpenLayers JavaScript. Defaults to - ``'http://openlayers.org/api/2.8/OpenLayers.js'``. - - - .. attribute:: modifiable - - Defaults to ``False``. When set to to ``True``, disables editing of - existing geometry fields in the admin. - - .. note:: - - This is different from adding the geometry field to - :attr:`~django.contrib.admin.ModelAdmin.readonly_fields`, - which will only display the WKT of the geometry. Setting - ``modifiable=False``, actually displays the geometry in a map, - but disables the ability to edit its vertices. - -``OSMGeoAdmin`` -=============== - -.. class:: OSMGeoAdmin - - A subclass of :class:`GeoModelAdmin` that uses a spherical mercator projection - with `OpenStreetMap <http://openstreetmap.org/>`_ street data tiles. - See the :ref:`OSMGeoAdmin introduction <osmgeoadmin-intro>` - in the tutorial for a usage example. diff --git a/parts/django/docs/ref/contrib/gis/commands.txt b/parts/django/docs/ref/contrib/gis/commands.txt deleted file mode 100644 index 3dd161c..0000000 --- a/parts/django/docs/ref/contrib/gis/commands.txt +++ /dev/null @@ -1,83 +0,0 @@ -.. ref-geodjango-admin: - -============================= -GeoDjango Management Commands -============================= - -inspectdb -========= - -.. describe:: django-admin.py inspectdb - -When :mod:`django.contrib.gis` is in your :setting:`INSTALLED_APPS`, the -:djadmin:`inspectdb` management command is overridden with one from GeoDjango. -The overridden command is spatially-aware, and places geometry fields in the -auto-generated model definition, where appropriate. - -ogrinspect <data_source> <model_name> -===================================== - -.. django-admin:: ogrinspect - -The ``ogrinpsect`` management command will inspect the given OGR-compatible -:class:`~django.contrib.gis.gdal.DataSource` (e.g., a shapefile) and will -output a GeoDjango model with the given model name. There's a detailed example -of using ``ogrinspect`` :ref:`in the tutorial <ogrinspect-intro>`. - -.. django-admin-option:: --blank <blank_field(s)> - - Use a comma separated list of OGR field names to add the ``blank=True`` - keyword option to the field definition. Set with ``true`` to apply - to all applicable fields. - -.. django-admin-option:: --decimal <decimal_field(s)> - - Use a comma separated list of OGR float fields to generate - :class:`~django.db.models.DecimalField` instead of the default - :class:`~django.db.models.FloatField`. Set to ``true`` to apply to all - OGR float fields. - -.. django-admin-option:: --geom-name <name> - - Specifies the model attribute name to use for the geometry field. - Defaults to ``'geom'``. - -.. django-admin-option:: --layer <layer> - - The key for specifying which layer in the OGR - :class:`~django.contrib.gis.gdal.DataSource` source to use. - Defaults to 0 (the first layer). May be an integer or a string identifier - for the :class:`~django.contrib.gis.gdal.Layer`. - -.. django-admin-option:: --mapping - - Automatically generate a mapping dictionary for use with - :class:`~django.contrib.gis.utils.LayerMapping`. - -.. django-admin-option:: --multi-geom - - When generating the geometry field, treat it as a geometry collection. - For example, if this setting is enabled then a - :class:`~django.contrib.gis.db.models.MultiPolygonField` will be placed - in the generated model rather than - :class:`~django.contrib.gis.db.models.PolygonField`. - -.. django-admin-option:: --name-field <name_field> - - Generates a ``__unicode__`` routine on the model that will return the - the given field name. - -.. django-admin-option:: --no-imports - - Suppresses the ``from django.contrib.gis.db import models`` import statement. - -.. django-admin-option:: --null <null_field(s)> - - Use a comma separated list of OGR field names to add the ``null=True`` - keyword option to the field definition. Set with ``true`` to apply to - all applicable fields. - -.. django-admin-option:: --srid - - The SRID to use for the geometry field. If not set, ``ogrinspect`` attempts - to automatically determine of the SRID of the data source. diff --git a/parts/django/docs/ref/contrib/gis/create_template_postgis-1.3.sh b/parts/django/docs/ref/contrib/gis/create_template_postgis-1.3.sh deleted file mode 100755 index c9ab4fc..0000000 --- a/parts/django/docs/ref/contrib/gis/create_template_postgis-1.3.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -POSTGIS_SQL_PATH=`pg_config --sharedir` -createdb -E UTF8 template_postgis # Create the template spatial database. -createlang -d template_postgis plpgsql # Adding PLPGSQL language support. -psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';" -psql -d template_postgis -f $POSTGIS_SQL_PATH/lwpostgis.sql # Loading the PostGIS SQL routines -psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql -psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" # Enabling users to alter spatial tables. -psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;" diff --git a/parts/django/docs/ref/contrib/gis/create_template_postgis-1.4.sh b/parts/django/docs/ref/contrib/gis/create_template_postgis-1.4.sh deleted file mode 100755 index 57a1373..0000000 --- a/parts/django/docs/ref/contrib/gis/create_template_postgis-1.4.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -POSTGIS_SQL_PATH=`pg_config --sharedir`/contrib -createdb -E UTF8 template_postgis # Create the template spatial database. -createlang -d template_postgis plpgsql # Adding PLPGSQL language support. -psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';" -psql -d template_postgis -f $POSTGIS_SQL_PATH/postgis.sql # Loading the PostGIS SQL routines -psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql -psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" # Enabling users to alter spatial tables. -psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;" diff --git a/parts/django/docs/ref/contrib/gis/create_template_postgis-1.5.sh b/parts/django/docs/ref/contrib/gis/create_template_postgis-1.5.sh deleted file mode 100755 index 081b5f2..0000000 --- a/parts/django/docs/ref/contrib/gis/create_template_postgis-1.5.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -POSTGIS_SQL_PATH=`pg_config --sharedir`/contrib/postgis-1.5 -createdb -E UTF8 template_postgis # Create the template spatial database. -createlang -d template_postgis plpgsql # Adding PLPGSQL language support. -psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';" -psql -d template_postgis -f $POSTGIS_SQL_PATH/postgis.sql # Loading the PostGIS SQL routines -psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql -psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" # Enabling users to alter spatial tables. -psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;" -psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;" diff --git a/parts/django/docs/ref/contrib/gis/create_template_postgis-debian.sh b/parts/django/docs/ref/contrib/gis/create_template_postgis-debian.sh deleted file mode 100755 index 46bd074..0000000 --- a/parts/django/docs/ref/contrib/gis/create_template_postgis-debian.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -POSTGIS_SQL_PATH=/usr/share/postgresql-8.3-postgis -createdb -E UTF8 template_postgis # Create the template spatial database. -createlang -d template_postgis plpgsql # Adding PLPGSQL language support. -psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';" -psql -d template_postgis -f $POSTGIS_SQL_PATH/lwpostgis.sql # Loading the PostGIS SQL routines -psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql -psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" # Enabling users to alter spatial tables. -psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;" diff --git a/parts/django/docs/ref/contrib/gis/db-api.txt b/parts/django/docs/ref/contrib/gis/db-api.txt deleted file mode 100644 index fbced8e..0000000 --- a/parts/django/docs/ref/contrib/gis/db-api.txt +++ /dev/null @@ -1,349 +0,0 @@ -.. _ref-gis-db-api: - -====================== -GeoDjango Database API -====================== - -.. module:: django.contrib.gis.db.models - :synopsis: GeoDjango's database API. - -.. _spatial-backends: - -Spatial Backends -================ - -.. versionadded:: 1.2 - -In Django 1.2, support for :doc:`multiple databases </topics/db/multi-db>` was -introduced. In order to support multiple databases, GeoDjango has segregated -its functionality into full-fledged spatial database backends: - -* :mod:`django.contrib.gis.db.backends.postgis` -* :mod:`django.contrib.gis.db.backends.mysql` -* :mod:`django.contrib.gis.db.backends.oracle` -* :mod:`django.contrib.gis.db.backends.spatialite` - -Database Settings Backwards-Compatibility ------------------------------------------ - -In :doc:`Django 1.2 </releases/1.2>`, the way -to :ref:`specify databases <specifying-databases>` in your settings was changed. -The old database settings format (e.g., the ``DATABASE_*`` settings) -is backwards compatible with GeoDjango, and will automatically use the -appropriate spatial backend as long as :mod:`django.contrib.gis` is in -your :setting:`INSTALLED_APPS`. For example, if you have the following in -your settings:: - - DATABASE_ENGINE='postgresql_psycopg2' - - ... - - INSTALLED_APPS = ( - ... - 'django.contrib.gis', - ... - ) - -Then, :mod:`django.contrib.gis.db.backends.postgis` is automatically used as your -spatial backend. - -.. _mysql-spatial-limitations: - -MySQL Spatial Limitations -------------------------- - -MySQL's spatial extensions only support bounding box operations -(what MySQL calls minimum bounding rectangles, or MBR). Specifically, -`MySQL does not conform to the OGC standard <http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html>`_: - - Currently, MySQL does not implement these functions - [``Contains``, ``Crosses``, ``Disjoint``, ``Intersects``, ``Overlaps``, - ``Touches``, ``Within``] - according to the specification. Those that are implemented return - the same result as the corresponding MBR-based functions. - -In other words, while spatial lookups such as :lookup:`contains <gis-contains>` -are available in GeoDjango when using MySQL, the results returned are really -equivalent to what would be returned when using :lookup:`bbcontains` -on a different spatial backend. - -.. warning:: - - True spatial indexes (R-trees) are only supported with - MyISAM tables on MySQL. [#fnmysqlidx]_ In other words, when using - MySQL spatial extensions you have to choose between fast spatial - lookups and the integrity of your data -- MyISAM tables do - not support transactions or foreign key constraints. - -Creating and Saving Geographic Models -===================================== -Here is an example of how to create a geometry object (assuming the ``Zipcode`` -model):: - - >>> 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:: - - >>> from django.contrib.gis.geos import GEOSGeometry - >>> poly = GEOSGeometry('POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))') - >>> z = Zipcode(code=77096, poly=poly) - >>> z.save() - -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:: - - >>> 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) - >>> z.save() - >>> from django.db import connection - >>> print connection.queries[-1]['sql'] # printing the last SQL statement executed (requires DEBUG=True) - INSERT INTO "geoapp_zipcode" ("code", "poly") VALUES (78212, ST_Transform(ST_GeomFromWKB('\\001 ... ', 3084), 4326)) - -Thus, geometry parameters may be passed in using the ``GEOSGeometry`` object, WKT -(Well Known Text [#fnwkt]_), HEXEWKB (PostGIS specific -- a WKB geometry in -hexadecimal [#fnewkb]_), and GeoJSON [#fngeojson]_ (requires GDAL). Essentially, -if the input is not a ``GEOSGeometry`` object, the geometry field will attempt to -create a ``GEOSGeometry`` instance from the input. - -For more information creating :class:`~django.contrib.gis.geos.GEOSGeometry` -objects, refer to the :ref:`GEOS tutorial <geos-tutorial>`. - -.. _spatial-lookups-intro: - -Spatial Lookups -=============== - -GeoDjango's lookup types may be used with any manager method like -``filter()``, ``exclude()``, etc. However, the lookup types unique to -GeoDjango are only available on geometry fields. -Filters on 'normal' fields (e.g. :class:`~django.db.models.CharField`) -may be chained with those on geographic fields. Thus, geographic queries -take the following general form (assuming the ``Zipcode`` model used in the -:ref:`ref-gis-model-api`):: - - >>> qs = Zipcode.objects.filter(<field>__<lookup_type>=<parameter>) - >>> qs = Zipcode.objects.exclude(...) - -For example:: - - >>> qs = Zipcode.objects.filter(poly__contains=pnt) - -In this case, ``poly`` is the geographic field, :lookup:`contains <gis-contains>` -is the spatial lookup type, and ``pnt`` is the parameter (which may be a -:class:`~django.contrib.gis.geos.GEOSGeometry` object or a string of -GeoJSON , WKT, or HEXEWKB). - -A complete reference can be found in the :ref:`spatial lookup reference -<spatial-lookups>`. - -.. note:: - - GeoDjango constructs spatial SQL with the :class:`GeoQuerySet`, a - subclass of :class:`~django.db.models.QuerySet`. The - :class:`GeoManager` instance attached to your model is what - enables use of :class:`GeoQuerySet`. - -.. _distance-queries: - -Distance Queries -================ - -Introduction ------------- -Distance calculations with spatial data is tricky because, unfortunately, -the Earth is not flat. Some distance queries with fields in a geographic -coordinate system may have to be expressed differently because of -limitations in PostGIS. Please see the :ref:`selecting-an-srid` section -in the :ref:`ref-gis-model-api` documentation for more details. - -.. _distance-lookups-intro: - -Distance Lookups ----------------- -*Availability*: PostGIS, Oracle, SpatiaLite - -The following distance lookups are available: - -* :lookup:`distance_lt` -* :lookup:`distance_lte` -* :lookup:`distance_gt` -* :lookup:`distance_gte` -* :lookup:`dwithin` - -.. note:: - - For *measuring*, rather than querying on distances, use the - :meth:`GeoQuerySet.distance` method. - -Distance lookups take a tuple parameter comprising: - -#. A geometry to base calculations from; and -#. A number or :class:`~django.contrib.gis.measure.Distance` object containing the distance. - -If a :class:`~django.contrib.gis.measure.Distance` object is used, -it may be expressed in any units (the SQL generated will use units -converted to those of the field); otherwise, numeric parameters are assumed -to be in the units of the field. - -.. note:: - - For users of PostGIS 1.4 and below, the routine ``ST_Distance_Sphere`` - is used by default for calculating distances on geographic coordinate systems - (e.g., WGS84) -- which may only be called with point geometries [#fndistsphere14]_. - Thus, geographic distance lookups on traditional PostGIS geometry columns are - only allowed on :class:`PointField` model fields using a point for the - geometry parameter. - -.. note:: - - In PostGIS 1.5, ``ST_Distance_Sphere`` does *not* limit the geometry types - geographic distance queries are performed with. [#fndistsphere15]_ However, - these queries may take a long time, as great-circle distances must be - calculated on the fly for *every* row in the query. This is because the - spatial index on traditional geometry fields cannot be used. - - For much better performance on WGS84 distance queries, consider using - :ref:`geography columns <geography-type>` in your database instead because - they are able to use their spatial index in distance queries. - You can tell GeoDjango to use a geography column by setting ``geography=True`` - in your field definition. - -For example, let's say we have a ``SouthTexasCity`` model (from the -`GeoDjango distance tests`__ ) on a *projected* coordinate system valid for cities -in southern Texas:: - - from django.contrib.gis.db import models - - class SouthTexasCity(models.Model): - name = models.CharField(max_length=30) - # A projected coordinate system (only valid for South Texas!) - # is used, units are in meters. - point = models.PointField(srid=32140) - objects = models.GeoManager() - -Then distance queries may be performed as follows:: - - >>> from django.contrib.gis.geos import * - >>> from django.contrib.gis.measure import D # ``D`` is a shortcut for ``Distance`` - >>> from geoapp import SouthTexasCity - # Distances will be calculated from this point, which does not have to be projected. - >>> pnt = fromstr('POINT(-96.876369 29.905320)', srid=4326) - # If numeric parameter, units of field (meters in this case) are assumed. - >>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, 7000)) - # Find all Cities within 7 km, > 20 miles away, and > 100 chains away (an obscure unit) - >>> qs = SouthTexasCity.objects.filter(point__distance_lte=(pnt, D(km=7))) - >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(mi=20))) - >>> qs = SouthTexasCity.objects.filter(point__distance_gte=(pnt, D(chain=100))) - -__ http://code.djangoproject.com/browser/django/trunk/django/contrib/gis/tests/distapp/models.py - -.. _compatibility-table: - -Compatibility Tables -==================== - -.. _spatial-lookup-compatibility: - -Spatial Lookups ---------------- - -The following table provides a summary of what spatial lookups are available -for each spatial database backend. - -================================= ========= ======== ============ ========== -Lookup Type PostGIS Oracle MySQL [#]_ SpatiaLite -================================= ========= ======== ============ ========== -:lookup:`bbcontains` X X X -:lookup:`bboverlaps` X X X -:lookup:`contained` X X X -:lookup:`contains <gis-contains>` X X X X -:lookup:`contains_properly` X -:lookup:`coveredby` X X -:lookup:`covers` X X -:lookup:`crosses` X X -:lookup:`disjoint` X X X X -:lookup:`distance_gt` X X X -:lookup:`distance_gte` X X X -:lookup:`distance_lt` X X X -:lookup:`distance_lte` X X X -:lookup:`dwithin` X X -:lookup:`equals` X X X X -:lookup:`exact` X X X X -:lookup:`intersects` X X X X -:lookup:`overlaps` X X X X -:lookup:`relate` X X X -:lookup:`same_as` X X X X -:lookup:`touches` X X X X -:lookup:`within` X X X X -:lookup:`left` X -:lookup:`right` X -:lookup:`overlaps_left` X -:lookup:`overlaps_right` X -:lookup:`overlaps_above` X -:lookup:`overlaps_below` X -:lookup:`strictly_above` X -:lookup:`strictly_below` X -================================= ========= ======== ============ ========== - -.. _geoqueryset-method-compatibility: - -``GeoQuerySet`` Methods ------------------------ -The following table provides a summary of what :class:`GeoQuerySet` methods -are available on each spatial backend. Please note that MySQL does not -support any of these methods, and is thus excluded from the table. - -==================================== ======= ====== ========== -Method PostGIS Oracle SpatiaLite -==================================== ======= ====== ========== -:meth:`GeoQuerySet.area` X X X -:meth:`GeoQuerySet.centroid` X X X -:meth:`GeoQuerySet.collect` X -:meth:`GeoQuerySet.difference` X X X -:meth:`GeoQuerySet.distance` X X X -:meth:`GeoQuerySet.envelope` X X -:meth:`GeoQuerySet.extent` X X -:meth:`GeoQuerySet.extent3d` X -:meth:`GeoQuerySet.force_rhr` X -:meth:`GeoQuerySet.geohash` X -:meth:`GeoQuerySet.geojson` X -:meth:`GeoQuerySet.gml` X X -:meth:`GeoQuerySet.intersection` X X X -:meth:`GeoQuerySet.kml` X -:meth:`GeoQuerySet.length` X X X -:meth:`GeoQuerySet.make_line` X -:meth:`GeoQuerySet.mem_size` X -:meth:`GeoQuerySet.num_geom` X X X -:meth:`GeoQuerySet.num_points` X X X -:meth:`GeoQuerySet.perimeter` X X -:meth:`GeoQuerySet.point_on_surface` X X X -:meth:`GeoQuerySet.reverse_geom` X X -:meth:`GeoQuerySet.scale` X X -:meth:`GeoQuerySet.snap_to_grid` X -:meth:`GeoQuerySet.svg` X X -:meth:`GeoQuerySet.sym_difference` X X X -:meth:`GeoQuerySet.transform` X X X -:meth:`GeoQuerySet.translate` X X -:meth:`GeoQuerySet.union` X X X -:meth:`GeoQuerySet.unionagg` X X X -==================================== ======= ====== ========== - -.. rubric:: Footnotes -.. [#fnwkt] *See* Open Geospatial Consortium, Inc., `OpenGIS Simple Feature Specification For SQL <http://www.opengis.org/docs/99-049.pdf>`_, Document 99-049 (May 5, 1999), at Ch. 3.2.5, p. 3-11 (SQL Textual Representation of Geometry). -.. [#fnewkb] *See* `PostGIS EWKB, EWKT and Canonical Forms <http://postgis.refractions.net/documentation/manual-1.5/ch04.html#EWKB_EWKT>`_, PostGIS documentation at Ch. 4.1.2. -.. [#fngeojson] *See* Howard Butler, Martin Daly, Allan Doyle, Tim Schaub, & Christopher Schmidt, `The GeoJSON Format Specification <http://geojson.org/geojson-spec.html>`_, Revision 1.0 (June 16, 2008). -.. [#fndistsphere14] *See* `PostGIS 1.4 documentation <http://postgis.refractions.net/documentation/manual-1.4/ST_Distance_Sphere.html>`_ on ``ST_distance_sphere``. -.. [#fndistsphere15] *See* `PostGIS 1.5 documentation <http://postgis.refractions.net/documentation/manual-1.5/ST_Distance_Sphere.html>`_ on ``ST_distance_sphere``. -.. [#fnmysqlidx] *See* `Creating Spatial Indexes <http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-indexes.html>`_ - in the MySQL 5.1 Reference Manual: - - For MyISAM tables, ``SPATIAL INDEX`` creates an R-tree index. For storage - engines that support nonspatial indexing of spatial columns, the engine - creates a B-tree index. A B-tree index on spatial values will be useful - for exact-value lookups, but not for range scans. - -.. [#] Refer :ref:`mysql-spatial-limitations` section for more details. diff --git a/parts/django/docs/ref/contrib/gis/deployment.txt b/parts/django/docs/ref/contrib/gis/deployment.txt deleted file mode 100644 index 035b23f..0000000 --- a/parts/django/docs/ref/contrib/gis/deployment.txt +++ /dev/null @@ -1,99 +0,0 @@ -=================== -Deploying GeoDjango -=================== - -.. warning:: - - GeoDjango uses the GDAL geospatial library which is - not thread safe at this time. Thus, it is *highly* recommended - to not use threading when deploying -- in other words, use a - an appropriate configuration of Apache or the prefork method - when using FastCGI through another Web server. - -Apache -====== -In this section there are some example ``VirtualHost`` directives for -when deploying using either ``mod_python`` or ``mod_wsgi``. At this -time, we recommend ``mod_wsgi``, as it is now officially recommended -way to deploy Django applications with Apache. Moreover, if -``mod_python`` is used, then a prefork version of Apache must also be -used. As long as ``mod_wsgi`` is configured correctly, it does not -matter whether the version of Apache is prefork or worker. - -.. note:: - - The ``Alias`` and ``Directory`` configurations in the the examples - below use an example path to a system-wide installation folder of Django. - Substitute in an appropriate location, if necessary, as it may be - different than the path on your system. - -``mod_wsgi`` ------------- - -Example:: - - <VirtualHost *:80> - WSGIDaemonProcess geodjango user=geo group=geo processes=5 threads=1 - WSGIProcessGroup geodjango - WSGIScriptAlias / /home/geo/geodjango/world.wsgi - - Alias /media/ "/usr/lib/python2.5/site-packages/django/contrib/admin/media/" - <Directory "/usr/lib/python2.5/site-packages/django/contrib/admin/media/"> - Order allow,deny - Options Indexes - Allow from all - IndexOptions FancyIndexing - </Directory> - - </VirtualHost> - -.. warning:: - - If the ``WSGIDaemonProcess`` attribute ``threads`` is not set to ``1``, then - Apache may crash when running your GeoDjango application. Increase the - number of ``processes`` instead. - -For more information, please consult Django's -:doc:`mod_wsgi documentation </howto/deployment/modwsgi>`. - -``mod_python`` --------------- - -Example:: - - <VirtualHost *:80> - - <Location "/"> - SetHandler mod_python - PythonHandler django.core.handlers.modpython - SetEnv DJANGO_SETTINGS_MODULE world.settings - PythonDebug On - PythonPath "['/var/www/apps'] + sys.path" - </Location> - - Alias /media/ "/usr/lib/python2.5/site-packages/django/contrib/admin/media/" - <Location "/media"> - SetHandler None - </Location> - - </VirtualHost> - -.. warning:: - - When using ``mod_python`` you *must* be using a prefork version of Apache, or - else your GeoDjango application may crash Apache. - -For more information, please consult Django's -:doc:`mod_python documentation </howto/deployment/modpython>`. - -Lighttpd -======== - -FastCGI -------- - -Nginx -===== - -FastCGI -------- diff --git a/parts/django/docs/ref/contrib/gis/feeds.txt b/parts/django/docs/ref/contrib/gis/feeds.txt deleted file mode 100644 index 7c3a2d0..0000000 --- a/parts/django/docs/ref/contrib/gis/feeds.txt +++ /dev/null @@ -1,95 +0,0 @@ -================ -Geographic Feeds -================ - -.. module:: django.contrib.gis.feeds - :synopsis: GeoDjango's framework for generating spatial feeds. - -GeoDjango has its own :class:`Feed` subclass that may embed location information -in RSS/Atom feeds formatted according to either the `Simple GeoRSS`__ or -`W3C Geo`_ standards. Because GeoDjango's syndication API is a superset of -Django's, please consult :doc:`Django's syndication documentation -</ref/contrib/syndication>` for details on general usage. - -.. _W3C Geo: http://www.w3.org/2003/01/geo/ - -__ http://georss.org/1.0#simple - -Example -======= - -API Reference -============= - -``Feed`` Subclass ------------------ - -.. class:: Feed - - In addition to methods provided by - the :class:`django.contrib.syndication.feeds.Feed` - base class, GeoDjango's ``Feed`` class provides - the following overrides. Note that these overrides may be done in multiple ways:: - - from django.contrib.gis.feeds import Feed - - class MyFeed(Feed): - - # First, as a class attribute. - geometry = ... - item_geometry = ... - - # Also a function with no arguments - def geometry(self): - ... - - def item_geometry(self): - ... - - # And as a function with a single argument - def geometry(self, obj): - ... - - def item_geometry(self, item): - ... - - .. method:: geometry(obj) - - Takes the object returned by ``get_object()`` and returns the *feed's* - geometry. Typically this is a ``GEOSGeometry`` instance, or can be a - tuple to represent a point or a box. For example:: - - class ZipcodeFeed(Feed): - - def geometry(self, obj): - # Can also return: `obj.poly`, and `obj.poly.centroid`. - return obj.poly.extent # tuple like: (X0, Y0, X1, Y1). - - .. method:: item_geometry(item) - - Set this to return the geometry for each *item* in the feed. This - can be a ``GEOSGeometry`` instance, or a tuple that represents a - point coordinate or bounding box. For example:: - - class ZipcodeFeed(Feed): - - def item_geometry(self, obj): - # Returns the polygon. - return obj.poly - -``SyndicationFeed`` Subclasses ------------------------------- - -The following :class:`django.utils.feedgenerator.SyndicationFeed` subclasses -are available: - -.. class:: GeoRSSFeed - -.. class:: GeoAtom1Feed - -.. class:: W3CGeoFeed - -.. note:: - - `W3C Geo`_ formatted feeds only support - :class:`~django.contrib.gis.db.models.PointField` geometries. diff --git a/parts/django/docs/ref/contrib/gis/gdal.txt b/parts/django/docs/ref/contrib/gis/gdal.txt deleted file mode 100644 index 1ce21d9..0000000 --- a/parts/django/docs/ref/contrib/gis/gdal.txt +++ /dev/null @@ -1,1114 +0,0 @@ -.. _ref-gdal: - -======== -GDAL API -======== - -.. module:: django.contrib.gis.gdal - :synopsis: GeoDjango's high-level interface to the GDAL library. - -`GDAL`__ stands for **G**\ eospatial **D**\ ata **A**\ bstraction **L**\ ibrary, -and is a veritable "swiss army knife" of GIS data functionality. A subset -of GDAL is the `OGR`__ Simple Features Library, which specializes -in reading and writing vector geographic data in a variety of standard -formats. - -GeoDjango provides a high-level Python interface for some of the -capabilities of OGR, including the reading and coordinate transformation -of vector spatial data. - -.. note:: - - Although the module is named ``gdal``, GeoDjango only supports - some of the capabilities of OGR. Thus, none of GDAL's features - with respect to raster (image) data are supported at this time. - -__ http://www.gdal.org/ -__ http://www.gdal.org/ogr/ - -Overview -======== - -Sample Data ------------ - -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 comes with a number of -simple data sets that you can use for testing. This snippet will -determine where these sample files are installed on your computer:: - - >>> import os - >>> import django.contrib.gis - >>> GIS_PATH = os.path.dirname(django.contrib.gis.__file__) - >>> CITIES_PATH = os.path.join(GIS_PATH, 'tests/data/cities/cities.shp') - -Vector Data Source Objects -========================== - -``DataSource`` --------------- - -:class:`DataSource` is a wrapper for the OGR data source object that -supports reading data from a variety of OGR-supported geospatial file -formats and data sources using a simple, consistent interface. Each -data source is represented by a :class:`DataSource` object which contains -one or more layers of data. Each layer, represented by a :class:`Layer` -object, contains some number of geographic features (:class:`Feature`), -information about the type of features contained in that layer (e.g. -points, polygons, etc.), as well as the names and types of any -additional fields (:class:`Field`) of data that may be associated with -each feature in that layer. - -.. class:: DataSource(ds_input) - - The constructor for ``DataSource`` just a single parameter: the path of - the file you want to read. However, OGR - also supports a variety of more complex data sources, including - databases, that may be accessed by passing a special name string instead - of a path. For more information, see the `OGR Vector Formats`__ - documentation. The :attr:`name` property of a ``DataSource`` - instance gives the OGR name of the underlying data source that it is - using. - - 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:: - - >>> from django.contrib.gis.gdal import DataSource - >>> ds = DataSource(CITIES_PATH) - >>> ds.name # The exact filename may be different on your computer - '/usr/local/lib/python2.6/site-packages/django/contrib/gis/tests/data/cities/cities.shp' - >>> ds.layer_count # This file only contains one layer - 1 - - .. attribute:: layer_count - - Returns the number of layers in the data source. - - .. attribute:: name - - Returns the name of the data source. - -__ http://www.gdal.org/ogr/ogr_formats.html - -``Layer`` ---------- - -.. class:: Layer - - ``Layer`` is a wrapper for a layer of data in a ``DataSource`` object. - You never create a ``Layer`` object directly. Instead, you retrieve - them from a :class:`DataSource` object, which is essentially a standard - Python container of ``Layer`` objects. For example, you can access a - specific layer by its index (e.g. ``ds[0]`` to access the first - layer), or you can iterate over all the layers in the container in a - ``for`` loop. The ``Layer`` itself acts as a container for geometric - features. - - 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`:: - - >>> for layer in ds: - ... print 'Layer "%s": %i %ss' % (layer.name, len(layer), layer.geom_type.name) - ... - Layer "cities": 3 Points - - 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``:: - - >>> layer = ds[0] - - .. attribute:: name - - Returns the name of this layer in the data source. - - >>> layer.name - 'cities' - - .. attribute:: num_feat - - Returns the number of features in the layer. Same as ``len(layer)``:: - - >>> layer.num_feat - 3 - - .. attribute:: geom_type - - Returns the geometry type of the layer, as an :class:`OGRGeomType` - object:: - - >>> layer.geom_type.name - 'Point' - - .. 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:: - - >>> layer.num_fields - 4 - - .. attribute:: fields - - Returns a list of the names of each of the fields in this layer:: - - >>> layer.fields - ['Name', 'Population', 'Density', 'Created'] - - .. 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:: - - >>> [ft.__name__ for ft in layer.field_types] - ['OFTString', 'OFTReal', 'OFTReal', 'OFTDate'] - - .. attribute:: field_widths - - Returns a list of the maximum field widths for each of the fields in - this layer:: - - >>> layer.field_widths - [80, 11, 24, 10] - - .. 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.field_precisions - [0, 0, 15, 0] - - .. attribute:: extent - - Returns the spatial extent of this layer, as an :class:`Envelope` - object:: - - >>> layer.extent.tuple - (-104.609252, 29.763374, -95.23506, 38.971823) - - .. attribute:: srs - - Property that returns the :class:`SpatialReference` associated - with this layer:: - - >>> print layer.srs - GEOGCS["GCS_WGS_1984", - DATUM["WGS_1984", - SPHEROID["WGS_1984",6378137,298.257223563]], - PRIMEM["Greenwich",0], - UNIT["Degree",0.017453292519943295]] - - If the :class:`Layer` has no spatial reference information associated - with it, ``None`` is returned. - - .. attribute:: spatial_filter - - .. versionadded:: 1.2 - - Property that may be used to retrieve or set a spatial filter for this - 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:: - - >>> print layer.spatial_filter - None - >>> print len(layer) - 3 - >>> [feat.get('Name') for feat in layer] - ['Pueblo', 'Lawrence', 'Houston'] - >>> ks_extent = (-102.051, 36.99, -94.59, 40.00) # Extent for state of Kansas - >>> layer.spatial_filter = ks_extent - >>> len(layer) - 1 - >>> [feat.get('Name') for feat in layer] - ['Lawrence'] - >>> layer.spatial_filter = None - >>> len(layer) - 3 - - .. method:: get_fields() - - A method that returns a list of the values of a given field for each - feature in the layer:: - - >>> layer.get_fields('Name') - ['Pueblo', 'Lawrence', 'Houston'] - - .. method:: get_geoms([geos=False]) - - 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:: - - >>> [pt.tuple for pt in layer.get_geoms()] - [(-104.609252, 38.255001), (-95.23506, 38.971823), (-95.363151, 29.763374)] - - .. method:: test_capability(capability) - - Returns a boolean indicating whether this layer supports the - given capability (a string). Examples of valid capability strings - include: ``'RandomRead'``, ``'SequentialWrite'``, ``'RandomWrite'``, - ``'FastSpatialFilter'``, ``'FastFeatureCount'``, ``'FastGetExtent'``, - ``'CreateField'``, ``'Transactions'``, ``'DeleteFeature'``, and - ``'FastSetNextByIndex'``. - -``Feature`` ------------ - -.. class:: Feature - - - ``Feature`` wraps an OGR feature. You never create a ``Feature`` - object directly. Instead, you retrieve them from a :class:`Layer` object. - Each feature consists of a geometry and a set of fields containing - additional properties. The geometry of a field is accessible via its - ``geom`` property, which returns an :class:`OGRGeometry` object. A ``Feature`` - behaves like a standard Python container for its fields, which it returns as - :class:`Field` objects: you can access a field directly by its index or name, - or you can iterate over a feature's fields, e.g. in a ``for`` loop. - - .. attribute:: geom - - Returns the geometry for this feature, as an ``OGRGeometry`` object:: - - >>> city.geom.tuple - (-104.609252, 38.255001) - - .. attribute:: get - - A method that returns the value of the given field (specified by name) - for this feature, **not** a ``Field`` wrapper object:: - - >>> city.get('Population') - 102121 - - .. attribute:: geom_type - - Returns the type of geometry for this feature, as an :class:`OGRGeomType` - object. This will be the same for all features in a given layer, and - is equivalent to the :attr:`Layer.geom_type` property of the - :class:`Layer`` object the feature came from. - - .. attribute:: num_fields - - Returns the number of fields of data associated with the feature. - This will be the same for all features in a given layer, and is - equivalent to the :attr:`Layer.num_fields` property of the - :class:`Layer` object the feature came from. - - .. attribute:: fields - - Returns a list of the names of the fields of data associated with the - feature. This will be the same for all features in a given layer, and - is equivalent to the :attr:`Layer.fields` property of the :class:`Layer` - object the feature came from. - - .. attribute:: fid - - Returns the feature identifier within the layer:: - - >>> city.fid - 0 - - .. 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:: - - >>> city.layer_name - 'cities' - - .. 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:: - - >>> city.index('Population') - 1 - -``Field`` ---------- - -.. class:: Field - - .. attribute:: name - - Returns the name of this field:: - - >>> city['Name'].name - 'Name' - - .. attribute:: type - - Returns the OGR type of this field, as an integer. The - ``FIELD_CLASSES`` dictionary maps these values onto - subclasses of ``Field``:: - - >>> city['Density'].type - 2 - - .. attribute:: type_name - - Returns a string with the name of the data type of this field:: - - >>> city['Name'].type_name - 'String' - - .. attribute:: value - - 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:: - - >>> city['Population'].value - 102121 - - .. attribute:: width - - Returns the width of this field:: - - >>> city['Name'].width - 80 - - .. attribute:: precision - - Returns the numeric precision of this field. This is meaningless (and - set to zero) for non-numeric fields:: - - >>> city['Density'].precision - 15 - - .. method:: as_double() - - Returns the value of the field as a double (float):: - - >>> city['Density'].as_double() - 874.7 - - .. method:: as_int() - - Returns the value of the field as an integer:: - - >>> city['Population'].as_int() - 102121 - - .. method:: as_string() - - Returns the value of the field as a string:: - - >>> city['Name'].as_string() - 'Pueblo' - - .. method:: as_datetime() - - Returns the value of the field as a tuple of date and time components:: - - >>> 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)) - -``Driver`` ----------- - -.. class:: Driver(dr_input) - - The ``Driver`` class is used internally to wrap an OGR :class:`DataSource` driver. - - .. attribute:: driver_count - - Returns the number of OGR vector drivers currently registered. - - -OGR Geometries -============== - -``OGRGeometry`` ---------------- - -:class:`OGRGeometry` objects share similar functionality with -:class:`~django.contrib.gis.geos.GEOSGeometry` objects, and are thin -wrappers 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:: - - >>> from django.contrib.gis.gdal import OGRGeometry - >>> polygon = OGRGeometry('POLYGON((0 0, 5 0, 5 5, 0 5))') - -.. class:: OGRGeometry(geom_input[, srs=None]) - - This object is a wrapper for the `OGR Geometry`__ class. - These objects are instantiated directly from the given ``geom_input`` - parameter, which may be a string containing WKT or HEX, a ``buffer`` - containing WKB data, or an :class:`OGRGeomType` object. These objects - are also returned from the :class:`Feature.geom` attribute, when - reading vector data from :class:`Layer` (which is in turn a part of - a :class:`DataSource`). - - __ http://www.gdal.org/ogr/classOGRGeometry.html - - .. classmethod:: from_bbox(bbox) - - .. versionadded:: 1.1 - - Constructs a :class:`Polygon` from the given bounding-box (a 4-tuple). - - .. method:: __len__ - - Returns the number of points in a :class:`LineString`, the - number of rings in a :class:`Polygon`, or the number of geometries in a - :class:`GeometryCollection`. Not applicable to other geometry types. - - .. method:: __iter__ - - Iterates over the points in a :class:`LineString`, the rings in a - :class:`Polygon`, or the geometries in a :class:`GeometryCollection`. - Not applicable to other geometry types. - - .. method:: __getitem__ - - Returns the point at the specified index for a :class:`LineString`, the - interior ring at the specified index for a :class:`Polygon`, or the geometry - at the specified index in a :class:`GeometryCollection`. Not applicable to - other geometry types. - - .. attribute:: dimension - - Returns the number of coordinated dimensions of the geometry, i.e. 0 - for points, 1 for lines, and so forth:: - - >> polygon.dimension - 2 - - .. attribute:: coord_dim - - .. versionchanged:: 1.2 - - Returns or sets the coordinate dimension of this geometry. For - example, the value would be 2 for two-dimensional geometries. - - .. note:: - - Setting this property is only available in versions 1.2 and above. - - .. attribute:: geom_count - - Returns the number of elements in this geometry:: - - >>> polygon.geom_count - 1 - - .. attribute:: point_count - - Returns the number of points used to describe this geometry:: - - >>> polygon.point_count - 4 - - .. attribute:: num_points - - Alias for :attr:`point_count`. - - .. attribute:: num_coords - - Alias for :attr:`point_count`. - - .. attribute:: geom_type - - Returns the type of this geometry, as an :class:`OGRGeomType` object. - - .. attribute:: geom_name - - Returns the name of the type of this geometry:: - - >>> polygon.geom_name - 'POLYGON' - - .. attribute:: area - - Returns the area of this geometry, or 0 for geometries that do not - contain an area:: - - >>> polygon.area - 25.0 - - .. attribute:: envelope - - Returns the envelope of this geometry, as an :class:`Envelope` object. - - .. attribute:: extent - - Returns the envelope of this geometry as a 4-tuple, instead of as an - :class:`Envelope` object:: - - >>> point.extent - (0.0, 0.0, 5.0, 5.0) - - .. attribute:: srs - - This property controls the spatial reference for this geometry, or - ``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:: - - >>> city.geom.srs.name - 'GCS_WGS_1984' - - .. attribute:: srid - - Returns or sets the spatial reference identifier corresponding to - :class:`SpatialReference` of this geometry. Returns ``None`` if - there is no spatial reference information associated with this - geometry, or if an SRID cannot be determined. - - .. attribute:: geos - - Returns a :class:`~django.contrib.gis.geos.GEOSGeometry` object - corresponding to this geometry. - - .. attribute:: gml - - Returns a string representation of this geometry in GML format:: - - >>> 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:: - - >>> OGRGeometry('POINT(1 2)').hex - '0101000000000000000000F03F0000000000000040' - - .. attribute:: json - - Returns a string representation of this geometry in JSON format:: - - >>> OGRGeometry('POINT(1 2)').json - '{ "type": "Point", "coordinates": [ 1.000000, 2.000000 ] }' - - - .. attribute:: kml - - .. versionadded:: 1.1 - - Returns a string representation of this geometry in KML format. - - .. attribute:: wkb_size - - Returns the size of the WKB buffer needed to hold a WKB representation - of this geometry:: - - >>> OGRGeometry('POINT(1 2)').wkb_size - 21 - - .. attribute:: wkb - - Returns a ``buffer`` containing a WKB representation of this geometry. - - .. attribute:: wkt - - Returns a string representation of this geometry in WKT format. - - .. attribute:: ewkt - - .. versionadded:: 1.2 - - Returns the EWKT representation of this geometry. - - .. method:: clone() - - Returns a new :class:`OGRGeometry` clone of this geometry object. - - .. 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:: - - >>> triangle = OGRGeometry('LINEARRING (0 0,0 1,1 0)') - >>> triangle.close_rings() - >>> triangle.wkt - 'LINEARRING (0 0,0 1,1 0,0 0)' - - .. method:: transform(coord_trans, clone=False) - - Transforms this geometry to a different spatial reference system. May - take a :class:`CoordTransform` object, a :class:`SpatialReference` object, - or any other input accepted by :class:`SpatialReference` (including - spatial reference WKT and PROJ.4 strings, or an integer SRID). - By default nothing is returned and the geometry is transformed in-place. - However, if the `clone` keyword is set to ``True`` then a transformed clone - of this geometry is returned instead. - - .. method:: intersects(other) - - Returns ``True`` if this geometry intersects the other, otherwise returns - ``False``. - - .. method:: equals(other) - - Returns ``True`` if this geometry is equivalent to the other, otherwise returns - ``False``. - - .. method:: disjoint(other) - - Returns ``True`` if this geometry is spatially disjoint to (i.e. does - not intersect) the other, otherwise returns ``False``. - - .. method:: touches(other) - - Returns ``True`` if this geometry touches the other, otherwise returns - ``False``. - - .. method:: crosses(other) - - Returns ``True`` if this geometry crosses the other, otherwise returns - ``False``. - - .. method:: within(other) - - Returns ``True`` if this geometry is contained within the other, otherwise returns - ``False``. - - .. method:: contains(other) - - Returns ``True`` if this geometry contains the other, otherwise returns - ``False``. - - .. method:: overlaps(other) - - Returns ``True`` if this geometry overlaps the other, otherwise returns - ``False``. - - .. method:: boundary - - The boundary of this geometry, as a new :class:`OGRGeometry` object. - - .. attribute:: convex_hull - - The smallest convex polygon that contains this geometry, as a new - :class:`OGRGeometry` object. - - .. method:: difference - - Returns the region consisting of the difference of this geometry and - the other, as a new :class:`OGRGeometry` object. - - .. method:: intersection - - Returns the region consisting of the intersection of this geometry and - the other, as a new :class:`OGRGeometry` object. - - .. method:: sym_difference - - Returns the region consisting of the symmetric difference of this - geometry and the other, as a new :class:`OGRGeometry` object. - - .. method:: union - - Returns the region consisting of the union of this geometry and - the other, as a new :class:`OGRGeometry` object. - - .. 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:: - - >>> OGRGeometry('POINT (1 2)').tuple - (1.0, 2.0) - >>> OGRGeometry('LINESTRING (1 2,3 4)').tuple - ((1.0, 2.0), (3.0, 4.0)) - - .. attribute:: coords - - An alias for :attr:`tuple`. - -.. class:: Point - - .. attribute:: x - - Returns the X coordinate of this point:: - - >>> OGRGeometry('POINT (1 2)').x - 1.0 - - .. attribute:: y - - Returns the Y coordinate of this point:: - - >>> OGRGeometry('POINT (1 2)').y - 2.0 - - .. attribute:: z - - Returns the Z coordinate of this point, or ``None`` if the - the point does not have a Z coordinate:: - - >>> OGRGeometry('POINT (1 2 3)').z - 3.0 - -.. class:: LineString - - .. attribute:: x - - Returns a list of X coordinates in this line:: - - >>> OGRGeometry('LINESTRING (1 2,3 4)').x - [1.0, 3.0] - - .. attribute:: y - - Returns a list of Y coordinates in this line:: - - >>> OGRGeometry('LINESTRING (1 2,3 4)').y - [2.0, 4.0] - - .. attribute:: z - - Returns a list of Z coordinates in this line, or ``None`` if the - line does not have Z coordinates:: - - >>> OGRGeometry('LINESTRING (1 2 3,4 5 6)').z - [3.0, 6.0] - - -.. class:: Polygon - - .. attribute:: shell - - Returns the shell or exterior ring of this polygon, as a ``LinearRing`` - geometry. - - .. attribute:: exterior_ring - - An alias for :attr:`shell`. - - .. attribute:: centroid - - Returns a :class:`Point` representing the centroid of this polygon. - -.. class:: GeometryCollection - - .. method:: add(geom) - - Adds a geometry to this geometry collection. Not applicable to other - geometry types. - - -``OGRGeomType`` ---------------- - -.. class:: OGRGeomType(type_input) - - This class allows for the representation of an OGR geometry type - in any of several ways:: - - >>> from django.contrib.gis.gdal import OGRGeomType - >>> gt1 = OGRGeomType(3) # Using an integer for the type - >>> gt2 = OGRGeomType('Polygon') # Using a string - >>> gt3 = OGRGeomType('POLYGON') # It's case-insensitive - >>> print gt1 == 3, gt1 == 'Polygon' # Equivalence works w/non-OGRGeomType objects - True True - - .. attribute:: name - - Returns a short-hand string form of the OGR Geometry type:: - - >>> gt1.name - 'Polygon' - - .. attribute:: num - - Returns the number corresponding to the OGR geometry type:: - - >>> gt1.num - 3 - - .. 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:: - - >>> gt1.django - 'PolygonField' - -``Envelope`` ------------- - -.. class:: Envelope(*args) - - Represents an OGR Envelope structure that contains the - minimum and maximum X, Y coordinates for a rectangle bounding box. - The naming of the variables is compatible with the OGR Envelope - C structure. - - .. attribute:: min_x - - The value of the minimum X coordinate. - - .. attribute:: min_y - - The value of the maximum X coordinate. - - .. attribute:: max_x - - The value of the minimum Y coordinate. - - .. attribute:: max_y - - The value of the maximum Y coordinate. - - .. attribute:: ur - - The upper-right coordinate, as a tuple. - - .. attribute:: ll - - The lower-left coordinate, as a tuple. - - .. attribute:: tuple - - A tuple representing the envelope. - - .. attribute:: wkt - - A string representing this envelope as a polygon in WKT format. - - - .. method:: expand_to_include(self, *args) - - .. versionadded:: 1.1 - -Coordinate System Objects -========================= - -``SpatialReference`` --------------------- - -.. class:: SpatialReference(srs_input) - - Spatial reference objects are initialized on the given ``srs_input``, - which may be one of the following: - - * OGC Well Known Text (WKT) (a string) - * EPSG code (integer or string) - * PROJ.4 string - * A shorthand string for well-known standards (``'WGS84'``, ``'WGS72'``, ``'NAD27'``, ``'NAD83'``) - - Example:: - - >>> wgs84 = SpatialReference('WGS84') # shorthand string - >>> wgs84 = SpatialReference(4326) # EPSG code - >>> wgs84 = SpatialReference('EPSG:4326') # EPSG string - >>> proj4 = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ' - >>> wgs84 = SpatialReference(proj4) # PROJ.4 string - >>> wgs84 = SpatialReference("""GEOGCS["WGS 84", - DATUM["WGS_1984", - SPHEROID["WGS 84",6378137,298.257223563, - AUTHORITY["EPSG","7030"]], - AUTHORITY["EPSG","6326"]], - PRIMEM["Greenwich",0, - AUTHORITY["EPSG","8901"]], - UNIT["degree",0.01745329251994328, - AUTHORITY["EPSG","9122"]], - AUTHORITY["EPSG","4326"]]""") # OGC WKT - - .. method:: __getitem__(target) - - 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:: - - >>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]') - >>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326 - >>> print srs['GEOGCS'] - WGS 84 - >>> print srs['DATUM'] - WGS_1984 - >>> print srs['AUTHORITY'] - EPSG - >>> print srs['AUTHORITY', 1] # The authority value - 4326 - >>> print srs['TOWGS84', 4] # the fourth value in this wkt - 0 - >>> print srs['UNIT|AUTHORITY'] # For the units authority, have to use the pipe symbole. - EPSG - >>> print srs['UNIT|AUTHORITY', 1] # The authority value for the untis - 9122 - - .. method:: attr_value(target, index=0) - - The attribute value for the given target node (e.g. ``'PROJCS'``). - The index keyword specifies an index of the child node to return. - - .. method:: auth_name(target) - - Returns the authority name for the given string target node. - - .. method:: auth_code(target) - - Returns the authority code for the given string target node. - - .. method:: clone() - - Returns a clone of this spatial reference object. - - .. method:: identify_epsg() - - This method inspects the WKT of this SpatialReference, and will - add EPSG authority nodes where an EPSG identifier is applicable. - - .. method:: from_esri() - - Morphs this SpatialReference from ESRI's format to EPSG - - .. method:: to_esri() - - Morphs this SpatialReference to ESRI's format. - - .. method:: validate() - - Checks to see if the given spatial reference is valid, if not - an exception will be raised. - - .. method:: import_epsg(epsg) - - Import spatial reference from EPSG code. - - .. method:: import_proj(proj) - - Import spatial reference from PROJ.4 string. - - .. method:: import_user_input(user_input) - - .. versionadded:: 1.1 - - .. method:: import_wkt(wkt) - - Import spatial reference from WKT. - - .. method:: import_xml(xml) - - Import spatial reference from XML. - - .. attribute:: name - - Returns the name of this Spatial Reference. - - .. attribute:: srid - - Returns the SRID of top-level authority, or ``None`` if undefined. - - .. attribute:: linear_name - - Returns the name of the linear units. - - .. attribute:: linear_units - - Returns the value of the linear units. - - .. attribute:: angular_name - - Returns the name of the angular units." - - .. attribute:: angular_units - - Returns the value of the angular units. - - .. attribute:: units - - Returns a 2-tuple of the units value and the units name, - and will automatically determines whether to return the linear - or angular units. - - .. attribute:: ellisoid - - Returns a tuple of the ellipsoid parameters for this spatial - reference: (semimajor axis, semiminor axis, and inverse flattening) - - .. attribute:: semi_major - - Returns the semi major axis of the ellipsoid for this spatial reference. - - .. attribute:: semi_minor - - Returns the semi minor axis of the ellipsoid for this spatial reference. - - .. attribute:: inverse_flattening - - Returns the inverse flattening of the ellipsoid for this spatial reference. - - .. attribute:: geographic - - Returns ``True`` if this spatial reference is geographic - (root node is ``GEOGCS``). - - .. attribute:: local - - Returns ``True`` if this spatial reference is local - (root node is ``LOCAL_CS``). - - .. attribute:: projected - - Returns ``True`` if this spatial reference is a projected coordinate - system (root node is ``PROJCS``). - - .. attribute:: wkt - - Returns the WKT representation of this spatial reference. - - .. attribute:: pretty_wkt - - Returns the 'pretty' representation of the WKT. - - .. attribute:: proj - - Returns the PROJ.4 representation for this spatial reference. - - .. attribute:: proj4 - - Alias for :attr:`SpatialReference.proj`. - - .. attribute:: xml - - Returns the XML representation of this spatial reference. - - -``CoordTransform`` ------------------- - -.. class:: CoordTransform(source, target) - -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:: - - >>> ct = CoordTransform(SpatialReference('WGS84'), SpatialReference('NAD83')) - >>> for feat in layer: - ... geom = feat.geom # getting clone of feature geometry - ... geom.transform(ct) # transforming - -Settings -======== - -.. setting:: GDAL_LIBRARY_PATH - -GDAL_LIBRARY_PATH ------------------ - -A string specifying the location of the GDAL library. Typically, -this setting is only used if the GDAL library is in a non-standard -location (e.g., ``/home/john/lib/libgdal.so``). diff --git a/parts/django/docs/ref/contrib/gis/geoip.txt b/parts/django/docs/ref/contrib/gis/geoip.txt deleted file mode 100644 index 784d69e..0000000 --- a/parts/django/docs/ref/contrib/gis/geoip.txt +++ /dev/null @@ -1,223 +0,0 @@ -.. _ref-geoip: - -====================== -Geolocation with GeoIP -====================== - -.. module:: django.contrib.gis.utils.geoip - :synopsis: High-level Python interface for MaxMind's GeoIP C library. - -.. currentmodule:: django.contrib.gis.utils - -The :class:`GeoIP` object is a ctypes wrapper for the -`MaxMind GeoIP C API`__. [#]_ This interface is a BSD-licensed alternative -to the GPL-licensed `Python GeoIP`__ interface provided by MaxMind. - -In order to perform IP-based geolocation, the :class:`GeoIP` object requires -the GeoIP C libary and either the GeoIP `Country`__ or `City`__ -datasets in binary format (the CSV files will not work!). These datasets may be -`downloaded from MaxMind`__. Grab the ``GeoIP.dat.gz`` and ``GeoLiteCity.dat.gz`` -and unzip them in a directory corresponding to what you set -``GEOIP_PATH`` with in your settings. See the example and reference below -for more details. - -__ http://www.maxmind.com/app/c -__ http://www.maxmind.com/app/python -__ http://www.maxmind.com/app/country -__ http://www.maxmind.com/app/city -__ http://www.maxmind.com/download/geoip/database/ - -Example -======= - -Assuming you have the GeoIP C library installed, here is an example of its -usage:: - - >>> from django.contrib.gis.utils import GeoIP - >>> g = GeoIP() - >>> g.country('google.com') - {'country_code': 'US', 'country_name': 'United States'} - >>> g.city('72.14.207.99') - {'area_code': 650, - 'city': 'Mountain View', - 'country_code': 'US', - 'country_code3': 'USA', - 'country_name': 'United States', - 'dma_code': 807, - 'latitude': 37.419200897216797, - 'longitude': -122.05740356445312, - 'postal_code': '94043', - 'region': 'CA'} - >>> g.lat_lon('salon.com') - (37.789798736572266, -122.39420318603516) - >>> g.lon_lat('uh.edu') - (-95.415199279785156, 29.77549934387207) - >>> g.geos('24.124.1.80').wkt - 'POINT (-95.2087020874023438 39.0392990112304688)' - -``GeoIP`` Settings -================== - -.. setting:: GEOIP_PATH - -GEOIP_PATH ----------- - -A string specifying the directory where the GeoIP data files are -located. This setting is *required* unless manually specified -with ``path`` keyword when initializing the :class:`GeoIP` object. - -.. setting:: GEOIP_LIBRARY_PATH - -GEOIP_LIBRARY_PATH ------------------- - -A string specifying the location of the GeoIP C library. Typically, -this setting is only used if the GeoIP C library is in a non-standard -location (e.g., ``/home/sue/lib/libGeoIP.so``). - -.. setting:: GEOIP_COUNTRY - -GEOIP_COUNTRY -------------- - -The basename to use for the GeoIP country data file. -Defaults to ``'GeoIP.dat'``. - -.. setting:: GEOIP_CITY - -GEOIP_CITY ----------- - -The basename to use for the GeoIP city data file. -Defaults to ``'GeoLiteCity.dat'``. - -``GeoIP`` API -============= - -.. class:: GeoIP([path=None, cache=0, country=None, city=None]) - -The ``GeoIP`` object does not require any parameters to use the default -settings. However, at the very least the :setting:`GEOIP_PATH` setting -should be set with the path of the location of your GeoIP data sets. The -following intialization keywords may be used to customize any of the -defaults. - -=================== ======================================================= -Keyword Arguments Description -=================== ======================================================= -``path`` Base directory to where GeoIP data is located or the - full path to where the city or country data files - (.dat) are located. Assumes that both the city and - country data sets are located in this directory; - overrides the :setting:`GEOIP_PATH` settings attribute. - -``cache`` The cache settings when opening up the GeoIP datasets, - and may be an integer in (0, 1, 2, 4) corresponding to - the ``GEOIP_STANDARD``, ``GEOIP_MEMORY_CACHE``, - ``GEOIP_CHECK_CACHE``, and ``GEOIP_INDEX_CACHE`` - ``GeoIPOptions`` C API settings, respectively. - Defaults to 0 (``GEOIP_STANDARD``). - -``country`` The name of the GeoIP country data file. Defaults - to ``GeoIP.dat``. Setting this keyword overrides the - :setting:`GEOIP_COUNTRY` settings attribute. - -``city`` The name of the GeoIP city data file. Defaults to - ``GeoLiteCity.dat``. Setting this keyword overrides - the :setting:`GEOIP_CITY` settings attribute. -=================== ======================================================= - -``GeoIP`` Methods -================= - -Querying --------- - -All the following querying routines may take either a string IP address -or a fully qualified domain name (FQDN). For example, both -``'24.124.1.80'`` and ``'djangoproject.com'`` would be valid query -parameters. - -.. method:: GeoIP.city(query) - -Returns a dictionary of city information for the given query. Some -of the values in the dictionary may be undefined (``None``). - -.. method:: GeoIPcountry(query) - -Returns a dictionary with the country code and country for the given -query. - -.. method:: GeoIP.country_code(query) - -Returns only the country code corresponding to the query. - -.. method:: GeoIP.country_name(query) - -Returns only the country name corresponding to the query. - -Coordinate Retrieval --------------------- - -.. method:: GeoIP.coords(query) - -Returns a coordinate tuple of (longitude, latitude). - -.. method:: GeoIP.lon_lat(query) - -Returns a coordinate tuple of (longitude, latitude). - -.. method:: GeoIP.lat_lon(query) - -Returns a coordinate tuple of (latitude, longitude), - -.. method:: GeoIP.geos(query) - -Returns a :class:`django.contrib.gis.geos.Point` object corresponding to the query. - -Database Information --------------------- - -.. attribute:: GeoIP.country_info - -This property returns information about the GeoIP country database. - -.. attribute:: GeoIP.city_info - -This property returns information about the GeoIP city database. - -.. attribute:: GeoIP.info - -This property returns information about all GeoIP databases (both city -and country). - -GeoIP-Python API compatibility methods ----------------------------------------- - -These methods exist to ease compatibility with any code using MaxMind's -existing Python API. - -.. classmethod:: GeoIP.open(path, cache) - -This classmethod instantiates the GeoIP object from the given database path -and given cache setting. - -.. method:: GeoIP.region_by_addr(query) - -.. method:: GeoIP.region_by_name(query) - -.. method:: GeoIP.record_by_addr(query) - -.. method:: GeoIP.record_by_name(query) - -.. method:: GeoIP.country_code_by_addr(query) - -.. method:: GeoIP.country_code_by_name(query) - -.. method:: GeoIP.country_name_by_addr(query) - -.. method:: GeoIP.country_name_by_name(query) - -.. rubric:: Footnotes -.. [#] GeoIP(R) is a registered trademark of MaxMind, LLC of Boston, Massachusetts. diff --git a/parts/django/docs/ref/contrib/gis/geoquerysets.txt b/parts/django/docs/ref/contrib/gis/geoquerysets.txt deleted file mode 100644 index 69f0c02..0000000 --- a/parts/django/docs/ref/contrib/gis/geoquerysets.txt +++ /dev/null @@ -1,1256 +0,0 @@ -.. _ref-geoquerysets: - -========================= -GeoQuerySet API Reference -========================= - -.. currentmodule:: django.contrib.gis.db.models - -.. class:: GeoQuerySet([model=None]) - - -.. _spatial-lookups: - -Spatial Lookups -=============== - -Just like when using the the :ref:`queryset-api`, interaction -with ``GeoQuerySet`` by :ref:`chaining filters <chaining-filters>`. -Instead of the regular Django :ref:`field-lookups`, the -spatial lookups in this section are available for :class:`GeometryField`. - -For an introduction, see the :ref:`spatial lookups introduction -<spatial-lookups-intro>`. For an overview of what lookups are -compatible with a particular spatial backend, refer to the -:ref:`spatial lookup compatibility table <spatial-lookup-compatibility>`. - -.. fieldlookup:: bbcontains - -bbcontains ----------- - -*Availability*: PostGIS, MySQL, SpatiaLite - -Tests if the geometry field's bounding box completely contains the lookup -geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__bbcontains=geom) - -========== ========================== -Backend SQL Equivalent -========== ========================== -PostGIS ``poly ~ geom`` -MySQL ``MBRContains(poly, geom)`` -SpatiaLite ``MbrContains(poly, geom)`` -========== ========================== - -.. fieldlookup:: bboverlaps - -bboverlaps ----------- - -*Availability*: PostGIS, MySQL, SpatiaLite - -Tests if the geometry field's bounding box overlaps the lookup geometry's -bounding box. - -Example:: - - Zipcode.objects.filter(poly__bboverlaps=geom) - -========== ========================== -Backend SQL Equivalent -========== ========================== -PostGIS ``poly && geom`` -MySQL ``MBROverlaps(poly, geom)`` -SpatiaLite ``MbrOverlaps(poly, geom)`` -========== ========================== - -.. fieldlookup:: contained - -contained ---------- - -*Availability*: PostGIS, MySQL, SpatiaLite - -Tests if the geometry field's bounding box is completely contained by the -lookup geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__contained=geom) - -========== ========================== -Backend SQL Equivalent -========== ========================== -PostGIS ``poly @ geom`` -MySQL ``MBRWithin(poly, geom)`` -SpatiaLite ``MbrWithin(poly, geom)`` -========== ========================== - -.. fieldlookup:: gis-contains - -contains --------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -Tests if the geometry field spatially contains the lookup geometry. - -Example:: - - Zipcode.objects.filter(poly__contains=geom) - -========== ============================ -Backend SQL Equivalent -========== ============================ -PostGIS ``ST_Contains(poly, geom)`` -Oracle ``SDO_CONTAINS(poly, geom)`` -MySQL ``MBRContains(poly, geom)`` -SpatiaLite ``Contains(poly, geom)`` -========== ============================ - -.. fieldlookup:: contains_properly - -contains_properly ------------------ - -.. versionadded:: 1.2 - -*Availability*: PostGIS - -Returns true if the lookup geometry intersects the interior of the -geometry field, but not the boundary (or exterior). [#fncontainsproperly]_ - -.. note:: - - Requires PostGIS 1.4 and above. - -Example:: - - Zipcode.objects.filter(poly__contains_properly=geom) - -========== =================================== -Backend SQL Equivalent -========== =================================== -PostGIS ``ST_ContainsProperly(poly, geom)`` -========== =================================== - -.. fieldlookup:: coveredby - -coveredby ---------- - -*Availability*: PostGIS, Oracle - -Tests if no point in the geometry field is outside the lookup geometry. -[#fncovers]_ - -Example:: - - Zipcode.objects.filter(poly__coveredby=geom) - -========== ============================= -Backend SQL Equivalent -========== ============================= -PostGIS ``ST_CoveredBy(poly, geom)`` -Oracle ``SDO_COVEREDBY(poly, geom)`` -========== ============================= - -.. fieldlookup:: covers - -covers ------- - -*Availability*: PostGIS, Oracle - -Tests if no point in the lookup geometry is outside the geometry field. -[#fncovers]_ - -Example:: - - Zipcode.objects.filter(poly__covers=geom) - -========== ========================== -Backend SQL Equivalent -========== ========================== -PostGIS ``ST_Covers(poly, geom)`` -Oracle ``SDO_COVERS(poly, geom)`` -========== ========================== - -.. fieldlookup:: crosses - -crosses -------- - -*Availability*: PostGIS, SpatiaLite - -Tests if the geometry field spatially crosses the lookup geometry. - -Example:: - - Zipcode.objects.filter(poly__crosses=geom) - -========== ========================== -Backend SQL Equivalent -========== ========================== -PostGIS ``ST_Crosses(poly, geom)`` -SpatiaLite ``Crosses(poly, geom)`` -========== ========================== - -.. fieldlookup:: disjoint - -disjoint --------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -Tests if the geometry field is spatially disjoint from the lookup geometry. - -Example:: - - Zipcode.objects.filter(poly__disjoint=geom) - -========== ================================================= -Backend SQL Equivalent -========== ================================================= -PostGIS ``ST_Disjoint(poly, geom)`` -Oracle ``SDO_GEOM.RELATE(poly, 'DISJOINT', geom, 0.05)`` -MySQL ``MBRDisjoint(poly, geom)`` -SpatiaLite ``Disjoint(poly, geom)`` -========== ================================================= - -equals ------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -.. fieldlookup:: exact -.. fieldlookup:: same_as - -exact, same_as --------------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -.. fieldlookup:: intersects - -intersects ----------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -Tests if the geometry field spatially intersects the lookup geometry. - -Example:: - - Zipcode.objects.filter(poly__intersects=geom) - -========== ================================================= -Backend SQL Equivalent -========== ================================================= -PostGIS ``ST_Intersects(poly, geom)`` -Oracle ``SDO_OVERLAPBDYINTERSECT(poly, geom)`` -MySQL ``MBRIntersects(poly, geom)`` -SpatiaLite ``Intersects(poly, geom)`` -========== ================================================= - -.. fieldlookup:: overlaps - -overlaps --------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -.. fieldlookup:: relate - -relate ------- - -*Availability*: PostGIS, Oracle, SpatiaLite - -Tests if the geometry field is spatially related to the the lookup geometry by -the values given in the given pattern. This lookup requires a tuple parameter, -``(geom, pattern)``; the form of ``pattern`` will depend on the spatial backend: - -PostGIS & SpatiaLite -~~~~~~~~~~~~~~~~~~~~ -On these spatial backends the intersection pattern is a string comprising -nine characters, which define intersections between the interior, boundary, -and exterior of the geometry field and the lookup geometry. -The intersection pattern matrix may only use the following characters: -``1``, ``2``, ``T``, ``F``, or ``*``. This lookup type allows users to "fine tune" -a specific geometric relationship consistent with the DE-9IM model. [#fnde9im]_ - -Example:: - - # A tuple lookup parameter is used to specify the geometry and - # the intersection pattern (the pattern here is for 'contains'). - Zipcode.objects.filter(poly__relate(geom, 'T*T***FF*')) - -PostGIS SQL equivalent:: - - SELECT ... WHERE ST_Relate(poly, geom, 'T*T***FF*') - -SpatiaLite SQL equivalent:: - - SELECT ... WHERE Relate(poly, geom, 'T*T***FF*') - -Oracle -~~~~~~ - -Here the relation pattern is compreised at least one of the nine relation -strings: ``TOUCH``, ``OVERLAPBDYDISJOINT``, ``OVERLAPBDYINTERSECT``, -``EQUAL``, ``INSIDE``, ``COVEREDBY``, ``CONTAINS``, ``COVERS``, ``ON``, and -``ANYINTERACT``. Multiple strings may be combined with the logical Boolean -operator OR, for example, ``'inside+touch'``. [#fnsdorelate]_ The relation -strings are case-insensitive. - -Example:: - - Zipcode.objects.filter(poly__relate(geom, 'anyinteract')) - -Oracle SQL equivalent:: - - SELECT ... WHERE SDO_RELATE(poly, geom, 'anyinteract') - -.. fieldlookup:: touches - -touches -------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -Tests if the geometry field spatially touches the lookup geometry. - -Example:: - - Zipcode.objects.filter(poly__touches=geom) - -========== ========================== -Backend SQL Equivalent -========== ========================== -PostGIS ``ST_Touches(poly, geom)`` -MySQL ``MBRTouches(poly, geom)`` -Oracle ``SDO_TOUCH(poly, geom)`` -SpatiaLite ``Touches(poly, geom)`` -========== ========================== - -.. fieldlookup:: within - -within ------- - -*Availability*: PostGIS, Oracle, MySQL, SpatiaLite - -Tests if the geometry field is spatially within the lookup geometry. - -Example:: - - Zipcode.objects.filter(poly__within=geom) - -========== ========================== -Backend SQL Equivalent -========== ========================== -PostGIS ``ST_Within(poly, geom)`` -MySQL ``MBRWithin(poly, geom)`` -Oracle ``SDO_INSIDE(poly, geom)`` -SpatiaLite ``Within(poly, geom)`` -========== ========================== - -.. fieldlookup:: left - -left ----- - -*Availability*: PostGIS - -Tests if the geometry field's bounding box is strictly to the left of the -lookup geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__left=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly << geom - -.. fieldlookup:: right - -right ------ - -*Availability*: PostGIS - -Tests if the geometry field's bounding box is strictly to the right of the -lookup geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__right=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly >> geom - -.. fieldlookup:: overlaps_left - -overlaps_left -------------- - -*Availability*: PostGIS - -Tests if the geometry field's bounding box overlaps or is to the left of the lookup -geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__overlaps_left=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly &< geom - - -.. fieldlookup:: overlaps_right - -overlaps_right --------------- - -*Availability*: PostGIS - -Tests if the geometry field's bounding box overlaps or is to the right of the lookup -geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__overlaps_right=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly &> geom - -.. fieldlookup:: overlaps_above - -overlaps_above --------------- - -*Availability*: PostGIS - -Tests if the geometry field's bounding box overlaps or is above the lookup -geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__overlaps_above=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly |&> geom - -.. fieldlookup:: overlaps_below - -overlaps_below --------------- - -*Availability*: PostGIS - -Tests if the geometry field's bounding box overlaps or is below the lookup -geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__overlaps_below=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly &<| geom - -.. fieldlookup:: strictly_above - -strictly_above --------------- - -*Availability*: PostGIS - -Tests if the geometry field's bounding box is strictly above the lookup -geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__strictly_above=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly |>> geom - -.. fieldlookup:: strictly_below - -strictly_below --------------- - -*Availability*: PostGIS - -Tests if the geometry field's bounding box is strictly above the lookup -geometry's bounding box. - -Example:: - - Zipcode.objects.filter(poly__strictly_above=geom) - -PostGIS equivalent:: - - SELECT ... WHERE poly |>> geom - - -.. _distance-lookups: - -Distance Lookups -================ - -*Availability*: PostGIS, Oracle, SpatiaLite - -For an overview on performing distance queries, please refer to -the :ref:`distance queries introduction <distance-queries>`. - -Distance lookups take the following form:: - - <field>__<distance lookup>=(<geometry>, <distance value>[, 'spheroid']) - -The value passed into a distance lookup is a tuple; the first two -values are mandatory, and are the geometry to calculate distances to, -and a distance value (either a number in units of the field or a -:class:`~django.contrib.gis.measure.Distance` object). On every -distance lookup but :lookup:`dwithin`, an optional -third element, ``'spheroid'``, may be included to tell GeoDjango -to use the more accurate spheroid distance calculation functions on -fields with a geodetic coordinate system (e.g., ``ST_Distance_Spheroid`` -would be used instead of ``ST_Distance_Sphere``). - -.. fieldlookup:: distance_gt - -distance_gt ------------ - -Returns models where the distance to the geometry field from the lookup -geometry is greater than the given distance value. - -Example:: - - Zipcode.objects.filter(poly__distance_gt=(geom, D(m=5))) - -========== =============================================== -Backend SQL Equivalent -========== =============================================== -PostGIS ``ST_Distance(poly, geom) > 5`` -Oracle ``SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) > 5`` -SpatiaLite ``Distance(poly, geom) > 5`` -========== =============================================== - -.. fieldlookup:: distance_gte - -distance_gte ------------- - -Returns models where the distance to the geometry field from the lookup -geometry is greater than or equal to the given distance value. - -Example:: - - Zipcode.objects.filter(poly__distance_gte=(geom, D(m=5))) - -========== ================================================ -Backend SQL Equivalent -========== ================================================ -PostGIS ``ST_Distance(poly, geom) >= 5`` -Oracle ``SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) >= 5`` -SpatiaLite ``Distance(poly, geom) >= 5`` -========== ================================================ - -.. fieldlookup:: distance_lt - -distance_lt ------------ - -Returns models where the distance to the geometry field from the lookup -geometry is less than the given distance value. - -Example:: - - Zipcode.objects.filter(poly__distance_lt=(geom, D(m=5))) - -========== =============================================== -Backend SQL Equivalent -========== =============================================== -PostGIS ``ST_Distance(poly, geom) < 5`` -Oracle ``SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) < 5`` -SpatiaLite ``Distance(poly, geom) < 5`` -========== =============================================== - -.. fieldlookup:: distance_lte - -distance_lte ------------- - -Returns models where the distance to the geometry field from the lookup -geometry is less than or equal to the given distance value. - -Example:: - - Zipcode.objects.filter(poly__distance_lte=(geom, D(m=5))) - -========== ================================================ -Backend SQL Equivalent -========== ================================================ -PostGIS ``ST_Distance(poly, geom) <= 5`` -Oracle ``SDO_GEOM.SDO_DISTANCE(poly, geom, 0.05) <= 5`` -SpatiaLite ``Distance(poly, geom) <= 5`` -========== ================================================ - -.. fieldlookup:: dwithin - -dwithin -------- - -Returns models where the distance to the geometry field from the -lookup geometry are within the given distance from one another. - -Example:: - - Zipcode.objects.filter(poly__dwithin=(geom, D(m=5))) - -========== ====================================== -Backend SQL Equivalent -========== ====================================== -PostGIS ``ST_DWithin(poly, geom, 5)`` -Oracle ``SDO_WITHIN_DISTANCE(poly, geom, 5)`` -========== ====================================== - -.. note:: - - This lookup is not available on SpatiaLite. - -.. fieldlookup:: equals - - -``GeoQuerySet`` Methods -======================= - -``GeoQuerySet`` methods specify that a spatial operation be performed -on each patial operation on each geographic -field in the queryset and store its output in a new attribute on the model -(which is generally the name of the ``GeoQuerySet`` method). - -There are also aggregate ``GeoQuerySet`` methods which return a single value -instead of a queryset. This section will describe the API and availability -of every ``GeoQuerySet`` method available in GeoDjango. - -.. note:: - - What methods are available depend on your spatial backend. See - the :ref:`compatibility table <geoqueryset-method-compatibility>` - for more details. - -With a few exceptions, the following keyword arguments may be used with all -``GeoQuerySet`` methods: - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``field_name`` By default, ``GeoQuerySet`` methods use the first - geographic field encountered in the model. This - keyword should be used to specify another - geographic field (e.g., ``field_name='point2'``) - when there are multiple geographic fields in a model. - - On PostGIS, the ``field_name`` keyword may also be - used on geometry fields in models that are related - via a ``ForeignKey`` relation (e.g., - ``field_name='related__point'``). - -``model_att`` By default, ``GeoQuerySet`` methods typically attach - their output in an attribute with the same name as - the ``GeoQuerySet`` method. Setting this keyword - with the desired attribute name will override this - default behavior. For example, - ``qs = Zipcode.objects.centroid(model_att='c')`` will - attach the centroid of the ``Zipcode`` geometry field - in a ``c`` attribute on every model rather than in a - ``centroid`` attribute. - - This keyword is required if - a method name clashes with an existing - ``GeoQuerySet`` method -- if you wanted to use the - ``area()`` method on model with a ``PolygonField`` - named ``area``, for example. -===================== ===================================================== - -Measurement ------------ -*Availability*: PostGIS, Oracle, SpatiaLite - -``area`` -~~~~~~~~ - -.. method:: GeoQuerySet.area(**kwargs) - -Returns the area of the geographic field in an ``area`` attribute on -each element of this GeoQuerySet. - -``distance`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.distance(geom, **kwargs) - -This method takes a geometry as a parameter, and attaches a ``distance`` -attribute to every model in the returned queryset that contains the -distance (as a :class:`~django.contrib.gis.measure.Distance` object) to the given geometry. - -In the following example (taken from the `GeoDjango distance tests`__), -the distance from the `Tasmanian`__ city of Hobart to every other -:class:`PointField` in the ``AustraliaCity`` queryset is calculated:: - - >>> pnt = AustraliaCity.objects.get(name='Hobart').point - >>> for city in AustraliaCity.objects.distance(pnt): print city.name, city.distance - Wollongong 990071.220408 m - Shellharbour 972804.613941 m - Thirroul 1002334.36351 m - Mittagong 975691.632637 m - Batemans Bay 834342.185561 m - Canberra 598140.268959 m - Melbourne 575337.765042 m - Sydney 1056978.87363 m - Hobart 0.0 m - Adelaide 1162031.83522 m - Hillsdale 1049200.46122 m - -.. note:: - - Because the ``distance`` attribute is a - :class:`~django.contrib.gis.measure.Distance` object, you can easily express - the value in the units of your choice. For example, ``city.distance.mi`` is - the distance value in miles and ``city.distance.km`` is the distance value - in kilometers. See the :ref:`ref-measure` for usage details and the list of - :ref:`supported_units`. - -__ http://code.djangoproject.com/browser/django/trunk/django/contrib/gis/tests/distapp/models.py -__ http://en.wikipedia.org/wiki/Tasmania - -``length`` -~~~~~~~~~~ - -.. method:: GeoQuerySet.length(**kwargs) - -Returns the length of the geometry field in a ``length`` attribute -(a :class:`~django.contrib.gis.measure.Distance` object) on each model in -the queryset. - -``perimeter`` -~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.perimeter(**kwargs) - -Returns the perimeter of the geometry field in a ``perimeter`` attribute -(a :class:`~django.contrib.gis.measure.Distance` object) on each model in -the queryset. - -Geometry Relationships ----------------------- - -The following methods take no arguments, and attach geometry objects -each element of the :class:`GeoQuerySet` that is the result of relationship -function evaluated on the the geometry field. - -``centroid`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.centroid(**kwargs) - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns the ``centroid`` value for the geographic field in a ``centroid`` -attribute on each element of the ``GeoQuerySet``. - -``envelope`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.envelope(**kwargs) - -*Availability*: PostGIS, SpatiaLite - -Returns a geometry representing the bounding box of the geometry field in -an ``envelope`` attribute on each element of the ``GeoQuerySet``. - -``point_on_surface`` -~~~~~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.point_on_surface(**kwargs) - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns a Point geometry guaranteed to lie on the surface of the -geometry field in a ``point_on_surface`` attribute on each element -of the queryset; otherwise sets with None. - -Geometry Editors ----------------- - -``force_rhr`` -~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.force_rhr(**kwargs) - -.. versionadded:: 1.2 - -*Availability*: PostGIS - -Returns a modified version of the polygon/multipolygon in which all -of the vertices follow the Right-Hand-Rule, and attaches as a -``force_rhr`` attribute on each element of the queryset. - -``reverse_geom`` -~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.reverse_geom(**kwargs) - -.. versionadded:: 1.2 - -*Availability*: PostGIS, Oracle - -Reverse the coordinate order of the geometry field, and attaches as a -``reverse`` attribute on each element of the queryset. - -``scale`` -~~~~~~~~~ - -.. method:: GeoQuerySet.scale(x, y, z=0.0, **kwargs) - -*Availability*: PostGIS, SpatiaLite - -``snap_to_grid`` -~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.snap_to_grid(*args, **kwargs) - -.. versionadded:: 1.1 - -Snap all points of the input geometry to the grid. How the -geometry is snapped to the grid depends on how many numeric -(either float, integer, or long) arguments are given. - -=================== ===================================================== -Number of Arguments Description -=================== ===================================================== -1 A single size to snap bot the X and Y grids to. -2 X and Y sizes to snap the grid to. -4 X, Y sizes and the corresponding X, Y origins. -=================== ===================================================== - -``transform`` -~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.transform(srid=4326, **kwargs) - -*Availability*: PostGIS, Oracle, SpatiaLite - -The ``transform`` method transforms the geometry field of a model to the spatial -reference system specified by the ``srid`` parameter. If no ``srid`` is given, -then 4326 (WGS84) is used by default. - -.. note:: - - Unlike other ``GeoQuerySet`` methods, ``transform`` stores its output - "in-place". In other words, no new attribute for the transformed - geometry is placed on the models. - -.. note:: - - What spatial reference system an integer SRID corresponds to may depend on - the spatial database used. In other words, the SRID numbers used for Oracle - are not necessarily the same as those used by PostGIS. - -Example:: - - >>> qs = Zipcode.objects.all().transform() # Transforms to WGS84 - >>> qs = Zipcode.objects.all().transform(32140) # Transforming to "NAD83 / Texas South Central" - >>> print qs[0].poly.srid - 32140 - >>> print qs[0].poly - POLYGON ((234055.1698884720099159 4937796.9232223574072123 ... - -``translate`` -~~~~~~~~~~~~~ -.. method:: GeoQuerySet.translate(x, y, z=0.0, **kwargs) - -*Availability*: PostGIS, SpatiaLite - -Translates the geometry field to a new location using the given numeric -parameters as offsets. - -Geometry Operations -------------------- -*Availability*: PostGIS, Oracle, SpatiaLite - -The following methods all take a geometry as a parameter and attach a geometry -to each element of the ``GeoQuerySet`` that is the result of the operation. - -``difference`` -~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.difference(geom) - -Returns the spatial difference of the geographic field with the given -geometry in a ``difference`` attribute on each element of the -``GeoQuerySet``. - - -``intersection`` -~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.intersection(geom) - -Returns the spatial intersection of the geographic field with the -given geometry in an ``intersection`` attribute on each element of the -``GeoQuerySet``. - -``sym_difference`` -~~~~~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.sym_difference(geom) - -Returns the symmetric difference of the geographic field with the -given geometry in a ``sym_difference`` attribute on each element of the -``GeoQuerySet``. - -``union`` -~~~~~~~~~ - -.. method:: GeoQuerySet.union(geom) - -Returns the union of the geographic field with the given -geometry in an ``union`` attribute on each element of the -``GeoQuerySet``. - -Geometry Output ---------------- - -The following ``GeoQuerySet`` methods will return an attribute that has the value -of the geometry field in each model converted to the requested output format. - -``geohash`` -~~~~~~~~~~~ - -.. method:: GeoQuerySet.geohash(preceision=20, **kwargs) - -.. versionadded:: 1.2 - -Attaches a ``geohash`` attribute to every model the the queryset -containing the `GeoHash`__ representation of the geometry. - -__ http://geohash.org/ - -``geojson`` -~~~~~~~~~~~ - -.. method:: GeoQuerySet.geojson(**kwargs) - -.. versionadded:: 1.1 - -*Availability*: PostGIS - -Attaches a ``geojson`` attribute to every model in the queryset that contains the -`GeoJSON`__ representation of the geometry. - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``precision`` It may be used to specify the number of significant - digits for the coordinates in the GeoJSON - representation -- the default value is 8. - -``crs`` Set this to ``True`` if you want the coordinate - reference system to be included in the returned - GeoJSON. - -``bbox`` Set this to ``True`` if you want the bounding box - to be included in the returned GeoJSON. -===================== ===================================================== - -__ http://geojson.org/ - -``gml`` -~~~~~~~ - -.. method:: GeoQuerySet.gml(**kwargs) - -*Availability*: PostGIS, Oracle - -Attaches a ``gml`` attribute to every model in the queryset that contains the -`Geographic Markup Language (GML)`__ representation of the geometry. - -Example:: - - >>> qs = Zipcode.objects.all().gml() - >>> print qs[0].gml - <gml:Polygon srsName="EPSG:4326"><gml:OuterBoundaryIs>-147.78711,70.245363 ... -147.78711,70.245363</gml:OuterBoundaryIs></gml:Polygon> - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``precision`` This keyword is for PostGIS only. It may be used - to specify the number of significant digits for the - coordinates in the GML representation -- the default - value is 8. - -``version`` This keyword is for PostGIS only. It may be used to - specify the GML version used, and may only be values - of 2 or 3. The default value is 2. -===================== ===================================================== - -__ http://en.wikipedia.org/wiki/Geography_Markup_Language - -``kml`` -~~~~~~~ - -.. method:: GeoQuerySet.kml(**kwargs) - -*Availability*: PostGIS - -Attaches a ``kml`` attribute to every model in the queryset that contains the -`Keyhole Markup Language (KML)`__ representation of the geometry fields. It -should be noted that the contents of the KML are transformed to WGS84 if -necessary. - -Example:: - - >>> qs = Zipcode.objects.all().kml() - >>> print qs[0].kml - <Polygon><outerBoundaryIs><LinearRing><coordinates>-103.04135,36.217596,0 ... -103.04135,36.217596,0</coordinates></LinearRing></outerBoundaryIs></Polygon> - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``precision`` This keyword may be used to specify the number of - significant digits for the coordinates in the KML - representation -- the default value is 8. -===================== ===================================================== - -__ http://code.google.com/apis/kml/documentation/ - -``svg`` -~~~~~~~ - -.. method:: GeoQuerySet.svg(**kwargs) - -*Availability*: PostGIS, SpatiaLite - -Attaches a ``svg`` attribute to every model in the queryset that contains -the `Scalable Vector Graphics (SVG)`__ path data of the geometry fields. - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``relative`` If set to ``True``, the path data will be implemented - in terms of relative moves. Defaults to ``False``, - meaning that absolute moves are used instead. - -``precision`` This keyword may be used to specify the number of - significant digits for the coordinates in the SVG - representation -- the default value is 8. -===================== ===================================================== - -__ http://www.w3.org/Graphics/SVG/ - -Miscellaneous -------------- - -``mem_size`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.mem_size(**kwargs) - -*Availability*: PostGIS - -Returns the memory size (number of bytes) that the geometry field takes -in a ``mem_size`` attribute on each element of the ``GeoQuerySet``. - -``num_geom`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.num_geom(**kwargs) - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns the number of geometries in a ``num_geom`` attribute on -each element of the ``GeoQuerySet`` if the geometry field is a -collection (e.g., a ``GEOMETRYCOLLECTION`` or ``MULTI*`` field); -otherwise sets with ``None``. - -``num_points`` -~~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.num_points(**kwargs) - -*Availability*: PostGIS, Oracle, SpatiaLite - -Returns the number of points in the first linestring in the -geometry field in a ``num_points`` attribute on each element of -the ``GeoQuerySet``; otherwise sets with ``None``. - -Spatial Aggregates -================== -.. versionadded:: 1.1 - -Aggregate Methods ------------------ - -``collect`` -~~~~~~~~~~~ - -.. method:: GeoQuerySet.collect(**kwargs) - -.. versionadded:: 1.1 - -*Availability*: PostGIS - -Returns a ``GEOMETRYCOLLECTION`` or a ``MULTI`` geometry object from the geometry -column. This is analagous to a simplified version of the :meth:`GeoQuerySet.unionagg` method, -except it can be several orders of magnitude faster than peforming a union because -it simply rolls up geometries into a collection or multi object, not caring about -dissolving boundaries. - -``extent`` -~~~~~~~~~~ - -.. method:: GeoQuerySet.extent(**kwargs) - -*Availability*: PostGIS, Oracle - -Returns the extent of the ``GeoQuerySet`` as a four-tuple, comprising the -lower left coordinate and the upper right coordinate. - -Example:: - - >>> qs = City.objects.filter(name__in=('Houston', 'Dallas')) - >>> print qs.extent() - (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820) - -``extent3d`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.extent3d(**kwargs) - -.. versionadded:: 1.2 - -*Availability*: PostGIS - -Returns the 3D extent of the ``GeoQuerySet`` as a six-tuple, comprising -the lower left coordinate and upper right coordinate. - -Example:: - - >>> qs = City.objects.filter(name__in=('Houston', 'Dallas')) - >>> print qs.extent3d() - (-96.8016128540039, 29.7633724212646, 0, -95.3631439208984, 32.782058715820, 0) - -``make_line`` -~~~~~~~~~~~~~ - -.. method:: GeoQuerySet.make_line(**kwargs) - -*Availability*: PostGIS - -Returns a ``LineString`` constructed from the point field geometries in the -``GeoQuerySet``. Currently, ordering the queryset has no effect. - -Example:: - - >>> print City.objects.filter(name__in=('Houston', 'Dallas')).make_line() - LINESTRING (-95.3631510000000020 29.7633739999999989, -96.8016109999999941 32.7820570000000018) - -``unionagg`` -~~~~~~~~~~~~ - -.. method:: GeoQuerySet.unionagg(**kwargs) - -*Availability*: PostGIS, Oracle, SpatiaLite - -This method returns a :class:`~django.contrib.gis.geos.GEOSGeometry` object -comprising the union of every geometry in the queryset. Please note that -use of ``unionagg`` is processor intensive and may take a significant amount -of time on large querysets. - -.. note:: - - If the computation time for using this method is too expensive, - consider using :meth:`GeoQuerySet.collect` instead. - -Example:: - - >>> u = Zipcode.objects.unionagg() # This may take a long time. - >>> u = Zipcode.objects.filter(poly__within=bbox).unionagg() # A more sensible approach. - -===================== ===================================================== -Keyword Argument Description -===================== ===================================================== -``tolerance`` This keyword is for Oracle only. It is for the - tolerance value used by the ``SDOAGGRTYPE`` - procedure; the `Oracle documentation`__ has more - details. -===================== ===================================================== - -__ http://download.oracle.com/docs/html/B14255_01/sdo_intro.htm#sthref150 - -Aggregate Functions -------------------- - -Example:: - - >>> from django.contrib.gis.db.models import Extent, Union - >>> WorldBorders.objects.aggregate(Extent('mpoly'), Union('mpoly')) - -``Collect`` -~~~~~~~~~~~ - -.. class:: Collect(geo_field) - -Returns the same as the :meth:`GeoQuerySet.collect` aggregate method. - -``Extent`` -~~~~~~~~~~ -.. class:: Extent(geo_field) - - -Returns the same as the :meth:`GeoQuerySet.extent` aggregate method. - -``Extent3D`` -~~~~~~~~~~~~ - -.. class:: Extent3D(geo_field) - -.. versionadded:: 1.2 - -Returns the same as the :meth:`GeoQuerySet.extent3d` aggregate method. - -``MakeLine`` -~~~~~~~~~~~~ - -.. class:: MakeLine(geo_field) - -Returns the same as the :meth:`GeoQuerySet.make_line` aggregate method. - -``Union`` -~~~~~~~~~ - -.. class:: Union(geo_field) - -Returns the same as the :meth:`GeoQuerySet.union` aggregate method. - -.. rubric:: Footnotes -.. [#fnde9im] *See* `OpenGIS Simple Feature Specification For SQL <http://www.opengis.org/docs/99-049.pdf>`_, at Ch. 2.1.13.2, p. 2-13 (The Dimensionally Extended Nine-Intersection Model). -.. [#fnsdorelate] *See* `SDO_RELATE documentation <http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14255/sdo_operat.htm#sthref845>`_, from Ch. 11 of the Oracle Spatial User's Guide and Manual. -.. [#fncovers] For an explanation of this routine, read `Quirks of the "Contains" Spatial Predicate <http://lin-ear-th-inking.blogspot.com/2007/06/subtleties-of-ogc-covers-spatial.html>`_ by Martin Davis (a PostGIS developer). -.. [#fncontainsproperly] Refer to the PostGIS ``ST_ContainsProperly`` `documentation <http://postgis.refractions.net/documentation/manual-1.4/ST_ContainsProperly.html>`_ for more details. diff --git a/parts/django/docs/ref/contrib/gis/geos.txt b/parts/django/docs/ref/contrib/gis/geos.txt deleted file mode 100644 index 06a88a8..0000000 --- a/parts/django/docs/ref/contrib/gis/geos.txt +++ /dev/null @@ -1,911 +0,0 @@ -.. _ref-geos: - -======== -GEOS API -======== - -.. module:: django.contrib.gis.geos - :synopsis: GeoDjango's high-level interface to the GEOS library. - -Background -========== - -What is GEOS? -------------- - -`GEOS`__ stands for **G**\ eometry **E**\ ngine - **O**\ pen **S**\ ource, -and is a C++ library, ported from the `Java Topology Suite`__. GEOS -implements the OpenGIS `Simple Features for SQL`__ spatial predicate functions -and spatial operators. GEOS, now an OSGeo project, was initially developed and -maintained by `Refractions Research`__ of Victoria, Canada. - -__ http://trac.osgeo.org/geos/ -__ http://sourceforge.net/projects/jts-topo-suite/ -__ http://www.opengeospatial.org/standards/sfs -__ http://www.refractions.net/ - -Features --------- - -GeoDjango implements a high-level Python wrapper for the GEOS library, its -features include: - -* A BSD-licensed interface to the GEOS geometry routines, implemented purely - in Python using ``ctypes``. -* Loosely-coupled to GeoDjango. For example, :class:`GEOSGeometry` objects - may be used outside of a django project/application. In other words, - no need to have ``DJANGO_SETTINGS_MODULE`` set or use a database, etc. -* Mutability: :class:`GEOSGeometry` objects may be modified. -* Cross-platform and tested; compatible with Windows, Linux, Solaris, and Mac - OS X platforms. - -.. _geos-tutorial: - -Tutorial -======== - -This section contains a brief introduction and tutorial to using -:class:`GEOSGeometry` objects. - -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:: - - >>> from django.contrib.gis.geos import GEOSGeometry - >>> pnt = GEOSGeometry('POINT(5 23)') # WKT - >>> pnt = GEOSGeometry('010100000000000000000014400000000000003740') # HEX - >>> pnt = GEOSGeometry(buffer('\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x007@')) - >>> pnt = GEOSGeometry('{ "type": "Point", "coordinates": [ 5.000000, 23.000000 ] }') # 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:: - - >>> from django.contrib.gis.geos import Point - >>> pnt = Point(5, 23) - -Finally, there are :func:`fromstr` and :func:`fromfile` factory methods, which -return a :class:`GEOSGeometry` object from an input string or a file:: - - >>> from django.contrib.gis.geos import fromstr, fromfile - >>> pnt = fromstr('POINT(5 23)') - >>> pnt = fromfile('/path/to/pnt.wkt') - >>> pnt = fromfile(open('/path/to/pnt.wkt')) - -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`:: - - >>> 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:: - - >>> pnt.coords - (5.0, 23.0) - -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:: - - >>> from django.contrib.gis.geos import LineString - >>> line = LineString((0, 0), (0, 50), (50, 50), (50, 0), (0, 0)) - >>> line[0] - (0.0, 0.0) - >>> line[-2] - (50.0, 0.0) - -Whereas indexing on a :class:`Polygon` will return the ring -(a :class:`LinearRing` object) corresponding to the index:: - - >>> 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)) ) - >>> poly[0] - <LinearRing object at 0x1044395b0> - >>> poly[0][-2] # second-to-last coordinate of external ring - (50.0, 0.0) - -In addition, coordinates/components of the geometry may added or modified, -just like a Python list:: - - >>> line[0] = (1.0, 1.0) - >>> line.pop() - (0.0, 0.0) - >>> line.append((1.0, 1.0)) - >>> line.coords - ((1.0, 1.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (1.0, 1.0)) - -Geometry Objects -================ - -``GEOSGeometry`` ----------------- - -.. class:: GEOSGeometry(geo_input[, srid=None]) - - :param geo_input: Geometry input value - :type geo_input: string or buffer - :param srid: spatial reference identifier - :type srid: integer - -This is the base class for all GEOS geometry objects. It initializes on the -given ``geo_input`` argument, and then assumes the proper geometry subclass -(e.g., ``GEOSGeometry('POINT(1 1)')`` will create a :class:`Point` object). - -The following input formats, along with their corresponding Python types, -are accepted: - -============= ====================== -Format Input Type -============= ====================== -WKT / EWKT ``str`` or ``unicode`` -HEX / HEXEWKB ``str`` or ``unicode`` -WKB / EWKB ``buffer`` -GeoJSON ``str`` or ``unicode`` -============= ====================== - -Properties -~~~~~~~~~~ - -.. attribute:: GEOSGeometry.coords - -Returns the coordinates of the geometry as a tuple. - -.. attribute:: GEOSGeometry.empty - -Returns whether or not the set of points in the geometry is empty. - -.. attribute:: GEOSGeometry.geom_type - -Returns a string corresponding to the type of geometry. For example:: - - >>> pnt = GEOSGeometry('POINT(5 23)') - >>> pnt.geom_type - 'Point' - -.. attribute:: GEOSGeometry.geom_typeid - -Returns the GEOS geometry type identification number. The following table -shows the value for each geometry type: - -=========================== ======== -Geometry ID -=========================== ======== -:class:`Point` 0 -:class:`LineString` 1 -:class:`LinearRing` 2 -:class:`Polygon` 3 -:class:`MultiPoint` 4 -:class:`MultiLineString` 5 -:class:`MultiPolygon` 6 -:class:`GeometryCollection` 7 -=========================== ======== - -.. attribute:: GEOSGeometry.num_coords - -Returns the number of coordinates in the geometry. - -.. attribute:: GEOSGeometry.num_geom - -Returns the number of geometries in this geometry. In other words, will -return 1 on anything but geometry collections. - -.. attribute:: GEOSGeometry.hasz - -Returns a boolean indicating whether the geometry is three-dimensional. - -.. attribute:: GEOSGeometry.ring - -Returns a boolean indicating whether the geometry is a ``LinearRing``. - -.. attribute:: GEOSGeometry.simple - -Returns a boolean indicating whether the geometry is 'simple'. A geometry -is simple if and only if it does not intersect itself (except at boundary -points). For example, a :class:`LineString` object is not simple if it -intersects itself. Thus, :class:`LinearRing` and :class`Polygon` objects -are always simple because they do cannot intersect themselves, by -definition. - -.. attribute:: GEOSGeometry.valid - -Returns a boolean indicating whether the geometry is valid. - -.. attribute:: GEOSGeometry.srid - -Property that may be used to retrieve or set the SRID associated with the -geometry. For example:: - - >>> pnt = Point(5, 23) - >>> print pnt.srid - None - >>> pnt.srid = 4326 - >>> pnt.srid - 4326 - -Output Properties -~~~~~~~~~~~~~~~~~ - -The properties in this section export the :class:`GEOSGeometry` object into -a different. This output may be in the form of a string, buffer, or even -another object. - -.. attribute:: GEOSGeometry.ewkt - -Returns the "extended" Well-Known Text of the geometry. This representation -is specific to PostGIS and is a super set of the OGC WKT standard. [#fnogc]_ -Essentially the SRID is prepended to the WKT representation, for example -``SRID=4326;POINT(5 23)``. - -.. note:: - - The output from this property does not include the 3dm, 3dz, and 4d - information that PostGIS supports in its EWKT representations. - -.. attribute:: GEOSGeometry.hex - -Returns the WKB of this Geometry in hexadecimal form. Please note -that the SRID and Z values are not included in this representation -because it is not a part of the OGC specification (use the -:attr:`GEOSGeometry.hexewkb` property instead). - -.. attribute:: GEOSGeometry.hexewkb - -.. versionadded:: 1.2 - -Returns the EWKB of this Geometry in hexadecimal form. This is an -extension of the WKB specification that includes SRID and Z values -that are a part of this geometry. - -.. note:: - - GEOS 3.1 is *required* if you want valid 3D HEXEWKB. - -.. attribute:: GEOSGeometry.json - -Returns the GeoJSON representation of the geometry. - -.. note:: - - Requires GDAL. - -.. attribute:: GEOSGeometry.geojson - -Alias for :attr:`GEOSGeometry.json`. - -.. attribute:: GEOSGeometry.kml - -Returns a `KML`__ (Keyhole Markup Language) representation of the -geometry. This should only be used for geometries with an SRID of -4326 (WGS84), but this restriction is not enforced. - -.. attribute:: GEOSGeometry.ogr - -Returns an :class:`~django.contrib.gis.gdal.OGRGeometry` object -correspondg to the GEOS geometry. - -.. note:: - - Requires GDAL. - -.. _wkb: - -.. attribute:: GEOSGeometry.wkb - -Returns the WKB (Well-Known Binary) representation of this Geometry -as a Python buffer. SRID and Z values are not included, use the -:attr:`GEOSGeometry.ewkb` property instead. - -.. _ewkb: - -.. attribute:: GEOSGeometry.ewkb - -.. versionadded:: 1.2 - -Return the EWKB representation of this Geometry as a Python buffer. -This is an extension of the WKB specification that includes any SRID -and Z values that are a part of this geometry. - -.. note:: - - GEOS 3.1 is *required* if you want valid 3D EWKB. - -.. attribute:: GEOSGeometry.wkt - -Returns the Well-Known Text of the geometry (an OGC standard). - -__ http://code.google.com/apis/kml/documentation/ - -Spatial Predicate Methods -~~~~~~~~~~~~~~~~~~~~~~~~~ - -All of the following spatial predicate methods take another -:class:`GEOSGeometry` instance (``other``) as a parameter, and -return a boolean. - -.. method:: GEOSGeometry.contains(other) - -Returns ``True`` if :meth:`GEOSGeometry.within` is ``False``. - -.. method:: GEOSGeometry.crosses(other) - -Returns ``True`` if the DE-9IM intersection matrix for the two Geometries -is ``T*T******`` (for a point and a curve,a point and an area or a line -and an area) ``0********`` (for two curves). - -.. method:: GEOSGeometry.disjoint(other) - -Returns ``True`` if the DE-9IM intersection matrix for the two geometries -is ``FF*FF****``. - -.. method:: GEOSGeometry.equals(other) - -Returns ``True`` if the DE-9IM intersection matrix for the two geometries -is ``T*F**FFF*``. - -.. method:: GEOSGeometry.equals_exact(other, tolerance=0) - -Returns true if the two geometries are exactly equal, up to a -specified tolerance. The ``tolerance`` value should be a floating -point number representing the error tolerance in the comparison, e.g., -``poly1.equals_exact(poly2, 0.001)`` will compare equality to within -one thousandth of a unit. - -.. method:: GEOSGeometry.intersects(other) - -Returns ``True`` if :meth:`GEOSGeometry.disjoint` is ``False``. - -.. method:: GEOSGeometry.overlaps(other) - -Returns true if the DE-9IM intersection matrix for the two geometries -is ``T*T***T**`` (for two points or two surfaces) ``1*T***T**`` -(for two curves). - -.. method:: GEOSGeometry.relate_pattern(other, pattern) - -Returns ``True`` if the elements in the DE-9IM intersection matrix -for this geometry and the other matches the given ``pattern`` -- -a string of nine characters from the alphabet: {``T``, ``F``, ``*``, ``0``}. - -.. method:: GEOSGeometry.touches(other) - -Returns ``True`` if the DE-9IM intersection matrix for the two geometries -is ``FT*******``, ``F**T*****`` or ``F***T****``. - -.. method:: GEOSGeometry.within(other) - -Returns ``True`` if the DE-9IM intersection matrix for the two geometries -is ``T*F**F***``. - -Topological Methods -~~~~~~~~~~~~~~~~~~~ - -.. method:: GEOSGeometry.buffer(width, quadsegs=8) - -Returns a :class:`GEOSGeometry` that represents all points whose distance -from this geometry is less than or equal to the given ``width``. The optional -``quadsegs`` keyword sets the number of segments used to approximate a -quarter circle (defaults is 8). - -.. method:: GEOSGeometry.difference(other) - -Returns a :class:`GEOSGeometry` representing the points making up this -geometry that do not make up other. - -.. method:: GEOSGeometry:intersection(other) - -Returns a :class:`GEOSGeometry` representing the points shared by this -geometry and other. - -.. method:: GEOSGeometry.relate(other) - -Returns the DE-9IM intersection matrix (a string) representing the -topological relationship between this geometry and the other. - -.. method:: GEOSGeometry.simplify(tolerance=0.0, preserve_topology=False) - -Returns a new :class:`GEOSGeometry`, simplified using the Douglas-Peucker -algorithm to the specified tolerance. A higher tolerance value implies -less points in the output. If no tolerance is tolerance provided, -it defaults to 0. - -By default, this function does not preserve topology - e.g., -:class:`Polygon` objects can be split, collapsed into lines or disappear. -:class:`Polygon` holes can be created or disappear, and lines can cross. -By specifying ``preserve_topology=True``, the result will have the same -dimension and number of components as the input, however, this is -significantly slower. - -.. method:: GEOSGeometry.sym_difference(other) - -Returns a :class:`GEOSGeometry` combining the points in this geometry -not in other, and the points in other not in this geometry. - -.. method:: GEOSGeometry.union(other) - -Returns a :class:`GEOSGeometry` representing all the points in this -geometry and the other. - -Topological Properties -~~~~~~~~~~~~~~~~~~~~~~ - -.. attribute:: GEOSGeometry.boundary - -Returns the boundary as a newly allocated Geometry object. - -.. attribute:: GEOSGeometry.centroid - -Returns a :class:`Point` object representing the geometric center of -the geometry. The point is not guaranteed to be on the interior -of the geometry. - -.. attribute:: GEOSGeometry.convex_hull - -Returns the smallest :class:`Polygon` that contains all the points in -the geometry. - -.. attribute:: GEOSGeometry.envelope - -Returns a :class:`Polygon` that represents the bounding envelope of -this geometry. - -.. attribute:: GEOSGeometry.point_on_surface - -Computes and returns a :class:`Point` guaranteed to be on the interior -of this geometry. - -Other Properties & Methods -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. attribute:: GEOSGeometry.area - -This property returns the area of the Geometry. - -.. attribute:: GEOSGeometry.extent - -This property returns the extent of this geometry as a 4-tuple, -consisting of (xmin, ymin, xmax, ymax). - -.. method:: GEOSGeometry.clone() - -This method returns a :class:`GEOSGeometry` that is a clone of the original. - -.. method:: GEOSGeometry.distance(geom) - -Returns the distance between the closest points on this geometry and the given -``geom`` (another :class:`GEOSGeometry` object). - -.. note:: - - GEOS distance calculations are linear -- in other words, GEOS does not - perform a spherical calculation even if the SRID specifies a geographic - coordinate system. - -.. attribute:: GEOSGeometry.length - -Returns the length of this geometry (e.g., 0 for a :class:`Point`, -the length of a :class:`LineString`, or the circumference of -a :class:`Polygon`). - -.. attribute:: GEOSGeometry.prepared - -.. versionadded:: 1.1 - -.. note:: - - Support for prepared geometries requires GEOS 3.1. - -Returns a GEOS ``PreparedGeometry`` for the contents of this geometry. -``PreparedGeometry`` objects are optimized for the contains, intersects, -and covers operations. Refer to the :ref:`prepared-geometries` documentation -for more information. - -.. attribute:: GEOSGeometry.srs - -Returns a :class:`~django.contrib.gis.gdal.SpatialReference` object -corresponding to the SRID of the geometry or ``None``. - -.. note:: - - Requires GDAL. - -.. method:: transform(ct, clone=False) - -Transforms the geometry according to the given coordinate transformation paramter -(``ct``), which may be an integer SRID, spatial reference WKT string, -a PROJ.4 string, a :class:`~django.contrib.gis.gdal.SpatialReference` object, or a -:class:`~django.contrib.gis.gdal.CoordTransform` object. By default, the geometry -is transformed in-place and nothing is returned. However if the ``clone`` keyword -is set, then the geometry is not modified and a transformed clone of the geometry -is returned instead. - -.. note:: - - Requires GDAL. - -``Point`` ---------- - -.. class:: Point(x, y, z=None, srid=None) - - ``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:: - - >>> pnt = Point(5, 23) - >>> pnt = Point([5, 23]) - -``LineString`` --------------- - -.. class:: LineString(*args, **kwargs) - - ``LineString`` objects are instantiated using arguments that are - either a sequence of coordinates or :class:`Point` objects. - For example, the following are equivalent:: - - >>> 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:: - - >>> ls = LineString( ((0, 0), (1, 1)) ) - >>> ls = LineString( [Point(0, 0), Point(1, 1)] ) - -``LinearRing`` --------------- - -.. class:: LinearRing(*args, **kwargs) - - ``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:: - - >>> ls = LinearRing((0, 0), (0, 1), (1, 1), (0, 0)) - - Notice that ``(0, 0)`` is the first and last coordinate -- if - they were not equal, an error would be raised. - -``Polygon`` ------------ - -.. class:: Polygon(*args, **kwargs) - - ``Polygon`` objects may be instantiated by passing in one or - more 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`:: - - >>> 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)) - >>> poly = Polygon(ext_coords, int_coords) - >>> poly = Polygon(LinearRing(ext_coords), LinearRing(int_coords)) - - .. classmethod:: from_bbox(bbox) - - .. versionadded:: 1.1 - - Returns a polygon object from the given bounding-box, a 4-tuple - comprising (xmin, ymin, xmax, ymax). - - .. attribute:: num_interior_rings - - Returns the number of interior rings in this geometry. - -Geometry Collections -==================== - -``MultiPoint`` --------------- - -.. class:: MultiPoint(*args, **kwargs) - - ``MultiPoint`` objects may be instantiated by passing in one - or more :class:`Point` objects as arguments, or a single - sequence of :class:`Point` objects:: - - >>> mp = MultiPoint(Point(0, 0), Point(1, 1)) - >>> mp = MultiPoint( (Point(0, 0), Point(1, 1)) ) - -``MultiLineString`` -------------------- - -.. class:: MultiLineString(*args, **kwargs) - - ``MultiLineString`` objects may be instantiated by passing in one - or more :class:`LineString` objects as arguments, or a single - sequence of :class:`LineString` objects:: - - >>> ls1 = LineString((0, 0), (1, 1)) - >>> ls2 = LineString((2, 2), (3, 3)) - >>> mls = MultiLineString(ls1, ls2) - >>> mls = MultiLineString([ls1, ls2]) - - .. attribute:: merged - - .. versionadded:: 1.1 - - Returns a :class:`LineString` representing the line merge of - all the components in this ``MultiLineString``. - - -``MultiPolygon`` ----------------- - -.. class:: MultiPolygon(*args, **kwargs) - - ``MultiPolygon`` objects may be instantiated by passing one or - more :class:`Polygon` objects as arguments, or a single sequence - of :class:`Polygon` objects:: - - >>> p1 = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) ) - >>> p2 = Polygon( ((1, 1), (1, 2), (2, 2), (1, 1)) ) - >>> mp = MultiPolygon(p1, p2) - >>> mp = MultiPolygon([p1, p2]) - - .. attribute:: cascaded_union - - .. versionadded:: 1.1 - - Returns a :class:`Polygon` that is the union of all of the component - polygons in this collection. The algorithm employed is significantly - more efficient (faster) than trying to union the geometries together - individually. [#fncascadedunion]_ - - .. note:: - - GEOS 3.1 is *required* to peform cascaded unions. - -``GeometryCollection`` ----------------------- - -.. class:: GeometryCollection(*args, **kwargs) - - ``GeometryCollection`` objects may be instantiated by passing in - one or more other :class:`GEOSGeometry` as arguments, or a single - sequence of :class:`GEOSGeometry` objects:: - - >>> poly = Polygon( ((0, 0), (0, 1), (1, 1), (0, 0)) ) - >>> gc = GeometryCollection(Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly) - >>> gc = GeometryCollection((Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly)) - -.. _prepared-geometries: - -Prepared Geometries -=================== - -.. versionadded: 1.1 - -In order to obtain a prepared geometry, just access the -:attr:`GEOSGeometry.prepared` property. Once you have a -``PreparedGeometry`` instance its spatial predicate methods, listed below, -may be used with other ``GEOSGeometry`` objects. An operation with a prepared -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 <http://trac.osgeo.org/geos/wiki/PreparedGeometry>`_. - -.. note:: - - GEOS 3.1 is *required* in order to use prepared geometries. - -For example:: - - >>> from django.contrib.gis.geos import Point, Polygon - >>> poly = Polygon.from_bbox((0, 0, 5, 5)) - >>> prep_poly = poly.prepared - >>> prep_poly.contains(Point(2.5, 2.5)) - True - -``PreparedGeometry`` --------------------- - -.. class:: PreparedGeometry - - All methods on ``PreparedGeometry`` take an ``other`` argument, which - must be a :class:`GEOSGeometry` instance. - - .. method:: contains(other) - - .. method:: contains_properly(other) - - .. method:: covers(other) - - .. method:: intersects(other) - -Geometry Factories -================== - -.. function:: fromfile(file_h) - - :param file_h: input file that contains spatial data - :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:: - - >>> from django.contrib.gis.geos import fromfile - >>> g = fromfile('/home/bob/geom.wkt') - -.. function:: fromstr(string, [,srid=None]) - - :param string: string that contains spatial data - :type string: string - :param srid: spatial reference identifier - :type srid: integer - :rtype: a :class:`GEOSGeometry` corresponding to the spatial data in the string - -Example:: - - >>> from django.contrib.gis.geos import fromstr - >>> pnt = fromstr('POINT(-90.5 29.5)', srid=4326) - -I/O Objects -=========== - -.. versionadded: 1.1 - -Reader Objects --------------- - -The reader I/O classes simply return a :class:`GEOSGeometry` instance from the -WKB and/or WKT input given to their ``read(geom)`` method. - -.. class:: WKBReader - -Example:: - - >>> from django.contrib.gis.geos import WKBReader - >>> wkb_r = WKBReader() - >>> wkb_r.read('0101000000000000000000F03F000000000000F03F') - <Point object at 0x103a88910> - -.. class:: WKTReader - -Example:: - - >>> from django.contrib.gis.geos import WKTReader - >>> wkt_r = WKTReader() - >>> wkt_r.read('POINT(1 1)') - <Point object at 0x103a88b50> - -Writer Objects --------------- - -All writer objects have a ``write(geom)`` method that returns either the -WKB or WKT of the given geometry. In addition, :class:`WKBWriter` objects -also have properties that may be used to change the byte order, and or -include the SRID and 3D values (in other words, EWKB). - -.. class:: WKBWriter - -``WKBWriter`` provides the most control over its output. By default it -returns OGC-compliant WKB when it's ``write`` method is called. However, -it has properties that allow for the creation of EWKB, a superset of the -WKB standard that includes additional information. - -.. method:: WKBWriter.write(geom) - -Returns the WKB of the given geometry as a Python ``buffer`` object. -Example:: - - >>> from django.contrib.gis.geos import Point, WKBWriter - >>> pnt = Point(1, 1) - >>> wkb_w = WKBWriter() - >>> wkb_w.write(pnt) - <read-only buffer for 0x103a898f0, size -1, offset 0 at 0x103a89930> - -.. method:: WKBWriter.write_hex(geom) - -Returns WKB of the geometry in hexadecimal. Example:: - - >>> from django.contrib.gis.geos import Point, WKBWriter - >>> pnt = Point(1, 1) - >>> wkb_w = WKBWriter() - >>> wkb_w.write_hex(pnt) - '0101000000000000000000F03F000000000000F03F' - -.. attribute:: WKBWriter.byteorder - -This property may be be set to change the byte-order of the geometry -representation. - -=============== ================================================= -Byteorder Value Description -=============== ================================================= -0 Big Endian (e.g., compatible with RISC systems) -1 Little Endian (e.g., compatible with x86 systems) -=============== ================================================= - -Example:: - - >>> from django.contrib.gis.geos import Point, WKBWriter - >>> wkb_w = WKBWriter() - >>> pnt = Point(1, 1) - >>> wkb_w.write_hex(pnt) - '0101000000000000000000F03F000000000000F03F' - >>> wkb_w.byteorder = 0 - '00000000013FF00000000000003FF0000000000000' - -.. attribute:: WKBWriter.outdim - -This property may be set to change the output dimension of the geometry -representation. In other words, if you have a 3D geometry then set to 3 -so that the Z value is included in the WKB. - -============ =========================== -Outdim Value Description -============ =========================== -2 The default, output 2D WKB. -3 Output 3D EWKB. -============ =========================== - -Example:: - - >>> from django.contrib.gis.geos import Point, WKBWriter - >>> wkb_w = WKBWriter() - >>> wkb_w.outdim - 2 - >>> pnt = Point(1, 1, 1) - >>> wkb_w.write_hex(pnt) # By default, no Z value included: - '0101000000000000000000F03F000000000000F03F' - >>> wkb_w.outdim = 3 # Tell writer to include Z values - >>> wkb_w.write_hex(pnt) - '0101000080000000000000F03F000000000000F03F000000000000F03F' - -.. 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:: - - >>> from django.contrib.gis.geos import Point, WKBWriter - >>> wkb_w = WKBWriter() - >>> pnt = Point(1, 1, srid=4326) - >>> wkb_w.write_hex(pnt) # By default, no SRID included: - '0101000000000000000000F03F000000000000F03F' - >>> wkb_w.srid = True # Tell writer to include SRID - >>> wkb_w.write_hex(pnt) - '0101000020E6100000000000000000F03F000000000000F03F' - -.. class:: WKTWriter - -.. method:: WKTWriter.write(geom) - -Returns the WKT of the given geometry. Example:: - - >>> from django.contrib.gis.geos import Point, WKTWriter - >>> pnt = Point(1, 1) - >>> wkt_w = WKTWriter() - >>> wkt_w.write(pnt) - 'POINT (1.0000000000000000 1.0000000000000000)' - - -.. rubric:: Footnotes -.. [#fnogc] *See* `PostGIS EWKB, EWKT and Canonical Forms <http://postgis.refractions.net/docs/ch04.html#id2591381>`_, PostGIS documentation at Ch. 4.1.2. -.. [#fncascadedunion] For more information, read Paul Ramsey's blog post about `(Much) Faster Unions in PostGIS 1.4 <http://blog.cleverelephant.ca/2009/01/must-faster-unions-in-postgis-14.html>`_ and Martin Davis' blog post on `Fast polygon merging in JTS using Cascaded Union <http://lin-ear-th-inking.blogspot.com/2007/11/fast-polygon-merging-in-jts-using.html>`_. - -Settings -======== - -.. setting:: GEOS_LIBRARY_PATH - -GEOS_LIBRARY_PATH ------------------ - -A string specifying the location of the GEOS C library. Typically, -this setting is only used if the GEOS C library is in a non-standard -location (e.g., ``/home/bob/lib/libgeos_c.so``). - -.. note:: - - The setting must be the *full* path to the **C** shared library; in - other words you want to use ``libgeos_c.so``, not ``libgeos.so``. diff --git a/parts/django/docs/ref/contrib/gis/index.txt b/parts/django/docs/ref/contrib/gis/index.txt deleted file mode 100644 index c4959e0..0000000 --- a/parts/django/docs/ref/contrib/gis/index.txt +++ /dev/null @@ -1,33 +0,0 @@ -.. _ref-contrib-gis: - -========= -GeoDjango -========= - -.. versionadded:: 1.0 - -.. module:: django.contrib.gis - :synopsis: Geographic Information System (GIS) extensions for Django - -GeoDjango intends to be a world-class geographic Web framework. Its goal is to -make it as easy as possible to build GIS Web applications and harness the power -of spatially enabled data. - -.. toctree:: - :maxdepth: 2 - - tutorial - install - model-api - db-api - geoquerysets - measure - geos - gdal - utils - commands - admin - feeds - sitemaps - testing - deployment diff --git a/parts/django/docs/ref/contrib/gis/install.txt b/parts/django/docs/ref/contrib/gis/install.txt deleted file mode 100644 index fa8e34c..0000000 --- a/parts/django/docs/ref/contrib/gis/install.txt +++ /dev/null @@ -1,1190 +0,0 @@ -.. _ref-gis-install: - -====================== -GeoDjango Installation -====================== - -Overview -======== -In general, GeoDjango installation requires: - -1. :ref:`python24` and :ref:`django` -2. :ref:`spatial_database` -3. :ref:`geospatial_libs` - -Details for each of the requirements and installation instructions -are provided in the sections below. In addition, platform-specific -instructions are available for: - -* :ref:`macosx` -* :ref:`ubuntudebian` -* :ref:`windows` - -.. admonition:: Use the Source - - Because GeoDjango takes advantage of the latest in the open source geospatial - software technology, recent versions of the libraries are necessary. - If binary packages aren't available for your platform, - :ref:`installation from source <build_from_source>` - may be required. When compiling the libraries from source, please follow the - directions closely, especially if you're a beginner. - -Requirements -============ - -.. _python24: - -Python 2.4+ ------------ - -Python 2.4 is the minimum version supported by Django, however Python 2.5+ is -recommended because the `ctypes`__ module comes included; otherwise, 2.4 users -will need to `download and install ctypes`__. - -__ http://docs.python.org/lib/module-ctypes.html -__ http://sourceforge.net/projects/ctypes/files/ - -.. _django: - -Django ------- - -Because GeoDjango is included with Django, please refer to Django's -:doc:`installation instructions </intro/install>` for details on how to install. - -.. _spatial_database: - -Spatial Database ----------------- -PostgreSQL (with PostGIS), MySQL, Oracle, and SQLite (with SpatiaLite) are -the spatial databases currently supported. - -.. note:: - - PostGIS is recommended, because it is the most mature and feature-rich - open source spatial database. - -The geospatial libraries required for a GeoDjango installation depends -on the spatial database used. The following lists the library requirements, -supported versions, and any notes for each of the supported database backends: - -================== ============================== ================== ========================================================== -Database Library Requirements Supported Versions Notes -================== ============================== ================== ========================================================== -PostgreSQL GEOS, PROJ.4, PostGIS 8.1+ Requires PostGIS. -MySQL GEOS 5.x Not OGC-compliant; limited functionality. -Oracle GEOS 10.2, 11 XE not supported; not tested with 9. -SQLite GEOS, GDAL, PROJ.4, SpatiaLite 3.6.+ Requires SpatiaLite 2.3+, pysqlite2 2.5+, and Django 1.1. -================== ============================== ================== ========================================================== - -.. _geospatial_libs: - -Geospatial Libraries --------------------- -GeoDjango uses and/or provides interfaces for the the following open source -geospatial libraries: - -======================== ==================================== ================================ ========================== -Program Description Required Supported Versions -======================== ==================================== ================================ ========================== -:ref:`GEOS <ref-geos>` Geometry Engine Open Source Yes 3.2, 3.1, 3.0 -`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.7, 4.6, 4.5, 4.4 -:ref:`GDAL <ref-gdal>` Geospatial Data Abstraction Library No (but, required for SQLite) 1.7, 1.6, 1.5, 1.4 -:ref:`GeoIP <ref-geoip>` IP-based geolocation library No 1.4 -`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 1.5, 1.4, 1.3 -`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 2.4, 2.3 -======================== ==================================== ================================ ========================== - -.. admonition:: Install GDAL - - While :ref:`gdalbuild` is technically not required, it is *recommended*. - Some features of GeoDjango (including the :ref:`ref-layermapping` and the geographic - admin) depend on its functionality. - -.. note:: - - The GeoDjango interfaces to GEOS, GDAL, and GeoIP may be used - independently of Django. In other words, no database or settings file - required -- just import them as normal from :mod:`django.contrib.gis`. - -.. _PROJ.4: http://trac.osgeo.org/proj/ -__ http://postgis.refractions.net/ -__ http://www.gaia-gis.it/spatialite/index.html - -.. _build_from_source: - -Building from Source -==================== - -When installing from source on UNIX and GNU/Linux systems, please follow -the installation instructions carefully, and install the libraries in the -given order. If using MySQL or Oracle as the spatial database, only GEOS -is required. - -.. note:: - - On Linux platforms, it may be necessarry to run the ``ldconfig`` - command after installing each library. For example:: - - $ sudo make install - $ sudo ldconfig - -.. note:: - - OS X users are required to install `Apple Developer Tools`_ in order - to compile software from source. This is typically included on your - OS X installation DVDs. - -.. _Apple Developer Tools: http://developer.apple.com/tools/xcode/ - -.. _geosbuild: - -GEOS ----- - -GEOS is a C++ library for performing geometric operations, and is the default -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 3.2 from the refractions Web site and untar the source -archive:: - - $ wget http://download.osgeo.org/geos/geos-3.2.2.tar.bz2 - $ tar xjf geos-3.2.2.tar.bz2 - -Next, change into the directory where GEOS was unpacked, run the configure -script, compile, and install:: - - $ cd geos-3.2.2 - $ ./configure - $ make - $ sudo make install - $ cd .. - -Troubleshooting -^^^^^^^^^^^^^^^ - -Can't find GEOS Library -~~~~~~~~~~~~~~~~~~~~~~~ - -When GeoDjango can't find GEOS, this error is raised:: - - ImportError: Could not find the GEOS library (tried "geos_c"). Try setting GEOS_LIBRARY_PATH in your settings. - -The most common solution is to properly configure your :ref:`libsettings` *or* set -:ref:`geoslibrarypath` in your settings. - -If using a binary package of GEOS (e.g., on Ubuntu 8.10), you may need to :ref:`binutils`. - -.. _geoslibrarypath: - -``GEOS_LIBRARY_PATH`` -~~~~~~~~~~~~~~~~~~~~~ - -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_LIBRARY_PATH = '/home/bob/local/lib/libgeos_c.so' - -.. note:: - - The setting must be the *full* path to the **C** shared library; in - other words you want to use ``libgeos_c.so``, not ``libgeos.so``. - -.. _proj4: - -PROJ.4 ------- - -`PROJ.4`_ is a library for converting geospatial data to different coordinate -reference systems. - -First, download the PROJ.4 source code and datum shifting files [#]_:: - - $ wget http://download.osgeo.org/proj/proj-4.7.0.tar.gz - $ wget http://download.osgeo.org/proj/proj-datumgrid-1.5.zip - -Next, untar the source code archive, and extract the datum shifting files in the -``nad`` subdirectory. This must be done *prior* to configuration:: - - $ tar xzf proj-4.7.0.tar.gz - $ cd proj-4.7.0/nad - $ unzip ../../proj-datumgrid-1.5.zip - $ cd .. - -Finally, configure, make and install PROJ.4:: - - $ ./configure - $ make - $ sudo make install - $ cd .. - -.. _postgis: - -PostGIS -------- - -`PostGIS`__ adds geographic object support to PostgreSQL, turning it -into a spatial database. :ref:`geosbuild` and :ref:`proj4` should be -installed prior to building PostGIS. - -.. note:: - - The `psycopg2`_ module is required for use as the database adaptor - when using GeoDjango with PostGIS. - -.. _psycopg2: http://initd.org/projects/psycopg2 - -First download the source archive, and extract:: - - $ wget http://postgis.refractions.net/download/postgis-1.5.2.tar.gz - $ tar xzf postgis-1.5.2.tar.gz - $ cd postgis-1.5.2 - -Next, configure, make and install PostGIS:: - - $ ./configure - -Finally, make and install:: - - $ make - $ sudo make install - $ cd .. - -.. note:: - - GeoDjango does not automatically create a spatial database. Please - consult the section on :ref:`spatialdb_template` for more information. - -__ http://postgis.refractions.net/ - -.. _gdalbuild: - -GDAL ----- - -`GDAL`__ is an excellent open source geospatial library that has support for -reading most vector and raster spatial data formats. Currently, GeoDjango only -supports :ref:`GDAL's vector data <ref-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:: - - $ wget http://download.osgeo.org/gdal/gdal-1.7.2.tar.gz - $ tar xzf gdal-1.7.2.tar.gz - $ cd gdal-1.7.2 - -Configure, make and install:: - - $ ./configure - $ make # Go get some coffee, this takes a while. - $ sudo make install - $ cd .. - -.. note:: - - Because GeoDjango has it's own Python interface, the preceding instructions - do not build GDAL's own Python bindings. The bindings may be built by - adding the ``--with-python`` flag when running ``configure``. See - `GDAL/OGR In Python`__ for more information on GDAL's bindings. - -If you have any problems, please see the troubleshooting section below for -suggestions and solutions. - -__ http://trac.osgeo.org/gdal/ -__ http://trac.osgeo.org/gdal/wiki/GdalOgrInPython - -.. _gdaltrouble: - -Troubleshooting -^^^^^^^^^^^^^^^ - -Can't find GDAL Library -~~~~~~~~~~~~~~~~~~~~~~~ - -When GeoDjango can't find the GDAL library, the ``HAS_GDAL`` flag -will be false:: - - >>> from django.contrib.gis import gdal - >>> gdal.HAS_GDAL - False - -The solution is to properly configure your :ref:`libsettings` *or* set -:ref:`gdallibrarypath` in your settings. - -.. _gdallibrarypath: - -``GDAL_LIBRARY_PATH`` -~~~~~~~~~~~~~~~~~~~~~ - -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:: - - GDAL_LIBRARY_PATH = '/home/sue/local/lib/libgdal.so' - -.. _gdaldata: - -Can't find GDAL data files (``GDAL_DATA``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When installed from source, GDAL versions 1.5.1 and below have an autoconf bug -that places data in the wrong location. [#]_ This can lead to error messages -like this:: - - ERROR 4: Unable to open EPSG support file gcs.csv. - ... - OGRException: OGR failure. - -The solution is to set the ``GDAL_DATA`` environment variable to the location of the -GDAL data files before invoking Python (typically ``/usr/local/share``; use -``gdal-config --datadir`` to find out). For example:: - - $ export GDAL_DATA=`gdal-config --datadir` - $ python manage.py shell - -If using Apache, you may need to add this environment variable to your configuration -file:: - - SetEnv GDAL_DATA /usr/local/share - -.. _spatialite: - -SpatiaLite ----------- -.. versionadded:: 1.1 - -.. note:: - - Mac OS X users should follow the instructions in the :ref:`kyngchaos` section, - as it is much easier than building from source. - -`SpatiaLite`__ adds spatial support to SQLite, turning it into a full-featured -spatial database. Because SpatiaLite has special requirements, it typically -requires SQLite and pysqlite2 (the Python SQLite DB-API adaptor) to be built from -source. :ref:`geosbuild` and :ref:`proj4` should be installed prior to building -SpatiaLite. - -After installation is complete, don't forget to read the post-installation -docs on :ref:`create_spatialite_db`. - -__ http://www.gaia-gis.it/spatialite/index.html - -.. _sqlite: - -SQLite -^^^^^^ - -Typically, SQLite packages are not compiled to include the `R*Tree module`__ -- -thus it must be compiled from source. First download the latest amalgamation -source archive from the `SQLite download page`__, and extract:: - - $ wget http://sqlite.org/sqlite-amalgamation-3.6.23.1.tar.gz - $ tar xzf sqlite-amalgamation-3.6.23.1.tar.gz - $ cd sqlite-3.6.23.1 - -Next, run the ``configure`` script -- however the ``CFLAGS`` environment variable -needs to be customized so that SQLite knows to build the R*Tree module:: - - $ CFLAGS="-DSQLITE_ENABLE_RTREE=1" ./configure - $ make - $ sudo make install - $ cd .. - -.. note:: - - If using Ubuntu, installing a newer SQLite from source can be very difficult - because it links to the existing ``libsqlite3.so`` in ``/usr/lib`` which - many other packages depend on. Unfortunately, the best solution at this time - is to overwrite the existing library by adding ``--prefix=/usr`` to the - ``configure`` command. - -__ http://www.sqlite.org/rtree.html -__ http://www.sqlite.org/download.html - -.. _spatialitebuild : - -SpatiaLite Library (``libspatialite``) and Tools (``spatialite``) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -After SQLite has been built with the R*Tree module enabled, get the latest -SpatiaLite library source and tools bundle from the `download page`__:: - - $ wget http://www.gaia-gis.it/spatialite/libspatialite-amalgamation-2.3.1.tar.gz - $ wget http://www.gaia-gis.it/spatialite/spatialite-tools-2.3.1.tar.gz - $ tar xzf libspatialite-amalgamation-2.3.1.tar.gz - $ tar xzf spatialite-tools-2.3.1.tar.gz - -Prior to attempting to build, please read the important notes below to see if -customization of the ``configure`` command is necessary. If not, then run the -``configure`` script, make, and install for the SpatiaLite library:: - - $ cd libspatialite-amalgamation-2.3.1 - $ ./configure # May need to modified, see notes below. - $ make - $ sudo make install - $ cd .. - -Finally, do the same for the SpatiaLite tools:: - - $ cd spatialite-tools-2.3.1 - $ ./configure # May need to modified, see notes below. - $ make - $ sudo make install - $ cd .. - -.. note:: - - If you've installed GEOS and PROJ.4 from binary packages, you will have to specify - their paths when running the ``configure`` scripts for *both* the library and the - tools (the configure scripts look, by default, in ``/usr/local``). For example, - on Debian/Ubuntu distributions that have GEOS and PROJ.4 packages, the command would be:: - - $ ./configure --with-proj-include=/usr/include --with-proj-lib=/usr/lib --with-geos-include=/usr/include --with-geos-lib=/usr/lib - -.. note:: - - For Mac OS X users building from source, the SpatiaLite library *and* tools - need to have their ``target`` configured:: - - $ ./configure --target=macosx - -__ http://www.gaia-gis.it/spatialite/sources.html - -.. _pysqlite2: - -pysqlite2 -^^^^^^^^^ - -Because SpatiaLite must be loaded as an external extension, it requires the -``enable_load_extension`` method, which is only available in versions 2.5+. -Thus, download pysqlite2 2.6, and untar:: - - $ wget http://pysqlite.googlecode.com/files/pysqlite-2.6.0.tar.gz - $ tar xzf pysqlite-2.6.0.tar.gz - $ cd pysqlite-2.6.0 - -Next, use a text editor (e.g., ``emacs`` or ``vi``) to edit the ``setup.cfg`` file -to look like the following:: - - [build_ext] - #define= - include_dirs=/usr/local/include - library_dirs=/usr/local/lib - libraries=sqlite3 - #define=SQLITE_OMIT_LOAD_EXTENSION - -.. note:: - - The important thing here is to make sure you comment out the the - ``define=SQLITE_OMIT_LOAD_EXTENSION`` flag and that the ``include_dirs`` - and ``library_dirs`` settings are uncommented and set to the appropriate - path if the SQLite header files and libraries are not in ``/usr/include`` - and ``/usr/lib``, respectively. - -After modifying ``setup.cfg`` appropriately, then run the ``setup.py`` script -to build and install:: - - $ sudo python setup.py install - -Post-Installation -================= - -.. _spatialdb_template: - -Creating a Spatial Database Template for PostGIS ------------------------------------------------- - -Creating a spatial database with PostGIS is different than normal because -additional SQL must be loaded to enable spatial functionality. Because of -the steps in this process, it's better to create a database template that -can be reused later. - -First, you need to be able to execute the commands as a privileged database -user. For example, you can use the following to become the ``postgres`` user:: - - $ sudo su - postgres - -.. note:: - - The location *and* name of the PostGIS SQL files (e.g., from - ``POSTGIS_SQL_PATH`` below) depends on the version of PostGIS. - PostGIS versions 1.3 and below use ``<pg_sharedir>/contrib/lwpostgis.sql``; - whereas version 1.4 uses ``<sharedir>/contrib/postgis.sql`` and - version 1.5 uses ``<sharedir>/contrib/postgis-1.5/postgis.sql``. - - The example below assumes PostGIS 1.5, thus you may need to modify - ``POSTGIS_SQL_PATH`` and the name of the SQL file for the specific - version of PostGIS you are using. - -Once you're a database super user, then you may execute the following commands -to create a PostGIS spatial database template. If running Ubuntu :ref:`ibex` -or Debian :ref:`lenny`, please refer to their specific documentation for -modifications to these commands:: - - $ POSTGIS_SQL_PATH=`pg_config --sharedir`/contrib/postgis-1.5 - # Creating the template spatial database. - $ createdb -E UTF8 template_postgis - $ createlang -d template_postgis plpgsql # Adding PLPGSQL language support. - # Allows non-superusers the ability to create from this template - $ psql -d postgres -c "UPDATE pg_database SET datistemplate='true' WHERE datname='template_postgis';" - # Loading the PostGIS SQL routines - $ psql -d template_postgis -f $POSTGIS_SQL_PATH/postgis.sql - $ psql -d template_postgis -f $POSTGIS_SQL_PATH/spatial_ref_sys.sql - # Enabling users to alter spatial tables. - $ psql -d template_postgis -c "GRANT ALL ON geometry_columns TO PUBLIC;" - $ psql -d template_postgis -c "GRANT ALL ON geography_columns TO PUBLIC;" - $ psql -d template_postgis -c "GRANT ALL ON spatial_ref_sys TO PUBLIC;" - -These commands may be placed in a shell script for later use; for convenience -the following scripts are available: - -=============== ========================================== -PostGIS Version Shell Script -=============== ========================================== -1.3 `create_template_postgis-1.3.sh`_ -1.4 `create_template_postgis-1.4.sh`_ -1.5 `create_template_postgis-1.5.sh`_ -=============== ========================================== - -Afterwards, you may create a spatial database by simply specifying -``template_postgis`` as the template to use (via the ``-T`` option):: - - $ createdb -T template_postgis <db name> - -.. note:: - - While the ``createdb`` command does not require database super-user privileges, - it must be executed by a database user that has permissions to create databases. - You can create such a user with the following command:: - - $ createuser --createdb <user> - -.. _create_template_postgis-1.3.sh: http://geodjango.org/docs/create_template_postgis-1.3.sh -.. _create_template_postgis-1.4.sh: http://geodjango.org/docs/create_template_postgis-1.4.sh -.. _create_template_postgis-1.5.sh: http://geodjango.org/docs/create_template_postgis-1.5.sh -.. _create_template_postgis-debian.sh: http://geodjango.org/docs/create_template_postgis-debian.sh - -.. _create_spatialite_db: - -Creating a Spatial Database for SpatiaLite -------------------------------------------- - -After the SpatiaLite library and tools have been installed, it is now possible -to create spatial database for use with GeoDjango. In order to do this, download -the spatial database initialization SQL from the `SpatiaLite Resources`__ page:: - - $ wget http://www.gaia-gis.it/spatialite/init_spatialite-2.3.sql.gz - $ gunzip init_spatialite-2.3.sql.gz - -Now, the ``spatialite`` command can be used to initialize a spatial database:: - - $ spatialite geodjango.db < init_spatialite-2.3.sql - -.. note:: - - The parameter ``geodjango.db`` is the *filename* of the SQLite database - you want to use. Use the same in the :setting:`DATABASE_NAME` - inside your ``settings.py``. - - -__ http://www.gaia-gis.it/spatialite/resources.html - - -Add ``django.contrib.gis`` to ``INSTALLED_APPS`` ------------------------------------------------- - -Like other Django contrib applications, you will *only* need to add -:mod:`django.contrib.gis` to :setting:`INSTALLED_APPS` in your settings. -This is the so that ``gis`` templates can be located -- if not done, then -features such as the geographic admin or KML sitemaps will not function properly. - -.. _addgoogleprojection: - -Add Google Projection to ``spatial_ref_sys`` table --------------------------------------------------- - -.. versionchanged:: 1.2 - -.. note:: - - If running PostGIS 1.4 and above, the entry is already included in the - default ``spatial_ref_sys`` table. You can skip this step. - -In order to conduct database transformations to the so-called "Google" -projection (a spherical mercator projection used by Google Maps), -an entry must be added to your spatial database's ``spatial_ref_sys`` table. -Invoke the Django shell from your project and execute the -``add_srs_entry`` function:: - - $ python manage shell - >>> from django.contrib.gis.utils import add_srs_entry - >>> add_srs_entry(900913) - -.. note:: - - In Django 1.1 the name of this function is ``add_postgis_srs``. - -This adds an entry for the 900913 SRID to the ``spatial_ref_sys`` (or equivalent) -table, making it possible for the spatial database to transform coordinates in -this projection. You only need to execute this command *once* per spatial database. - -Troubleshooting -=============== - -If you can't find the solution to your problem here then participate in the -community! You can: - -* Join the ``#geodjango`` IRC channel on FreeNode (may be accessed on the - Web via `Mibbit`__). Please be patient and polite -- while you may not - get an immediate response, someone will attempt to answer your question - as soon as they see it. -* Ask your question on the `GeoDjango`__ mailing list. -* File a ticket on the `Django trac`__ if you think there's a bug. Make - sure to provide a complete description of the problem, versions used, - and specify the component as "GIS". - -__ http://www.mibbit.com/?server=irc.freenode.net&channel=%23geodjango -__ http://groups.google.com/group/geodjango -__ http://code.djangoproject.com/simpleticket - -.. _libsettings: - -Library Environment Settings ----------------------------- - -By far, the most common problem when installing GeoDjango is that the -external shared libraries (e.g., for GEOS and GDAL) cannot be located. [#]_ -Typically, the cause of this problem is that the operating system isn't aware -of the directory where the libraries built from source were installed. - -In general, the library path may be set on a per-user basis by setting -an environment variable, or by configuring the library path for the entire -system. - -``LD_LIBRARY_PATH`` environment variable -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -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:: - - export LD_LIBRARY_PATH=/usr/local/lib - -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:: - - $ sudo echo /usr/local/lib >> /etc/ld.so.conf - $ sudo ldconfig - -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:: - - # crle -l $OLD_PATH:/usr/local/lib - -.. _binutils: - -Install ``binutils`` -^^^^^^^^^^^^^^^^^^^^ - -GeoDjango uses the ``find_library`` function (from the ``ctypes.util`` Python -module) to discover libraries. The ``find_library`` routine uses a program -called ``objdump`` (part of the ``binutils`` package) to verify a shared -library on GNU/Linux systems. Thus, if ``binutils`` is not installed on your -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:: - - $ sudo apt-get install binutils - -Similarly, on Red Hat and CentOS systems:: - - $ sudo yum install binutils - -Platform Specific Instructions -============================== - -.. _macosx: - -Mac OS X --------- - -Because of the variety of packaging systems available for OS X, users have -several different options for installing GeoDjango. These options are: - -* :ref:`kyngchaos` -* :ref:`fink` -* :ref:`macports` -* :ref:`build_from_source` - -.. note:: - - Currently, the easiest and recommended approach for installing GeoDjango - on OS X is to use the KyngChaos packages. - -This section also includes instructions for installing an upgraded version -of :ref:`macosx_python` from packages provided by the Python Software -Foundation, however, this is not required. - -.. _macosx_python: - -Python -^^^^^^ - -Although OS X comes with Python installed, users can use framework -installers (`2.5`__ and `2.6`__ are available) provided by -the Python Software Foundation. An advantage to using the installer is -that OS X's Python will remain "pristine" for internal operating system -use. - -__ http://python.org/ftp/python/2.5.4/python-2.5.4-macosx.dmg -__ http://python.org/ftp/python/2.6.2/python-2.6.2-macosx2009-04-16.dmg - -.. note:: - - 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:: - - export PATH=/Library/Frameworks/Python.framework/Versions/Current/bin:$PATH - -.. _kyngchaos: - -KyngChaos Packages -^^^^^^^^^^^^^^^^^^ - -William Kyngesburye provides a number of `geospatial library binary packages`__ -that make it simple to get GeoDjango installed on OS X without compiling -them from source. However, the `Apple Developer Tools`_ are still necessary -for compiling the Python database adapters :ref:`psycopg2_kyngchaos` (for PostGIS) -and :ref:`pysqlite2_kyngchaos` (for SpatiaLite). - -.. note:: - - SpatiaLite users should consult the :ref:`spatialite_kyngchaos` section - after installing the packages for additional instructions. - -Download the framework packages for: - -* UnixImageIO -* PROJ -* GEOS -* SQLite3 (includes the SpatiaLite library) -* GDAL - -Install the packages in the order they are listed above, as the GDAL and SQLite -packages require the packages listed before them. Afterwards, you can also -install the KyngChaos binary packages for `PostgreSQL and PostGIS`__. - -After installing the binary packages, you'll want to add the following to -your ``.profile`` to be able to run the package programs from the command-line:: - - export PATH=/Library/Frameworks/UnixImageIO.framework/Programs:$PATH - export PATH=/Library/Frameworks/PROJ.framework/Programs:$PATH - export PATH=/Library/Frameworks/GEOS.framework/Programs:$PATH - export PATH=/Library/Frameworks/SQLite3.framework/Programs:$PATH - export PATH=/Library/Frameworks/GDAL.framework/Programs:$PATH - export PATH=/usr/local/pgsql/bin:$PATH - -__ http://www.kyngchaos.com/software/frameworks -__ http://www.kyngchaos.com/software/postgres - -.. note:: - - Use of these binaries requires Django 1.0.3 and above. If you are - using a previous version of Django (like 1.0.2), then you will have - to add the the following in your settings:: - - GEOS_LIBRARY_PATH='/Library/Frameworks/GEOS.framework/GEOS' - GDAL_LIBRARY_PATH='/Library/Frameworks/GDAL.framework/GDAL' - -.. _psycopg2_kyngchaos: - -psycopg2 -~~~~~~~~ - -After you've installed the KyngChaos binaries and modified your ``PATH``, as -described above, ``psycopg2`` may be installed using the following command:: - - $ sudo python easy_install psycopg2 - -.. note:: - - To use ``easy_install`` you'll need to install Python's `setuptools`_. - -.. _setuptools: http://pypi.python.org/pypi/setuptools - -.. _pysqlite2_kyngchaos: - -pysqlite2 -~~~~~~~~~ - -Follow the :ref:`pysqlite2` source install instructions, however, -when editing the ``setup.cfg`` use the following instead:: - - [build_ext] - #define= - include_dirs=/Library/Frameworks/SQLite3.framework/unix/include - library_dirs=/Library/Frameworks/SQLite3.framework/unix/lib - libraries=sqlite3 - #define=SQLITE_OMIT_LOAD_EXTENSION - -.. _spatialite_kyngchaos: - -SpatiaLite -~~~~~~~~~~ - -When :ref:`create_spatialite_db`, the ``spatialite`` program is required. -However, instead of attempting to compile the SpatiaLite tools from source, -download the `SpatiaLite Binaries`__ for OS X, and install ``spatialite`` in a -location available in your ``PATH``. For example:: - - $ curl -O http://www.gaia-gis.it/spatialite/spatialite-tools-osx-x86-2.3.1.tar.gz - $ tar xzf spatialite-tools-osx-x86-2.3.1.tar.gz - $ cd spatialite-tools-osx-x86-2.3.1/bin - $ sudo cp spatialite /Library/Frameworks/SQLite3.framework/Programs - -Finally, for GeoDjango to be able to find the KyngChaos SpatiaLite library, -add the following to your ``settings.py``:: - - SPATIALITE_LIBRARY_PATH='/Library/Frameworks/SQLite3.framework/SQLite3' - -__ http://www.gaia-gis.it/spatialite/binaries.html - -.. _fink: - -Fink -^^^^ - -`Kurt Schwehr`__ has been gracious enough to create GeoDjango packages for users -of the `Fink`__ package system. The following packages are available, depending -on which version of Python you want to use: - -* ``django-gis-py26`` -* ``django-gis-py25`` -* ``django-gis-py24`` - -__ http://schwehr.org/blog/ -__ http://www.finkproject.org/ - -.. _macports: - -MacPorts -^^^^^^^^ - -`MacPorts`__ may be used to install GeoDjango prerequisites on Macintosh -computers running OS X. Because MacPorts still builds the software from source, -the `Apple Developer Tools`_ are required. - -Summary:: - - $ sudo port install postgresql83-server - $ sudo port install geos - $ sudo port install proj - $ sudo port install postgis - $ sudo port install gdal - $ sudo port install libgeoip - -.. note:: - - You will also have to modify the ``PATH`` in your ``.profile`` so - that the MacPorts programs are accessible from the command-line:: - - export PATH=/opt/local/bin:/opt/local/lib/postgresql83/bin - - In addition, add the ``FALLBACK_DYLD_LIBRARY_PATH`` setting so that - the libraries can be found by Python:: - - export FALLBACK_DYLD_LIBRARY_PATH=/opt/local/lib:/opt/local/lib/postgresql83 - -__ http://www.macports.org/ - -.. _ubuntudebian: - -Ubuntu & Debian GNU/Linux -------------------------- - -.. _ubuntu: - -Ubuntu -^^^^^^ - -.. _heron: - -8.04 and lower -~~~~~~~~~~~~~~ - -The 8.04 (and lower) versions of Ubuntu use GEOS v2.2.3 in their binary packages, -which is incompatible with GeoDjango. Thus, do *not* use the binary packages -for GEOS or PostGIS and build some prerequisites from source, per the instructions -in this document; however, it is okay to use the PostgreSQL binary packages. - -For more details, please see the Debian instructions for :ref:`etch` below. - -.. _ibex: - -8.10 -~~~~ - -Use the synaptic package manager to install the following packages:: - - $ sudo apt-get install binutils libgdal1-1.5.0 postgresql-8.3-postgis postgresql-server-dev-8.3 python-psycopg2 python-setuptools - -Afterwards, you may install Django with Python's ``easy_install`` script (the -Ubuntu package ``python-django`` uses an older version missing several -important bug fixes for GeoDjango):: - - $ sudo easy_install Django - -That's it! For the curious, the required binary prerequisites packages are: - -* ``binutils``: for ctypes to find libraries -* ``postgresql-8.3`` -* ``postgresql-server-dev-8.3``: for ``pg_config`` -* ``postgresql-8.3-postgis``: for PostGIS 1.3.3 -* ``libgeos-3.0.0``, and ``libgeos-c1``: for GEOS 3.0.0 -* ``libgdal1-1.5.0``: for GDAL 1.5.0 library -* ``proj``: for PROJ 4.6.0 -- but no datum shifting files, see note below -* ``python-psycopg2`` -* ``python-setuptools``: for ``easy_install`` - -Optional packages to consider: - -* ``libgeoip1``: for :ref:`GeoIP <ref-geoip>` support -* ``gdal-bin``: for GDAL command line programs like ``ogr2ogr`` -* ``python-gdal`` for GDAL's own Python bindings -- includes interfaces for raster manipulation - -.. note:: - - The Ubuntu ``proj`` package does not come with the datum shifting files - installed, which will cause problems with the geographic admin because - the ``null`` datum grid is not available for transforming geometries to the - spherical mercator projection. A solution is to download the - datum-shifting files, create the grid file, and install it yourself:: - - $ wget http://download.osgeo.org/proj/proj-datumgrid-1.4.tar.gz - $ mkdir nad - $ cd nad - $ tar xzf ../proj-datumgrid-1.4.tar.gz - $ nad2bin null < null.lla - $ sudo cp null /usr/share/proj - - Otherwise, the Ubuntu ``proj`` package is fine for general use as long as you - do not plan on doing any database transformation of geometries to the - Google projection (900913). - -.. note:: - - The PostGIS SQL files are not placed the PostgreSQL share directory in the - Ubuntu packages. Use the `create_template_postgis-debian.sh`_ script - instead when :ref:`spatialdb_template`. - -.. _debian: - -Debian ------- - -.. _etch: - -4.0 (Etch) -^^^^^^^^^^ -The situation here is the same as that of Ubuntu :ref:`heron` -- in other words, -some packages must be built from source to work properly with GeoDjango. - -Binary Packages -~~~~~~~~~~~~~~~ -The following command will install acceptable binary packages, as well as -the development tools necessary to build the rest of the requirements:: - - $ sudo apt-get install binutils bzip2 gcc g++ flex make postgresql-8.1 postgresql-server-dev-8.1 python-ctypes python-psycopg2 python-setuptools - -Required package information: - -* ``binutils``: for ctypes to find libraries -* ``bzip2``: for decompressing the source packages -* ``gcc``, ``g++``, ``make``: GNU developer tools used to compile the libraries -* ``flex``: required to build PostGIS -* ``postgresql-8.1`` -* ``postgresql-server-dev-8.1``: for ``pg_config`` -* ``python-ctypes``: Python 2.4 needs to have ctypes installed separately -* ``python-psycopg2`` -* ``python-setuptools``: for ``easy_install`` - -Optional packages: - -* ``libgeoip``: for :ref:`GeoIP <ref-geoip>` support - -Source Packages -~~~~~~~~~~~~~~~ -You will still have to install :ref:`geosbuild`, :ref:`proj4`, -:ref:`postgis`, and :ref:`gdalbuild` from source. Please follow the -directions carefully. - -.. _lenny: - -5.0 (Lenny) -^^^^^^^^^^^ -This version is comparable to Ubuntu :ref:`ibex`, so the command -is very similar:: - - $ sudo apt-get install binutils libgdal1-1.5.0 postgresql-8.3 postgresql-8.3-postgis postgresql-server-dev-8.3 python-psycopg2 python-setuptools - -This assumes that you are using PostgreSQL version 8.3. Else, replace ``8.3`` -in the above command with the appropriate PostgreSQL version. - -.. note:: - - Please read the note in the Ubuntu :ref:`ibex` install documentation - about the ``proj`` package -- it also applies here because the package does - not include the datum shifting files. - -.. _post_install: - -Post-installation Notes -~~~~~~~~~~~~~~~~~~~~~~~ - -If the PostgreSQL database cluster was not initiated after installing, then it -can be created (and started) with the following command:: - - $ sudo pg_createcluster --start 8.3 main - -Afterwards, the ``/etc/init.d/postgresql-8.3`` script should be used to manage -the starting and stopping of PostgreSQL. - -In addition, the SQL files for PostGIS are placed in a different location on -Debian 5.0 . Thus when :ref:`spatialdb_template` either: - -* Create a symbolic link to these files:: - - $ sudo ln -s /usr/share/postgresql-8.3-postgis/{lwpostgis,spatial_ref_sys}.sql /usr/share/postgresql/8.3 - - If not running PostgreSQL 8.3, then replace ``8.3`` in the command above with the correct version. - -* Or use the `create_template_postgis-debian.sh`_ to create the spatial database. - -.. _windows: - -Windows XP ----------- - -Python -^^^^^^ - -First, download the `Python 2.6 installer`__ from the Python Web site. Next, -execute the installer and use defaults, e.g., keep 'Install for all users' -checked and the installation path set as ``C:\Python26``. - -.. note:: - - You may already have a version of Python installed in ``C:\python`` as ESRI - products sometimes install a copy there. *You should still install a - fresh version of Python 2.6.* - -__ http://python.org/ftp/python/2.6.2/python-2.6.2.msi - -PostgreSQL -^^^^^^^^^^ - -First, select a mirror and download the latest `PostgreSQL 8.3 installer`__ from -the EnterpriseDB Web site. - -.. note:: - - PostgreSQL 8.3 is required because PostGIS is not available yet for 8.4. - -After downloading, simply click on the installer, follow the -on-screen directions, and keep the default options (e.g., keep the installation -path as ``C:\Program Files\PostgreSQL\8.3``). - -.. note:: - - This PostgreSQL installation process will create both a new windows user to be the - 'postgres service account' and a special 'postgres superuser' to own the database - cluster. You will be prompted to set a password for both users (make sure to write - them down!). To see basic details on the 'service user' account right click on - 'My Computer' and select 'Manage' or go to: Control Panel -> Administrative Tools -> - Computer Management -> System Tools -> Local Users and Groups. - -If installed successfully, the PostgreSQL server will run in the background each time -the system as started as a Windows service. When finished, the installer should launch -the Application Stack Builder (ASB) -- use this to install PostGIS, see instructions -below for more details. A 'PostgreSQL 8.3' start menu group should be created that -contains shortcuts for the ASB and 'Command Prompt', which launches a terminal window -in the PostgreSQL directory. - -__ http://www.enterprisedb.com/products/pgdownload.do#windows - -PostGIS -^^^^^^^ - -From the Application Stack Builder (Programs -> PostgreSQL 8.3), select -'PostgreSQL Database Server 8.3 on port 5432' from the drop down menu. Next, -select 'PostGIS 1.3.6 for PostgreSQL 8.3' from the 'Spatial Extensions' tree -in the list. Select only the default options during install (do not uncheck -the option to create a default PostGIS database). - -.. note:: - - You will be prompted to enter your 'postgres superuser' password in the - 'Database Connection Information' dialog. - -psycopg2 -^^^^^^^^ - -The ``psycopg2`` Python module provides the interface between Python and the -PostgreSQL database. Download the `Windows installer`__ (v2.0.10) and run -using the default settings. [#]_ - -__ http://www.stickpeople.com/projects/python/win-psycopg/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.exe - -GeoDjango Installer -^^^^^^^^^^^^^^^^^^^ - -Download the `GeoDjango Installer`__; this was created [#]_ to simplify the rest -of the process for installing GeoDjango on Windows platforms. The installer -automatically installs Django 1.1, GDAL 1.6.0, PROJ 4.6.1 (including datum grid -files), and configures the necessary environment variables. - -Once the installer has completed, log out and log back in so that the -modifications to the system environment variables take effect, and you -should be good to go. - -.. note:: - - The installer modifies the system ``Path`` environment variable to - include ``C:\Program Files\PostgreSQL\8.3\bin`` and - ``C:\Program Files\GeoDjango\bin``. This is required so that Python - may find the GEOS DLL provided by PostGIS and the GDAL DLL provided - by the installer. The installer also sets the ``GDAL_DATA`` and - ``PROJ_LIB`` environment variables. - -__ http://geodjango.org/windows/GeoDjango_Installer.exe - -.. rubric:: Footnotes -.. [#] The datum shifting files are needed for converting data to and from certain projections. - For example, the PROJ.4 string for the `Google projection (900913) <http://spatialreference.org/ref/epsg/900913/proj4>`_ - requires the ``null`` grid file only included in the extra datum shifting files. - It is easier to install the shifting files now, then to have debug a problem caused by their absence later. -.. [#] Specifically, GeoDjango provides support for the `OGR <http://gdal.org/ogr>`_ library, a component of GDAL. -.. [#] See `GDAL ticket #2382 <http://trac.osgeo.org/gdal/ticket/2382>`_. -.. [#] GeoDjango uses the `find_library <http://docs.python.org/library/ctypes.html#finding-shared-libraries>`_ - routine from ``ctypes.util`` to locate shared libraries. -.. [#] The ``psycopg2`` Windows installers are packaged and maintained by - `Jason Erickson <http://www.stickpeople.com/projects/python/win-psycopg/>`_. -.. [#] The source code for the installer is available in the `nsis_installer <http://geodjango.org/hg/nsis_installer/>`_ - GeoDjango mercurial repository. diff --git a/parts/django/docs/ref/contrib/gis/layermapping.txt b/parts/django/docs/ref/contrib/gis/layermapping.txt deleted file mode 100644 index 0b09e17..0000000 --- a/parts/django/docs/ref/contrib/gis/layermapping.txt +++ /dev/null @@ -1,220 +0,0 @@ -.. _ref-layermapping: - -==================================== -``LayerMapping`` data import utility -==================================== - -.. module:: django.contrib.gis.utils.layermapping - :synopsis: Spatial data import utility for GeoDjango models. - -.. currentmodule:: django.contrib.gis.utils - -The :class:`LayerMapping` class provides a way to map the contents of -vector spatial data files (e.g. shapefiles) intoto GeoDjango models. - -This utility grew out of the author's personal needs to eliminate -the code repetition that went into pulling geometries and fields out of -a vector layer, converting to another coordinate system (e.g. WGS84), and -then inserting into a GeoDjango model. - -.. note:: - - Use of :class:`LayerMapping` requires GDAL. - -.. warning :: - - GIS data sources, like shapefiles, may be very large. If you find - that :class:`LayerMapping` is using too much memory, set - :setting:`DEBUG` to ``False`` in your settings. When :setting:`DEBUG` - is set to ``True``, Django :ref:`automatically logs <faq-see-raw-sql-queries>` - *every* SQL query -- thus, when SQL statements contain geometries, it is - easy to consume more memory than is typical. - -Example -======= - -1. You need a GDAL-supported data source, like a shapefile (here we're using - a simple polygon shapefile, ``test_poly.shp``, with three features):: - - >>> from django.contrib.gis.gdal import DataSource - >>> ds = DataSource('test_poly.shp') - >>> layer = ds[0] - >>> print layer.fields # Exploring the fields in the layer, we only want the 'str' field. - ['float', 'int', 'str'] - >>> print len(layer) # getting the number of features in the layer (should be 3) - 3 - >>> print layer.geom_type # Should be 'Polygon' - Polygon - >>> print layer.srs # WGS84 in WKT - GEOGCS["GCS_WGS_1984", - DATUM["WGS_1984", - SPHEROID["WGS_1984",6378137,298.257223563]], - PRIMEM["Greenwich",0], - UNIT["Degree",0.017453292519943295]] - -2. Now we define our corresponding Django model (make sure to use ``syncdb``):: - - from django.contrib.gis.db import models - - class TestGeo(models.Model): - name = models.CharField(max_length=25) # corresponds to the 'str' field - poly = models.PolygonField(srid=4269) # we want our model in a different SRID - objects = models.GeoManager() - def __unicode__(self): - return 'Name: %s' % self.name - -3. Use :class:`LayerMapping` to extract all the features and place them in the - database:: - - >>> from django.contrib.gis.utils import LayerMapping - >>> from geoapp.models import TestGeo - >>> mapping = {'name' : 'str', # The 'name' model field maps to the 'str' layer field. - 'poly' : 'POLYGON', # For geometry fields use OGC name. - } # The mapping is a dictionary - >>> lm = LayerMapping(TestGeo, 'test_poly.shp', mapping) - >>> lm.save(verbose=True) # Save the layermap, imports the data. - Saved: Name: 1 - Saved: Name: 2 - Saved: Name: 3 - -Here, :class:`LayerMapping` just transformed the three geometries from the -shapefile in their original spatial reference system (WGS84) to the spatial -reference system of the GeoDjango model (NAD83). If no spatial reference -system is defined for the layer, use the ``source_srs`` keyword with a -:class:`~django.contrib.gis.gdal.SpatialReference` object to specify one. - -``LayerMapping`` API -==================== - -.. class:: LayerMapping(model, data_source, mapping[, layer=0, source_srs=None, encoding=None, transaction_mode='commit_on_success', transform=True, unique=True, using='default']) - -The following are the arguments and keywords that may be used during -instantiation of ``LayerMapping`` objects. - -================= ========================================================= -Argument Description -================= ========================================================= -``model`` The geographic model, *not* an instance. - -``data_source`` The path to the OGR-supported data source file - (e.g., a shapefile). Also accepts - :class:`django.contrib.gis.gdal.DataSource` instances. - -``mapping`` A dictionary: keys are strings corresponding to - the model field, and values correspond to - string field names for the OGR feature, or if the - model field is a geographic then it should - correspond to the OGR geometry type, - e.g., ``'POINT'``, ``'LINESTRING'``, ``'POLYGON'``. -================= ========================================================= - -===================== ===================================================== -Keyword Arguments -===================== ===================================================== -``layer`` The index of the layer to use from the Data Source - (defaults to 0) - -``source_srs`` Use this to specify the source SRS manually (for - example, some shapefiles don't come with a '.prj' - file). An integer SRID, WKT or PROJ.4 strings, and - :class:`django.contrib.gis.gdal.SpatialReference` - objects are accepted. - -``encoding`` Specifies the character set encoding of the strings - in the OGR data source. For example, ``'latin-1'``, - ``'utf-8'``, and ``'cp437'`` are all valid encoding - parameters. - -``transaction_mode`` May be ``'commit_on_success'`` (default) or - ``'autocommit'``. - -``transform`` Setting this to False will disable coordinate - transformations. In other words, geometries will - be inserted into the database unmodified from their - original state in the data source. - -``unique`` Setting this to the name, or a tuple of names, - from the given model will create models unique - only to the given name(s). Geometries will from - each feature will be added into the collection - associated with the unique model. Forces - the transaction mode to be ``'autocommit'``. - -``using`` New in version 1.2. Sets the database to use when - importing spatial data. Default is ``'default'`` -===================== ===================================================== - -``save()`` Keyword Arguments ----------------------------- - -.. method:: LayerMapping.save([verbose=False, fid_range=False, step=False, progress=False, silent=False, stream=sys.stdout, strict=False]) - -The ``save()`` method also accepts keywords. These keywords are -used for controlling output logging, error handling, and for importing -specific feature ranges. - -=========================== ================================================= -Save Keyword Arguments Description -=========================== ================================================= -``fid_range`` May be set with a slice or tuple of - (begin, end) feature ID's to map from - the data source. In other words, this - keyword enables the user to selectively - import a subset range of features in the - geographic data source. - -``progress`` When this keyword is set, status information - will be printed giving the number of features - processed and successfully saved. By default, - progress information will be printed every 1000 - features processed, however, this default may - be overridden by setting this keyword with an - integer for the desired interval. - -``silent`` By default, non-fatal error notifications are - printed to ``sys.stdout``, but this keyword may - be set to disable these notifications. - -``step`` If set with an integer, transactions will - occur at every step interval. For example, if - ``step=1000``, a commit would occur after the - 1,000th feature, the 2,000th feature etc. - - -``stream`` Status information will be written to this file - handle. Defaults to using ``sys.stdout``, but - any object with a ``write`` method is supported. - -``strict`` Execution of the model mapping will cease upon - the first error encountered. The default value - (``False``) - behavior is to attempt to continue. - -``verbose`` If set, information will be printed - subsequent to each model save - executed on the database. -=========================== ================================================= - -Troubleshooting -=============== - -Running out of memory ---------------------- - -As noted in the warning at the top of this section, Django stores all SQL -queries when ``DEBUG=True``. Set ``DEBUG=False`` in your settings, and this -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:: - - 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:: - - max_allowed_packet = 10M diff --git a/parts/django/docs/ref/contrib/gis/measure.txt b/parts/django/docs/ref/contrib/gis/measure.txt deleted file mode 100644 index 6971788..0000000 --- a/parts/django/docs/ref/contrib/gis/measure.txt +++ /dev/null @@ -1,180 +0,0 @@ -.. _ref-measure: - -=================== -Measurement Objects -=================== - -.. module:: django.contrib.gis.measure - :synopsis: GeoDjango's distance and area measurment objects. - -The :mod:`django.contrib.gis.measure` module contains objects that allow -for convenient representation of distance and area units of measure. [#]_ -Specifically, it implements two objects, :class:`Distance` and -:class:`Area` -- both of which may be accessed via the -:class:`D` and :class:`A` convenience aliases, respectively. - -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``):: - - >>> from django.contrib.gis.measure import Distance, D - >>> d1 = Distance(km=5) - >>> print d1 - 5.0 km - >>> d2 = D(mi=5) # `D` is an alias for `Distance` - >>> print d2 - 5.0 mi - -Conversions are easy, just access the preferred unit attribute to get a -converted distance quantity:: - - >>> print d1.mi # Converting 5 kilometers to miles - 3.10685596119 - >>> print d2.km # Converting 5 miles to kilometers - 8.04672 - -Moreover, arithmetic operations may be performed between the distance -objects:: - - >>> print d1 + d2 # Adding 5 miles to 5 kilometers - 13.04672 km - >>> print d2 - d1 # Subtracting 5 kilometers from 5 miles - 1.89314403881 mi - -Two :class:`Distance` objects multiplied together will yield an :class:`Area` -object, which uses squared units of measure:: - - >>> 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:: - - >>> print Distance.unit_attname('US Survey Foot') - survey_ft - >>> print Distance.unit_attname('centimeter') - cm - -.. _supported_units: - -Supported units -=============== - -================================= ======================================== -Unit Attribute Full name or alias(es) -================================= ======================================== -``km`` Kilometre, Kilometer -``mi`` Mile -``m`` Meter, Metre -``yd`` Yard -``ft`` Foot, Foot (International) -``survey_ft`` U.S. Foot, US survey foot -``inch`` Inches -``cm`` Centimeter -``mm`` Millimetre, Millimeter -``um`` Micrometer, Micrometre -``british_ft`` British foot (Sears 1922) -``british_yd`` British yard (Sears 1922) -``british_chain_sears`` British chain (Sears 1922) -``indian_yd`` Indian yard, Yard (Indian) -``sears_yd`` Yard (Sears) -``clarke_ft`` Clarke's Foot -``chain`` Chain -``chain_benoit`` Chain (Benoit) -``chain_sears`` Chain (Sears) -``british_chain_benoit`` British chain (Benoit 1895 B) -``british_chain_sears_truncated`` British chain (Sears 1922 truncated) -``gold_coast_ft`` Gold Coast foot -``link`` Link -``link_benoit`` Link (Benoit) -``link_sears`` Link (Sears) -``clarke_link`` Clarke's link -``fathom`` Fathom -``rod`` Rod -``nm`` Nautical Mile -``nm_uk`` Nautical Mile (UK) -``german_m`` German legal metre -================================= ======================================== - -.. note:: - - :class:`Area` attributes are the same as :class:`Distance` attributes, - except they are prefixed with ``sq_`` (area units are square in nature). - For example, ``Area(sq_m=2)`` creates an :class:`Area` object - representing two square meters. - -Measurement API -=============== - -``Distance`` ------------- - -.. class:: Distance(**kwargs) - - 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:: - - >>> dist = Distance(mi=5) - - .. method:: __getattr__(unit_att) - - Returns the distance value in units corresponding to the given unit - attribute. For example:: - - >>> print dist.km - 8.04672 - - .. classmethod:: unit_attname(unit_name) - - Returns the distance unit attribute name for the given full unit name. - For example:: - - >>> Distance.unit_attname('Mile') - 'mi' - -.. class:: D - - Alias for :class:`Distance` class. - -``Area`` --------- - -.. class:: Area(**kwargs) - - 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 square miles:: - - >>> a = Area(sq_mi=5) - - .. method:: __getattr__(unit_att) - - Returns the area value in units corresponding to the given unit - attribute. For example:: - - >>> print a.sq_km - 12.949940551680001 - - .. classmethod:: unit_attname(unit_name) - - Returns the area unit attribute name for the given full unit name. - For example:: - - >>> Area.unit_attname('Kilometer') - 'sq_km' - -.. class:: A - - Alias for :class:`Area` class. - -.. rubric:: Footnotes -.. [#] `Robert Coup <http://koordinates.com/>`_ is the initial author of the measure objects, - and was inspired by Brian Beck's work in `geopy <http://code.google.com/p/geopy/>`_ - and Geoff Biggs' PhD work on dimensioned units for robotics. diff --git a/parts/django/docs/ref/contrib/gis/model-api.txt b/parts/django/docs/ref/contrib/gis/model-api.txt deleted file mode 100644 index 6b50cf3..0000000 --- a/parts/django/docs/ref/contrib/gis/model-api.txt +++ /dev/null @@ -1,265 +0,0 @@ -.. _ref-gis-model-api: - -=================== -GeoDjango Model API -=================== - -.. module:: django.contrib.gis.db.models - :synopsis: GeoDjango model and field API. - -This document explores the details of the GeoDjango Model API. Throughout this -section, we'll be using the following geographic model of a `ZIP code`__ as our -example:: - - from django.contrib.gis.db import models - - class Zipcode(models.Model): - code = models.CharField(max_length=5) - poly = models.PolygonField() - objects = models.GeoManager() - -__ http://en.wikipedia.org/wiki/ZIP_code - -Geometry Field Types -==================== - -Each of the following geometry field types correspond with the -OpenGIS Simple Features specification [#fnogc]_. - -``GeometryField`` ------------------ - -.. class:: GeometryField - -``PointField`` --------------- - -.. class:: PointField - -``LineStringField`` -------------------- - -.. class:: LineStringField - -``PolygonField`` ----------------- - -.. class:: PolygonField - -``MultiPointField`` -------------------- - -.. class:: MultiPointField - -``MultiLineStringField`` ------------------------- - -.. class:: MultiLineStringField - -``MultiPolygonField`` ---------------------- - -.. class:: MultiPolygonField - -``GeometryCollectionField`` ---------------------------- - -.. class:: GeometryCollectionField - -.. _geometry-field-options: - -Geometry Field Options -====================== - -In addition to the regular :ref:`common-model-field-options` available for -Django model fields, geometry fields have the following additional options. -All are optional. - -``srid`` --------- - -.. attribute:: GeometryField.srid - -Sets the SRID [#fnogcsrid]_ (Spatial Reference System Identity) of the geometry field to -the given value. Defaults to 4326 (also known as `WGS84`__, units are in degrees -of longitude and latitude). - -__ http://en.wikipedia.org/wiki/WGS84 - -.. _selecting-an-srid: - -Selecting an SRID -^^^^^^^^^^^^^^^^^ - -Choosing an appropriate SRID for your model is an important decision that the -developer should consider carefully. The SRID is an integer specifier that -corresponds to the projection system that will be used to interpret the data -in the spatial database. [#fnsrid]_ Projection systems give the context to the -coordinates that specify a location. Although the details of `geodesy`__ are -beyond the scope of this documentation, the general problem is that the earth -is spherical and representations of the earth (e.g., paper maps, Web maps) -are not. - -Most people are familiar with using latitude and longitude to reference a -location on the earth's surface. However, latitude and longitude are angles, -not distances. [#fnharvard]_ In other words, while the shortest path between two points on -a flat surface is a straight line, the shortest path between two points on a curved -surface (such as the earth) is an *arc* of a `great circle`__. [#fnthematic]_ Thus, -additional computation is required to obtain distances in planar units (e.g., -kilometers and miles). Using a geographic coordinate system may introduce -complications for the developer later on. For example, PostGIS versions 1.4 -and below do not have the capability to perform distance calculations between -non-point geometries using geographic coordinate systems, e.g., constructing a -query to find all points within 5 miles of a county boundary stored as WGS84. -[#fndist]_ - -Portions of the earth's surface may projected onto a two-dimensional, or -Cartesian, plane. Projected coordinate systems are especially convenient -for region-specific applications, e.g., if you know that your database will -only cover geometries in `North Kansas`__, then you may consider using projection -system specific to that region. Moreover, projected coordinate systems are -defined in Cartesian units (such as meters or feet), easing distance -calculations. - -.. note:: - - If you wish to peform arbitrary distance queries using non-point - geometries in WGS84, consider upgrading to PostGIS 1.5. For - better performance, enable the :attr:`GeometryField.geography` - keyword so that :ref:`geography database type <geography-type>` - is used instead. - -Additional Resources: - -* `spatialreference.org`__: A Django-powered database of spatial reference - systems. -* `The State Plane Coordinate System`__: A Web site covering the various - projection systems used in the United States. Much of the U.S. spatial - data encountered will be in one of these coordinate systems rather than - in a geographic coordinate system such as WGS84. - -__ http://en.wikipedia.org/wiki/Geodesy -__ http://en.wikipedia.org/wiki/Great_circle -__ http://www.spatialreference.org/ref/epsg/2796/ -__ http://spatialreference.org/ -__ http://welcome.warnercnr.colostate.edu/class_info/nr502/lg3/datums_coordinates/spcs.html - -``spatial_index`` ------------------ - -.. attribute:: GeometryField.spatial_index - -Defaults to ``True``. Creates a spatial index for the given geometry -field. - -.. note:: - - This is different from the ``db_index`` field option because spatial - indexes are created in a different manner than regular database - indexes. Specifically, spatial indexes are typically created using - a variant of the R-Tree, while regular database indexes typically - use B-Trees. - -``dim`` -------- - -.. versionadded:: 1.2 - -.. attribute:: GeometryField.dim - -This option may be used for customizing the coordinate dimension of the -geometry field. By default, it is set to 2, for representing two-dimensional -geometries. For spatial backends that support it, it may be set to 3 for -three-dimensonal support. - -.. note:: - - At this time 3D support requires that GEOS 3.1 be installed, and is - limited only to the PostGIS spatial backend. - -``geography`` -------------- - -.. versionadded:: 1.2 - -.. attribute:: GeometryField.geography - -If set to ``True``, this option will create a database column of -type geography, rather than geometry. Please refer to the -:ref:`geography type <geography-type>` section below for more -details. - -.. note:: - - Geography support is limited only to PostGIS 1.5+, and will - force the SRID to be 4326. - -.. _geography-type: - -Geography Type -^^^^^^^^^^^^^^ - -In PostGIS 1.5, the geography type was introduced -- it provides -provides native support for spatial features represented with geographic -coordinates (e.g., WGS84 longitude/latitude). [#fngeography]_ -Unlike the plane used by a geometry type, the geography type uses a spherical -representation of its data. Distance and measurement operations -performed on a geography column automatically employ great circle arc -calculations and return linear units. In other words, when ``ST_Distance`` -is called on two geographies, a value in meters is returned (as opposed -to degrees if called on a geometry column in WGS84). - -Because geography calculations involve more mathematics, only a subset of the -PostGIS spatial lookups are available for the geography type. Practically, -this means that in addition to the :ref:`distance lookups <distance-lookups>` -only the following additional :ref:`spatial lookups <spatial-lookups>` are -available for geography columns: - -* :lookup:`bboverlaps` -* :lookup:`coveredby` -* :lookup:`covers` -* :lookup:`intersects` - -For more information, the PostGIS documentation contains a helpful section on -determining `when to use geography data type over geometry data type -<http://postgis.refractions.net/documentation/manual-1.5/ch04.html#PostGIS_GeographyVSGeometry>`_. - -``GeoManager`` -============== - -.. currentmodule:: django.contrib.gis.db.models -.. class:: GeoManager - -In order to conduct geographic queries, each geographic model requires -a ``GeoManager`` model manager. This manager allows for the proper SQL -construction for geographic queries; thus, without it, all geographic filters -will fail. It should also be noted that ``GeoManager`` is required even if the -model does not have a geographic field itself, e.g., in the case of a -``ForeignKey`` relation to a model with a geographic field. For example, -if we had an ``Address`` model with a ``ForeignKey`` to our ``Zipcode`` -model:: - - from django.contrib.gis.db import models - from django.contrib.localflavor.us.models import USStateField - - class Address(models.Model): - num = models.IntegerField() - street = models.CharField(max_length=100) - city = models.CharField(max_length=100) - state = USStateField() - zipcode = models.ForeignKey(Zipcode) - objects = models.GeoManager() - -The geographic manager is needed to do spatial queries on related ``Zipcode`` objects, -for example:: - - qs = Address.objects.filter(zipcode__poly__contains='POINT(-104.590948 38.319914)') - -.. rubric:: Footnotes -.. [#fnogc] OpenGIS Consortium, Inc., `Simple Feature Specification For SQL <http://www.opengis.org/docs/99-049.pdf>`_, Document 99-049 (May 5, 1999). -.. [#fnogcsrid] *See id.* at Ch. 2.3.8, p. 39 (Geometry Values and Spatial Reference Systems). -.. [#fnsrid] Typically, SRID integer corresponds to an EPSG (`European Petroleum Survey Group <http://www.epsg.org>`_) identifier. However, it may also be associated with custom projections defined in spatial database's spatial reference systems table. -.. [#fnharvard] Harvard Graduate School of Design, `An Overview of Geodesy and Geographic Referencing Systems <http://www.gsd.harvard.edu/gis/manual/projections/fundamentals/>`_. This is an excellent resource for an overview of principles relating to geographic and Cartesian coordinate systems. -.. [#fnthematic] Terry A. Slocum, Robert B. McMaster, Fritz C. Kessler, & Hugh H. Howard, *Thematic Cartography and Geographic Visualization* (Prentice Hall, 2nd edition), at Ch. 7.1.3. -.. [#fndist] This limitation does not apply to PostGIS 1.5. It should be noted that even in previous versions of PostGIS, this isn't impossible using GeoDjango; you could for example, take a known point in a projected coordinate system, buffer it to the appropriate radius, and then perform an intersection operation with the buffer transformed to the geographic coordinate system. -.. [#fngeography] Please refer to the `PostGIS Geography Type <http://postgis.refractions.net/documentation/manual-1.5/ch04.html#PostGIS_Geography>`_ documentation for more details. diff --git a/parts/django/docs/ref/contrib/gis/ogrinspect.txt b/parts/django/docs/ref/contrib/gis/ogrinspect.txt deleted file mode 100644 index ed285e0..0000000 --- a/parts/django/docs/ref/contrib/gis/ogrinspect.txt +++ /dev/null @@ -1,21 +0,0 @@ -.. _ref-ogrinspect: - -============== -OGR Inspection -============== - -.. module:: django.contrib.gis.utils.ogrinspect - :synopsis: Utilities for inspecting OGR data sources. - -.. currentmodule:: django.contrib.gis.utils - -``ogrinspect`` -============== - -.. function:: ogrinspect(data_source, model_name[, **kwargs]) - :noindex: - -``mapping`` -=========== - -.. function:: mapping(data_source, [geom_name='geom', layer_key=0, multi_geom=False]) diff --git a/parts/django/docs/ref/contrib/gis/sitemaps.txt b/parts/django/docs/ref/contrib/gis/sitemaps.txt deleted file mode 100644 index 75bddd3..0000000 --- a/parts/django/docs/ref/contrib/gis/sitemaps.txt +++ /dev/null @@ -1,27 +0,0 @@ -=================== -Geographic Sitemaps -=================== - -Google's sitemap protocol has been recently extended to support geospatial -content. [#]_ This includes the addition of the ``<url>`` child element -``<geo:geo>``, which tells Google that the content located at the URL is -geographic in nature. [#]_ - -Example -======= - -Reference -========= - -``KMLSitemap`` --------------- - -``KMZSitemap`` --------------- - -``GeoRSSSitemap`` ------------------ - -.. rubric:: Footnotes -.. [#] Google, Inc., `What is a Geo Sitemap? <http://www.google.com/support/webmasters/bin/answer.py?answer=94554>`_. -.. [#] Google, Inc., `Submit Your Geo Content to Google <http://code.google.com/apis/kml/documentation/kmlSearch.html>`_. diff --git a/parts/django/docs/ref/contrib/gis/testing.txt b/parts/django/docs/ref/contrib/gis/testing.txt deleted file mode 100644 index 889b43a..0000000 --- a/parts/django/docs/ref/contrib/gis/testing.txt +++ /dev/null @@ -1,268 +0,0 @@ -====================== -Testing GeoDjango Apps -====================== - -.. versionchanged:: 1.2 - -In Django 1.2, the addition of :ref:`spatial-backends` -simplified the process of testing GeoDjango applications. Specifically, testing -GeoDjango applications is now the same as :doc:`/topics/testing`. - -Included in this documentation are some additional notes and settings -for :ref:`testing-postgis` and :ref:`testing-spatialite` users. - -.. note:: - - Django 1.1 users are still required to use a custom :setting:`TEST_RUNNER`. - See the :ref:`testing-1.1` section for more details. - -.. _testing-postgis: - -PostGIS -======= - -Settings --------- - -.. note:: - - The settings below have sensible defaults, and shouldn't require manual setting. - -.. setting:: POSTGIS_TEMPLATE - -``POSTGIS_TEMPLATE`` -^^^^^^^^^^^^^^^^^^^^ - -.. versionadded:: 1.1 - -.. versionchanged:: 1.2 - -This setting may be used to customize the name of the PostGIS template -database to use. In Django versions 1.2 and above, it automatically -defaults to ``'template_postgis'`` (the same name used in the -:ref:`installation documentation <spatialdb_template>`). - -.. note:: - - Django 1.1 users will still have to define the :setting:`POSTGIS_TEMPLATE` - with a value, for example:: - - POSTGIS_TEMPLATE='template_postgis' - -.. setting:: POSTGIS_VERSION - -``POSTGIS_VERSION`` -^^^^^^^^^^^^^^^^^^^ - -.. versionadded:: 1.1 - -When GeoDjango's spatial backend initializes on PostGIS, it has to perform -a SQL query to determine the version in order to figure out what -features are available. Advanced users wishing to prevent this additional -query may set the version manually using a 3-tuple of integers specifying -the major, minor, and subminor version numbers for PostGIS. For example, -to configure for PostGIS 1.5.2 you would use:: - - POSTGIS_VERSION = (1, 5, 2) - -Obtaining Sufficient Privileges -------------------------------- - -Depending on your configuration, this section describes several methods to -configure a database user with sufficient privileges to run tests for -GeoDjango applications on PostgreSQL. If your -:ref:`spatial database template <spatialdb_template>` -was created like in the instructions, then your testing database user -only needs to have the ability to create databases. In other configurations, -you may be required to use a database superuser. - -Create Database User -^^^^^^^^^^^^^^^^^^^^ - -To make database user with the ability to create databases, use the -following command:: - - $ createuser --createdb -R -S <user_name> - -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):: - - postgres# ALTER ROLE <user_name> CREATEDB NOSUPERUSER NOCREATEROLE; - -Create Database Superuser -^^^^^^^^^^^^^^^^^^^^^^^^^ - -This may be done at the time the user is created, for example:: - - $ 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):: - - postgres# ALTER ROLE <user_name> SUPERUSER; - - -Create Local PostgreSQL Database -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -1. Initialize database: ``initdb -D /path/to/user/db`` - -2. If there's already a Postgres instance on the machine, it will need - to use a different TCP port than 5432. Edit ``postgresql.conf`` (in - ``/path/to/user/db``) to change the database port (e.g. ``port = 5433``). - -3. Start this database ``pg_ctl -D /path/to/user/db start`` - -Windows -------- - -On Windows platforms the pgAdmin III utility may also be used as -a simple way to add superuser privileges to your database user. - -By default, the PostGIS installer on Windows includes a template -spatial database entitled ``template_postgis``. - -.. _testing-spatialite: - -SpatiaLite -========== - -.. versionadded:: 1.1 - -You will need to download the `initialization SQL`__ script for SpatiaLite:: - - $ wget http://www.gaia-gis.it/spatialite/init_spatialite-2.3.zip - $ unzip init_spatialite-2.3.zip - -If ``init_spatialite-2.3.sql`` is in the same path as your project's ``manage.py``, -then all you have to do is:: - - $ python manage.py test - -Settings --------- - -.. setting:: SPATIALITE_SQL - -``SPATIALITE_SQL`` -^^^^^^^^^^^^^^^^^^ - -.. versionadded:: 1.1 - -By default, the GeoDjango test runner looks for the SpatiaLite SQL in the -same directory where it was invoked (by default the same directory where -``manage.py`` is located). If you want to use a different location, then -you may add the following to your settings:: - - SPATIALITE_SQL='/path/to/init_spatialite-2.3.sql' - -__ http://www.gaia-gis.it/spatialite/init_spatialite-2.3.zip - -.. _testing-1.1: - -Testing GeoDjango Applications in 1.1 -===================================== - -In Django 1.1, to accommodate the extra steps required to scaffalod a -spatial database automatically, a test runner customized for GeoDjango -must be used. To use this runner, configure :setting:`TEST_RUNNER` as follows:: - - TEST_RUNNER='django.contrib.gis.tests.run_tests' - -.. note:: - - In order to create a spatial database, the :setting:`USER` setting - (or :setting:`TEST_USER`, if optionally defined on Oracle) requires - elevated privileges. When using PostGIS or MySQL, the database user - must have at least the ability to create databases. When testing on Oracle, - the user should be a superuser. - -.. _geodjango-tests: - -GeoDjango Tests -=============== - -.. versionchanged:: 1.2.4 - -GeoDjango's test suite may be run in one of two ways, either by itself or -with the rest of Django's :ref:`unit-tests`. - -.. note:: - - The :setting:`TEST_RUNNER` previously used to execute the GeoDjango - test suite,:func:`django.contrib.gis.tests.run_gis_tests`, was deprecated - in favor of the :class:`django.contrib.gis.tests.GeoDjangoTestSuiteRunner` - class. - -Run only GeoDjango tests ------------------------- - -To run *only* the tests for GeoDjango, the :setting:`TEST_RUNNER` -setting must be changed to use the -:class:`~django.contrib.gis.tests.GeoDjangoTestSuiteRunner`:: - - TEST_RUNNER = 'django.contrib.gis.tests.GeoDjangoTestSuiteRunner' - -Example -^^^^^^^ - -First, you'll need a bare-bones settings file, like below, that is -customized with your spatial database name and user:: - - TEST_RUNNER = 'django.contrib.gis.tests.GeoDjangoTestSuiteRunner' - - DATABASES = { - 'default': { - 'ENGINE': 'django.contrib.gis.db.backends.postgis', - 'NAME': 'a_spatial_database', - 'USER': 'db_user' - } - } - -Assuming the above is in a file called ``postgis.py`` that is in the -the same directory as ``manage.py`` of your Django project, then -you may run the tests with the following command:: - - $ python manage.py test --settings=postgis - -Run with ``runtests.py`` ------------------------- - -To have the GeoDjango tests executed when -:ref:`running the Django test suite <running-unit-tests>` with ``runtests.py`` -all of the databases in the settings file must be using one of the -:ref:`spatial database backends <spatial-backends>`. - -.. warning:: - - Do not change the :setting:`TEST_RUNNER` setting - when running the GeoDjango tests with ``runtests.py``. - -Example -^^^^^^^ - -The following is an example bare-bones settings file with spatial backends -that can be used to run the entire Django test suite, including those -in :mod:`django.contrib.gis`:: - - DATABASES = { - 'default': { - 'ENGINE': 'django.contrib.gis.db.backends.postgis', - 'NAME': 'geodjango', - 'USER': 'geodjango', - }, - 'other': { - 'ENGINE': 'django.contrib.gis.db.backends.postgis', - 'NAME': 'other', - 'USER': 'geodjango', - } - } - -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:: - - $ ./runtests.py --settings=postgis diff --git a/parts/django/docs/ref/contrib/gis/tutorial.txt b/parts/django/docs/ref/contrib/gis/tutorial.txt deleted file mode 100644 index 9deeb78..0000000 --- a/parts/django/docs/ref/contrib/gis/tutorial.txt +++ /dev/null @@ -1,758 +0,0 @@ -================== -GeoDjango Tutorial -================== - -Introduction -============ - -GeoDjango is an add-on for Django that turns it into a world-class geographic -Web framework. GeoDjango strives to make at as simple as possible to create -geographic Web applications, like location-based services. Some features include: - -* Django model fields for `OGC`_ geometries. -* Extensions to Django's ORM for the querying and manipulation of spatial data. -* Loosely-coupled, high-level Python interfaces for GIS geometry operations and - data formats. -* Editing of geometry fields inside the admin. - -This tutorial assumes a familiarity with Django; thus, if you're brand new to -Django please read through the :doc:`regular tutorial </intro/tutorial01>` to introduce -yourself with basic Django concepts. - -.. note:: - - GeoDjango has special prerequisites overwhat is required by Django -- - please consult the :ref:`installation documentation <ref-gis-install>` - for more details. - -This tutorial will guide you through the creation of a geographic Web -application for viewing the `world borders`_. [#]_ Some of the code -used in this tutorial is taken from and/or inspired by the `GeoDjango -basic apps`_ project. [#]_ - -.. note:: - - Proceed through the tutorial sections sequentially for step-by-step - instructions. - -.. _OGC: http://www.opengeospatial.org/ -.. _world borders: http://thematicmapping.org/downloads/world_borders.php -.. _GeoDjango basic apps: http://code.google.com/p/geodjango-basic-apps/ - -Setting Up -========== - -Create a Spatial Database -------------------------- - -.. note:: - - MySQL and Oracle users can skip this section because spatial types - are already built into the database. - -First, a spatial database needs to be created for our project. If using -PostgreSQL and PostGIS, then the following commands will -create the database from a :ref:`spatial database template <spatialdb_template>`:: - - $ createdb -T template_postgis geodjango - -.. note:: - - This command must be issued by a database user that has permissions to - create a database. Here is an example set of commands to create such - a user:: - - $ sudo su - postgres - $ createuser --createdb geo - $ exit - - Replace ``geo`` to correspond to the system login user name will be - connecting to the database. For example, ``johndoe`` if that is the - system user that will be running GeoDjango. - -Users of SQLite and SpatiaLite should consult the instructions on how -to create a :ref:`SpatiaLite database <create_spatialite_db>`. - -Create GeoDjango Project ------------------------- - -Use the ``django-admin.py`` script like normal to create a ``geodjango`` project:: - - $ django-admin.py startproject geodjango - -With the project initialized, now create a ``world`` Django application within -the ``geodjango`` project:: - - $ cd geodjango - $ python manage.py startapp world - -Configure ``settings.py`` -------------------------- - -The ``geodjango`` project settings are stored in the ``settings.py`` file. Edit -the database connection settings appropriately:: - - DATABASES = { - 'default': { - 'ENGINE': 'django.contrib.gis.db.backends.postgis', - 'NAME': 'geodjango', - 'USER': 'geo', - } - } - -.. note:: - - These database settings are for Django 1.2 and above. - -In addition, modify the :setting:`INSTALLED_APPS` setting to include -:mod:`django.contrib.admin`, :mod:`django.contrib.gis`, -and ``world`` (our newly created application):: - - INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.admin', - 'django.contrib.gis', - 'world' - ) - -Geographic Data -=============== - -.. _worldborders: - -World Borders -------------- - -The world borders data is available in this `zip file`__. Create a data directory -in the ``world`` application, download the world borders data, and unzip. -On GNU/Linux platforms the following commands should do it:: - - $ mkdir world/data - $ cd world/data - $ wget http://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip - $ unzip TM_WORLD_BORDERS-0.3.zip - $ cd ../.. - -The world borders ZIP file contains a set of data files collectively known as -an `ESRI Shapefile`__, one of the most popular geospatial data formats. When -unzipped the world borders data set includes files with the following extensions: - -* ``.shp``: Holds the vector data for the world borders geometries. -* ``.shx``: Spatial index file for geometries stored in the ``.shp``. -* ``.dbf``: Database file for holding non-geometric attribute data - (e.g., integer and character fields). -* ``.prj``: Contains the spatial reference information for the geographic - data stored in the shapefile. - -__ http://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip -__ http://en.wikipedia.org/wiki/Shapefile - -Use ``ogrinfo`` to examine spatial data ---------------------------------------- - -The GDAL ``ogrinfo`` utility is excellent for examining metadata about -shapefiles (or other vector data sources):: - - $ ogrinfo world/data/TM_WORLD_BORDERS-0.3.shp - INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp' - using driver `ESRI Shapefile' successful. - 1: TM_WORLD_BORDERS-0.3 (Polygon) - -Here ``ogrinfo`` is telling us that the shapefile has one layer, and that -layer contains polygon data. To find out more we'll specify the layer name -and use the ``-so`` option to get only important summary information:: - - $ ogrinfo -so world/data/TM_WORLD_BORDERS-0.3.shp TM_WORLD_BORDERS-0.3 - INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp' - using driver `ESRI Shapefile' successful. - - Layer name: TM_WORLD_BORDERS-0.3 - Geometry: Polygon - Feature Count: 246 - Extent: (-180.000000, -90.000000) - (180.000000, 83.623596) - Layer SRS WKT: - GEOGCS["GCS_WGS_1984", - DATUM["WGS_1984", - SPHEROID["WGS_1984",6378137.0,298.257223563]], - PRIMEM["Greenwich",0.0], - UNIT["Degree",0.0174532925199433]] - FIPS: String (2.0) - ISO2: String (2.0) - ISO3: String (3.0) - UN: Integer (3.0) - NAME: String (50.0) - AREA: Integer (7.0) - POP2005: Integer (10.0) - REGION: Integer (3.0) - SUBREGION: Integer (3.0) - LON: Real (8.3) - LAT: Real (7.3) - -This detailed summary information tells us the number of features in the layer -(246), the geographical extent, the spatial reference system ("SRS WKT"), -as well as detailed information for each attribute field. For example, -``FIPS: String (2.0)`` indicates that there's a ``FIPS`` character field -with a maximum length of 2; similarly, ``LON: Real (8.3)`` is a floating-point -field that holds a maximum of 8 digits up to three decimal places. Although -this information may be found right on the `world borders`_ Web site, this shows -you how to determine this information yourself when such metadata is not -provided. - -Geographic Models -================= - -Defining a Geographic Model ---------------------------- - -Now that we've examined our world borders data set using ``ogrinfo``, we can -create a GeoDjango model to represent this data:: - - from django.contrib.gis.db import models - - class WorldBorders(models.Model): - # Regular Django fields corresponding to the attributes in the - # world borders shapefile. - name = models.CharField(max_length=50) - area = models.IntegerField() - pop2005 = models.IntegerField('Population 2005') - fips = models.CharField('FIPS Code', max_length=2) - iso2 = models.CharField('2 Digit ISO', max_length=2) - iso3 = models.CharField('3 Digit ISO', max_length=3) - un = models.IntegerField('United Nations Code') - region = models.IntegerField('Region Code') - subregion = models.IntegerField('Sub-Region Code') - lon = models.FloatField() - lat = models.FloatField() - - # GeoDjango-specific: a geometry field (MultiPolygonField), and - # overriding the default manager with a GeoManager instance. - mpoly = models.MultiPolygonField() - objects = models.GeoManager() - - # So the model is pluralized correctly in the admin. - class Meta: - verbose_name_plural = "World Borders" - - # Returns the string representation of the model. - def __unicode__(self): - return self.name - -Two important things to note: - -1. The ``models`` module is imported from :mod:`django.contrib.gis.db`. -2. The model overrides its default manager with - :class:`~django.contrib.gis.db.models.GeoManager`; this is *required* - to perform spatial queries. - -When declaring a geometry field on your model the default spatial reference system -is WGS84 (meaning the `SRID`__ is 4326) -- in other words, the field coordinates are in -longitude/latitude pairs in units of degrees. If you want the coordinate system to be -different, then SRID of the geometry field may be customized by setting the ``srid`` -with an integer corresponding to the coordinate system of your choice. - -__ http://en.wikipedia.org/wiki/SRID - -Run ``syncdb`` --------------- - -After you've defined your model, it needs to be synced with the spatial database. -First, let's look at the SQL that will generate the table for the ``WorldBorders`` -model:: - - $ python manage.py sqlall world - -This management command should produce the following output:: - - BEGIN; - CREATE TABLE "world_worldborders" ( - "id" serial NOT NULL PRIMARY KEY, - "name" varchar(50) NOT NULL, - "area" integer NOT NULL, - "pop2005" integer NOT NULL, - "fips" varchar(2) NOT NULL, - "iso2" varchar(2) NOT NULL, - "iso3" varchar(3) NOT NULL, - "un" integer NOT NULL, - "region" integer NOT NULL, - "subregion" integer NOT NULL, - "lon" double precision NOT NULL, - "lat" double precision NOT NULL - ) - ; - SELECT AddGeometryColumn('world_worldborders', 'mpoly', 4326, 'MULTIPOLYGON', 2); - ALTER TABLE "world_worldborders" ALTER "mpoly" SET NOT NULL; - CREATE INDEX "world_worldborders_mpoly_id" ON "world_worldborders" USING GIST ( "mpoly" GIST_GEOMETRY_OPS ); - COMMIT; - -If satisfied, you may then create this table in the database by running the -``syncdb`` management command:: - - $ python manage.py syncdb - Creating table world_worldborders - Installing custom SQL for world.WorldBorders model - -The ``syncdb`` command may also prompt you to create an admin user; go ahead and -do so (not required now, may be done at any point in the future using the -``createsuperuser`` management command). - -Importing Spatial Data -====================== - -This section will show you how to take the data from the world borders -shapefile and import it into GeoDjango models using the :ref:`ref-layermapping`. -There are many different different ways to import data in to a -spatial database -- besides the tools included within GeoDjango, you -may also use the following to populate your spatial database: - -* `ogr2ogr`_: Command-line utility, included with GDAL, that - supports loading a multitude of vector data formats into - the PostGIS, MySQL, and Oracle spatial databases. -* `shp2pgsql`_: This utility is included with PostGIS and only supports - ESRI shapefiles. - -.. _ogr2ogr: http://www.gdal.org/ogr2ogr.html -.. _shp2pgsql: http://postgis.refractions.net/documentation/manual-1.5/ch04.html#shp2pgsql_usage - -.. _gdalinterface: - -GDAL Interface --------------- - -Earlier we used the the ``ogrinfo`` to explore the contents of the world borders -shapefile. Included within GeoDjango is an interface to GDAL's powerful OGR -library -- in other words, you'll be able explore all the vector data sources -that OGR supports via a Pythonic API. - -First, invoke the Django shell:: - - $ python manage.py shell - -If the :ref:`worldborders` data was downloaded like earlier in the -tutorial, then we can determine the path using Python's built-in -``os`` module:: - - >>> import os - >>> from geodjango import world - >>> world_shp = os.path.abspath(os.path.join(os.path.dirname(world.__file__), - ... 'data/TM_WORLD_BORDERS-0.3.shp')) - -Now, the world borders shapefile may be opened using GeoDjango's -:class:`~django.contrib.gis.gdal.DataSource` interface:: - - >>> from django.contrib.gis.gdal import * - >>> ds = DataSource(world_shp) - >>> print ds - / ... /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:: - - >>> print len(ds) - 1 - >>> lyr = ds[0] - >>> print lyr - TM_WORLD_BORDERS-0.3 - -You can see what the geometry type of the layer is and how many features it -contains:: - - >>> print lyr.geom_type - Polygon - >>> print len(lyr) - 246 - -.. note:: - - Unfortunately the shapefile data format does not allow for greater - specificity with regards to geometry types. This shapefile, like - many others, actually includes ``MultiPolygon`` geometries in its - features. You need to watch out for this when creating your models - as a GeoDjango ``PolygonField`` will not accept a ``MultiPolygon`` - type geometry -- thus a ``MultiPolygonField`` is used in our model's - definition instead. - -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:: - - >>> srs = lyr.srs - >>> print srs - GEOGCS["GCS_WGS_1984", - DATUM["WGS_1984", - SPHEROID["WGS_1984",6378137.0,298.257223563]], - PRIMEM["Greenwich",0.0], - UNIT["Degree",0.0174532925199433]] - >>> srs.proj4 # PROJ.4 representation - '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ' - -Here we've noticed that the shapefile is in the popular WGS84 spatial reference -system -- in other words, the data uses units of degrees longitude and latitude. - -In addition, shapefiles also support attribute fields that may contain -additional data. Here are the fields on the World Borders layer: - - >>> print lyr.fields - ['FIPS', 'ISO2', 'ISO3', 'UN', 'NAME', 'AREA', 'POP2005', 'REGION', 'SUBREGION', 'LON', 'LAT'] - -Here we are examining the OGR types (e.g., whether a field is an integer or -a string) associated with each of the fields: - - >>> [fld.__name__ for fld in lyr.field_types] - ['OFTString', 'OFTString', 'OFTString', 'OFTInteger', 'OFTString', 'OFTInteger', 'OFTInteger', 'OFTInteger', 'OFTInteger', 'OFTReal', 'OFTReal'] - -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):: - - >>> for feat in lyr: - ... print feat.get('NAME'), feat.geom.num_points - ... - Guernsey 18 - Jersey 26 - South Georgia South Sandwich Islands 338 - Taiwan 363 - -:class:`~django.contrib.gis.gdal.Layer` objects may be sliced:: - - >>> 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:: - - >>> feat = lyr[234] - >>> print feat.get('NAME') - San Marino - -Here the boundary geometry for San Marino is extracted and looking -exported to WKT and GeoJSON:: - - >>> geom = feat.geom - >>> print geom.wkt - POLYGON ((12.415798 43.957954,12.450554 ... - >>> print geom.json - { "type": "Polygon", "coordinates": [ [ [ 12.415798, 43.957954 ], [ 12.450554, 43.979721 ], ... - - -``LayerMapping`` ----------------- - -We're going to dive right in -- create a file called ``load.py`` inside the -``world`` application, and insert the following:: - - import os - from django.contrib.gis.utils import LayerMapping - from models import WorldBorders - - world_mapping = { - 'fips' : 'FIPS', - 'iso2' : 'ISO2', - 'iso3' : 'ISO3', - 'un' : 'UN', - 'name' : 'NAME', - 'area' : 'AREA', - 'pop2005' : 'POP2005', - 'region' : 'REGION', - 'subregion' : 'SUBREGION', - 'lon' : 'LON', - 'lat' : 'LAT', - 'mpoly' : 'MULTIPOLYGON', - } - - world_shp = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data/TM_WORLD_BORDERS-0.3.shp')) - - def run(verbose=True): - lm = LayerMapping(WorldBorders, world_shp, world_mapping, - transform=False, encoding='iso-8859-1') - - lm.save(strict=True, verbose=verbose) - -A few notes about what's going on: - -* Each key in the ``world_mapping`` dictionary corresponds to a field in the - ``WorldBorders`` model, and the value is the name of the shapefile field - that data will be loaded from. -* The key ``mpoly`` for the geometry field is ``MULTIPOLYGON``, the - geometry type we wish to import as. Even if simple polygons are encountered - in the shapefile they will automatically be converted into collections prior - to insertion into the database. -* The path to the shapefile is not absolute -- in other words, if you move the - ``world`` application (with ``data`` subdirectory) to a different location, - then the script will still work. -* The ``transform`` keyword is set to ``False`` because the data in the - shapefile does not need to be converted -- it's already in WGS84 (SRID=4326). -* The ``encoding`` keyword is set to the character encoding of string values in - the shapefile. This ensures that string values are read and saved correctly - from their original encoding system. - -Afterwards, 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:: - - >>> from world import load - >>> load.run() - - -.. _ogrinspect-intro: - -Try ``ogrinspect`` ------------------- -Now that you've seen how to define geographic models and import data with the -:ref:`ref-layermapping`, it's possible to further automate this process with -use of the :djadmin:`ogrinspect` management command. The :djadmin:`ogrinspect` -command introspects a GDAL-supported vector data source (e.g., a shapefile) and -generates a model definition and ``LayerMapping`` dictionary automatically. - -The general usage of the command goes as follows:: - - $ python manage.py ogrinspect [options] <data_source> <model_name> [options] - -Where ``data_source`` is the path to the GDAL-supported data source and -``model_name`` is the name to use for the model. Command-line options may -be used to further define how the model is generated. - -For example, the following command nearly reproduces the ``WorldBorders`` model -and mapping dictionary created above, automatically:: - - $ python manage.py ogrinspect world/data/TM_WORLD_BORDERS-0.3.shp WorldBorders --srid=4326 --mapping --multi - -A few notes about the command-line options given above: - -* The ``--srid=4326`` option sets the SRID for the geographic field. -* The ``--mapping`` option tells ``ogrinspect`` to also generate a - mapping dictionary for use with :class:`~django.contrib.gis.utils.LayerMapping`. -* The ``--multi`` option is specified so that the geographic field is a - :class:`~django.contrib.gis.db.models.MultiPolygonField` instead of just a - :class:`~django.contrib.gis.db.models.PolygonField`. - -The command produces the following output, which may be copied -directly into the ``models.py`` of a GeoDjango application:: - - # This is an auto-generated Django model module created by ogrinspect. - from django.contrib.gis.db import models - - class WorldBorders(models.Model): - fips = models.CharField(max_length=2) - iso2 = models.CharField(max_length=2) - iso3 = models.CharField(max_length=3) - un = models.IntegerField() - name = models.CharField(max_length=50) - area = models.IntegerField() - pop2005 = models.IntegerField() - region = models.IntegerField() - subregion = models.IntegerField() - lon = models.FloatField() - lat = models.FloatField() - geom = models.MultiPolygonField(srid=4326) - objects = models.GeoManager() - - # Auto-generated `LayerMapping` dictionary for WorldBorders model - worldborders_mapping = { - 'fips' : 'FIPS', - 'iso2' : 'ISO2', - 'iso3' : 'ISO3', - 'un' : 'UN', - 'name' : 'NAME', - 'area' : 'AREA', - 'pop2005' : 'POP2005', - 'region' : 'REGION', - 'subregion' : 'SUBREGION', - 'lon' : 'LON', - 'lat' : 'LAT', - 'geom' : 'MULTIPOLYGON', - } - -Spatial Queries -=============== - -Spatial Lookups ---------------- -GeoDjango extends the Django ORM and allows the use of spatial lookups. -Let's do an example where we find the ``WorldBorder`` model that contains -a point. First, fire up the management shell:: - - $ python manage.py shell - -Now, define a point of interest [#]_:: - - >>> pnt_wkt = 'POINT(-95.3385 29.7245)' - -The ``pnt_wkt`` string represents the point at -95.3385 degrees longitude, -and 29.7245 degrees latitude. The geometry is in a format known as -Well Known Text (WKT), an open standard issued by the Open Geospatial -Consortium (OGC). [#]_ Import the ``WorldBorders`` model, and perform -a ``contains`` lookup using the ``pnt_wkt`` as the parameter:: - - >>> from world.models import WorldBorders - >>> qs = WorldBorders.objects.filter(mpoly__contains=pnt_wkt) - >>> qs - [<WorldBorders: United States>] - -Here we retrieved a ``GeoQuerySet`` that has only one model: the one -for the United States (which is what we would expect). Similarly, -a :ref:`GEOS geometry object <ref-geos>` may also be used -- here the ``intersects`` -spatial lookup is combined with the ``get`` method to retrieve -only the ``WorldBorders`` instance for San Marino instead of a queryset:: - - >>> from django.contrib.gis.geos import Point - >>> pnt = Point(12.4604, 43.9420) - >>> sm = WorldBorders.objects.get(mpoly__intersects=pnt) - >>> sm - <WorldBorders: San Marino> - -The ``contains`` and ``intersects`` lookups are just a subset of what's -available -- the :ref:`ref-gis-db-api` documentation has more. - -Automatic Spatial Transformations ---------------------------------- -When querying the spatial database GeoDjango automatically transforms -geometries if they're in a different coordinate system. In the following -example, the coordinate will be expressed in terms of `EPSG SRID 32140`__, -a coordinate system specific to south Texas **only** and in units of -**meters** and not degrees:: - - >>> from django.contrib.gis.geos import * - >>> pnt = Point(954158.1, 4215137.1, srid=32140) - -Note that ``pnt`` may also constructed with EWKT, an "extended" form of -WKT that includes the SRID:: - - >>> pnt = GEOSGeometry('SRID=32140;POINT(954158.1 4215137.1)') - -When using GeoDjango's ORM, it will automatically wrap geometry values -in transformation SQL, allowing the developer to work at a higher level -of abstraction:: - - >>> qs = WorldBorders.objects.filter(mpoly__intersects=pnt) - >>> qs.query.as_sql() # Generating the SQL - ('SELECT "world_worldborders"."id", "world_worldborders"."name", "world_worldborders"."area", - "world_worldborders"."pop2005", "world_worldborders"."fips", "world_worldborders"."iso2", - "world_worldborders"."iso3", "world_worldborders"."un", "world_worldborders"."region", - "world_worldborders"."subregion", "world_worldborders"."lon", "world_worldborders"."lat", - "world_worldborders"."mpoly" FROM "world_worldborders" - WHERE ST_Intersects("world_worldborders"."mpoly", ST_Transform(%s, 4326))', - (<django.contrib.gis.db.backend.postgis.adaptor.PostGISAdaptor object at 0x25641b0>,)) - >>> qs # printing evaluates the queryset - [<WorldBorders: United States>] - -__ http://spatialreference.org/ref/epsg/32140/ - -Lazy Geometries ---------------- -Geometries come to GeoDjango in a standardized textual representation. Upon -access of the geometry field, GeoDjango creates a `GEOS geometry object <ref-geos>`, -exposing powerful functionality, such as serialization properties for -popular geospatial formats:: - - >>> sm = WorldBorders.objects.get(name='San Marino') - >>> sm.mpoly - <MultiPolygon object at 0x24c6798> - >>> sm.mpoly.wkt # WKT - MULTIPOLYGON (((12.4157980000000006 43.9579540000000009, 12.4505540000000003 43.9797209999999978, ... - >>> sm.mpoly.wkb # WKB (as Python binary buffer) - <read-only buffer for 0x1fe2c70, size -1, offset 0 at 0x2564c40> - >>> sm.mpoly.geojson # GeoJSON (requires GDAL) - '{ "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:: - - >>> pnt = Point(12.4604, 43.9420) - >>> sm.mpoly.contains(pnt) - True - >>> pnt.contains(sm.mpoly) - False - -``GeoQuerySet`` Methods ------------------------ - - -Putting your data on the map -============================ - -Google ------- - -Geographic Admin ----------------- - -GeoDjango extends :doc:`Django's admin application </ref/contrib/admin/index>` -to enable support for editing geometry fields. - -Basics -^^^^^^ - -GeoDjango also supplements the Django admin by allowing users to create -and modify geometries on a JavaScript slippy map (powered by `OpenLayers`_). - -Let's dive in again -- create a file called ``admin.py`` inside the -``world`` application, and insert the following:: - - from django.contrib.gis import admin - from models import WorldBorders - - admin.site.register(WorldBorders, admin.GeoModelAdmin) - -Next, edit your ``urls.py`` in the ``geodjango`` project folder to look -as follows:: - - from django.conf.urls.defaults import * - from django.contrib.gis import admin - - admin.autodiscover() - - urlpatterns = patterns('', - (r'^admin/', include(admin.site.urls)), - ) - -Start up the Django development server:: - - $ python manage.py runserver - -Finally, browse to ``http://localhost:8000/admin/``, and log in with the admin -user created after running ``syncdb``. Browse to any of the ``WorldBorders`` -entries -- the borders may be edited by clicking on a polygon and dragging -the vertexes to the desired position. - -.. _OpenLayers: http://openlayers.org/ -.. _Open Street Map: http://openstreetmap.org/ -.. _Vector Map Level 0: http://earth-info.nga.mil/publications/vmap0.html -.. _Metacarta: http://metacarta.com - -.. _osmgeoadmin-intro: - -``OSMGeoAdmin`` -^^^^^^^^^^^^^^^ - -With the :class:`~django.contrib.gis.admin.OSMGeoAdmin`, GeoDjango uses -a `Open Street Map`_ layer in the admin. -This provides more context (including street and thoroughfare details) than -available with the :class:`~django.contrib.gis.admin.GeoModelAdmin` -(which uses the `Vector Map Level 0`_ WMS data set hosted at `Metacarta`_). - -First, there are some important requirements and limitations: - -* :class:`~django.contrib.gis.admin.OSMGeoAdmin` requires that the - :ref:`spherical mercator projection be added <addgoogleprojection>` - to the to be added to the ``spatial_ref_sys`` table (PostGIS 1.3 and - below, only). -* The PROJ.4 datum shifting files must be installed (see the - :ref:`PROJ.4 installation instructions <proj4>` for more details). - -If you meet these requirements, then just substitute in the ``OSMGeoAdmin`` -option class in your ``admin.py`` file:: - - admin.site.register(WorldBorders, admin.OSMGeoAdmin) - -.. rubric:: Footnotes - -.. [#] Special thanks to Bjørn Sandvik of `thematicmapping.org <http://thematicmapping.org>`_ for providing and maintaining this data set. -.. [#] GeoDjango basic apps was written by Dane Springmeyer, Josh Livni, and Christopher Schmidt. -.. [#] Here the point is for the `University of Houston Law Center <http://www.law.uh.edu/>`_ . -.. [#] Open Geospatial Consortium, Inc., `OpenGIS Simple Feature Specification For SQL <http://www.opengis.org/docs/99-049.pdf>`_, Document 99-049. diff --git a/parts/django/docs/ref/contrib/gis/utils.txt b/parts/django/docs/ref/contrib/gis/utils.txt deleted file mode 100644 index 9f8e518..0000000 --- a/parts/django/docs/ref/contrib/gis/utils.txt +++ /dev/null @@ -1,32 +0,0 @@ -.. _ref-gis-utils: - -=================== -GeoDjango Utilities -=================== - -.. module:: django.contrib.gis.utils - :synopsis: GeoDjango's collection of utilities. - -The :mod:`django.contrib.gis.utils` module contains various utilities that are -useful in creating geospatial Web applications. - -.. toctree:: - :maxdepth: 2 - - geoip - layermapping - ogrinspect - -GeoIP -===== - -Interface to the MaxMind GeoIP library for performing IP-based geolocation -from GeoDjango. See :ref:`GeoIP reference <ref-geoip>` documentation for -more information. - -LayerMapping -============ - -The :class:`~django.contrib.gis.utils.LayerMapping` simplifies the process -of importing spatial data and attributes into your GeoDjango models. - diff --git a/parts/django/docs/ref/contrib/humanize.txt b/parts/django/docs/ref/contrib/humanize.txt deleted file mode 100644 index b5ec518..0000000 --- a/parts/django/docs/ref/contrib/humanize.txt +++ /dev/null @@ -1,100 +0,0 @@ -======================== -django.contrib.humanize -======================== - -.. module:: django.contrib.humanize - :synopsis: A set of Django template filters useful for adding a "human - touch" to data. - -A set of Django template filters useful for adding a "human touch" to data. - -To activate these filters, add ``'django.contrib.humanize'`` to your -:setting:`INSTALLED_APPS` setting. Once you've done that, use -``{% load humanize %}`` in a template, and you'll have access to the following -filters. - -.. templatefilter:: apnumber - -apnumber --------- - -For numbers 1-9, returns the number spelled out. Otherwise, returns the -number. This follows Associated Press style. - -Examples: - - * ``1`` becomes ``one``. - * ``2`` becomes ``two``. - * ``10`` becomes ``10``. - -You can pass in either an integer or a string representation of an integer. - -.. templatefilter:: intcomma - -intcomma --------- - -Converts an integer to a string containing commas every three digits. - -Examples: - - * ``4500`` becomes ``4,500``. - * ``45000`` becomes ``45,000``. - * ``450000`` becomes ``450,000``. - * ``4500000`` becomes ``4,500,000``. - -You can pass in either an integer or a string representation of an integer. - -.. templatefilter:: intword - -intword -------- - -Converts a large integer to a friendly text representation. Works best for -numbers over 1 million. - -Examples: - - * ``1000000`` becomes ``1.0 million``. - * ``1200000`` becomes ``1.2 million``. - * ``1200000000`` becomes ``1.2 billion``. - -Values up to 1000000000000000 (one quadrillion) are supported. - -You can pass in either an integer or a string representation of an integer. - -.. templatefilter:: naturalday - -naturalday ----------- - -.. versionadded:: 1.0 - -For dates that are the current day or within one day, return "today", -"tomorrow" or "yesterday", as appropriate. Otherwise, format the date using -the passed in format string. - -**Argument:** Date formatting string as described in the :tfilter:`date` tag. - -Examples (when 'today' is 17 Feb 2007): - - * ``16 Feb 2007`` becomes ``yesterday``. - * ``17 Feb 2007`` becomes ``today``. - * ``18 Feb 2007`` becomes ``tomorrow``. - * Any other day is formatted according to given argument or the - :setting:`DATE_FORMAT` setting if no argument is given. - -.. templatefilter:: ordinal - -ordinal -------- - -Converts an integer to its ordinal as a string. - -Examples: - - * ``1`` becomes ``1st``. - * ``2`` becomes ``2nd``. - * ``3`` becomes ``3rd``. - -You can pass in either an integer or a string representation of an integer. diff --git a/parts/django/docs/ref/contrib/index.txt b/parts/django/docs/ref/contrib/index.txt deleted file mode 100644 index 90edf72..0000000 --- a/parts/django/docs/ref/contrib/index.txt +++ /dev/null @@ -1,207 +0,0 @@ -==================== -``contrib`` packages -==================== - -Django aims to follow Python's `"batteries included" philosophy`_. It ships -with a variety of extra, optional tools that solve common Web-development -problems. - -This code lives in ``django/contrib`` in the Django distribution. This document -gives a rundown of the packages in ``contrib``, along with any dependencies -those packages have. - -.. admonition:: Note - - For most of these add-ons -- specifically, the add-ons that include either - models or template tags -- you'll need to add the package name (e.g., - ``'django.contrib.admin'``) to your ``INSTALLED_APPS`` setting and re-run - ``manage.py syncdb``. - -.. _"batteries included" philosophy: http://docs.python.org/tutorial/stdlib.html#batteries-included - -.. toctree:: - :maxdepth: 1 - - admin/index - auth - comments/index - contenttypes - csrf - databrowse - flatpages - formtools/index - gis/index - humanize - localflavor - markup - messages - redirects - sitemaps - sites - syndication - webdesign - -admin -===== - -The automatic Django administrative interface. For more information, see -:doc:`Tutorial 2 </intro/tutorial02>` and the -:doc:`admin documentation </ref/contrib/admin/index>`. - -Requires the auth_ and contenttypes_ contrib packages to be installed. - -auth -==== - -Django's authentication framework. - -See :doc:`/topics/auth`. - -comments -======== - -.. versionchanged:: 1.0 - The comments application has been rewriten. See :doc:`/ref/contrib/comments/upgrade` - for information on howto upgrade. - -A simple yet flexible comments system. See :doc:`/ref/contrib/comments/index`. - -contenttypes -============ - -A light framework for hooking into "types" of content, where each installed -Django model is a separate content type. - -See the :doc:`contenttypes documentation </ref/contrib/contenttypes>`. - -csrf -==== - -A middleware for preventing Cross Site Request Forgeries - -See the :doc:`csrf documentation </ref/contrib/csrf>`. - -flatpages -========= - -A framework for managing simple "flat" HTML content in a database. - -See the :doc:`flatpages documentation </ref/contrib/flatpages>`. - -Requires the sites_ contrib package to be installed as well. - -formtools -========= - -A set of high-level abstractions for Django forms (django.forms). - -django.contrib.formtools.preview --------------------------------- - -An abstraction of the following workflow: - -"Display an HTML form, force a preview, then do something with the submission." - -See the :doc:`form preview documentation </ref/contrib/formtools/form-preview>`. - -django.contrib.formtools.wizard --------------------------------- - -Splits forms across multiple Web pages. - -See the :doc:`form wizard documentation </ref/contrib/formtools/form-wizard>`. - -gis -==== - -A world-class geospatial framework built on top of Django, that enables -storage, manipulation and display of spatial data. - -See the :doc:`/ref/contrib/gis/index` documentation for more. - -humanize -======== - -A set of Django template filters useful for adding a "human touch" to data. - -See the :doc:`humanize documentation </ref/contrib/humanize>`. - -localflavor -=========== - -A collection of various Django snippets that are useful only for a particular -country or culture. For example, ``django.contrib.localflavor.us.forms`` -contains a ``USZipCodeField`` that you can use to validate U.S. zip codes. - -See the :doc:`localflavor documentation </ref/contrib/localflavor>`. - -markup -====== - -A collection of template filters that implement common markup languages - -See the :doc:`markup documentation </ref/contrib/markup>`. - -messages -======== - -.. versionchanged:: 1.2 - The messages framework was added. - -A framework for storing and retrieving temporary cookie- or session-based -messages - -See the :doc:`messages documentation </ref/contrib/messages>`. - -redirects -========= - -A framework for managing redirects. - -See the :doc:`redirects documentation </ref/contrib/redirects>`. - -sessions -======== - -A framework for storing data in anonymous sessions. - -See the :doc:`sessions documentation </topics/http/sessions>`. - -sites -===== - -A light framework that lets you operate multiple Web sites off of the same -database and Django installation. It gives you hooks for associating objects to -one or more sites. - -See the :doc:`sites documentation </ref/contrib/sites>`. - -sitemaps -======== - -A framework for generating Google sitemap XML files. - -See the :doc:`sitemaps documentation </ref/contrib/sitemaps>`. - -syndication -=========== - -A framework for generating syndication feeds, in RSS and Atom, quite easily. - -See the :doc:`syndication documentation </ref/contrib/syndication>`. - -webdesign -========= - -Helpers and utilities targeted primarily at Web *designers* rather than -Web *developers*. - -See the :doc:`Web design helpers documentation </ref/contrib/webdesign>`. - -Other add-ons -============= - -If you have an idea for functionality to include in ``contrib``, let us know! -Code it up, and post it to the `django-users mailing list`_. - -.. _django-users mailing list: http://groups.google.com/group/django-users diff --git a/parts/django/docs/ref/contrib/localflavor.txt b/parts/django/docs/ref/contrib/localflavor.txt deleted file mode 100644 index 2eb731d..0000000 --- a/parts/django/docs/ref/contrib/localflavor.txt +++ /dev/null @@ -1,842 +0,0 @@ -========================== -The "local flavor" add-ons -========================== - -.. module:: django.contrib.localflavor - :synopsis: A collection of various Django snippets that are useful only for - a particular country or culture. - -Following its "batteries included" philosophy, Django comes with assorted -pieces of code that are useful for particular countries or cultures. These are -called the "local flavor" add-ons and live in the -:mod:`django.contrib.localflavor` package. - -Inside that package, country- or culture-specific code is organized into -subpackages, named using `ISO 3166 country codes`_. - -Most of the ``localflavor`` add-ons are localized form components deriving -from the :doc:`forms </topics/forms/index>` framework -- for example, a -:class:`~django.contrib.localflavor.us.forms.USStateField` that knows how to -validate U.S. state abbreviations, and a -:class:`~django.contrib.localflavor.fi.forms.FISocialSecurityNumber` that -knows how to validate Finnish social security numbers. - -To use one of these localized components, just import the relevant subpackage. -For example, here's how you can create a form with a field representing a -French telephone number:: - - from django import forms - from django.contrib.localflavor.fr.forms import FRPhoneNumberField - - class MyForm(forms.Form): - my_french_phone_no = FRPhoneNumberField() - -Supported countries -=================== - -Countries currently supported by :mod:`~django.contrib.localflavor` are: - - * Argentina_ - * Australia_ - * Austria_ - * Brazil_ - * Canada_ - * Chile_ - * Czech_ - * Finland_ - * France_ - * Germany_ - * Iceland_ - * India_ - * Indonesia_ - * Ireland_ - * Italy_ - * Japan_ - * Kuwait_ - * Mexico_ - * `The Netherlands`_ - * Norway_ - * Peru_ - * Poland_ - * Portugal_ - * Romania_ - * Slovakia_ - * `South Africa`_ - * Spain_ - * Sweden_ - * Switzerland_ - * `United Kingdom`_ - * `United States of America`_ - * Uruguay_ - -The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage, -containing useful code that is not specific to one particular country or culture. -Currently, it defines date, datetime and split datetime input fields based on -those from :doc:`forms </topics/forms/index>`, but with non-US default formats. -Here's an example of how to use them:: - - from django import forms - from django.contrib.localflavor import generic - - class MyForm(forms.Form): - my_date_field = generic.forms.DateField() - -.. _ISO 3166 country codes: http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm -.. _Argentina: `Argentina (ar)`_ -.. _Australia: `Australia (au)`_ -.. _Austria: `Austria (at)`_ -.. _Brazil: `Brazil (br)`_ -.. _Canada: `Canada (ca)`_ -.. _Chile: `Chile (cl)`_ -.. _Czech: `Czech (cz)`_ -.. _Finland: `Finland (fi)`_ -.. _France: `France (fr)`_ -.. _Germany: `Germany (de)`_ -.. _The Netherlands: `The Netherlands (nl)`_ -.. _Iceland: `Iceland (is\_)`_ -.. _India: `India (in\_)`_ -.. _Indonesia: `Indonesia (id)`_ -.. _Ireland: `Ireland (ie)`_ -.. _Italy: `Italy (it)`_ -.. _Japan: `Japan (jp)`_ -.. _Kuwait: `Kuwait (kw)`_ -.. _Mexico: `Mexico (mx)`_ -.. _Norway: `Norway (no)`_ -.. _Peru: `Peru (pe)`_ -.. _Poland: `Poland (pl)`_ -.. _Portugal: `Portugal (pt)`_ -.. _Romania: `Romania (ro)`_ -.. _Slovakia: `Slovakia (sk)`_ -.. _South Africa: `South Africa (za)`_ -.. _Spain: `Spain (es)`_ -.. _Sweden: `Sweden (se)`_ -.. _Switzerland: `Switzerland (ch)`_ -.. _United Kingdom: `United Kingdom (uk)`_ -.. _United States of America: `United States of America (us)`_ -.. _Uruguay: `Uruguay (uy)`_ - -Adding flavors -============== - -We'd love to add more of these to Django, so please `create a ticket`_ with -any code you'd like to contribute. One thing we ask is that you please use -Unicode objects (``u'mystring'``) for strings, rather than setting the encoding -in the file. See any of the existing flavors for examples. - -.. _create a ticket: http://code.djangoproject.com/simpleticket - -Argentina (``ar``) -============================================= - -.. class:: ar.forms.ARPostalCodeField - - A form field that validates input as either a classic four-digit Argentinian - postal code or a CPA_. - -.. _CPA: http://www.correoargentino.com.ar/consulta_cpa/home.php - -.. class:: ar.forms.ARDNIField - - A form field that validates input as a Documento Nacional de Identidad (DNI) - number. - -.. class:: ar.forms.ARCUITField - - A form field that validates input as a Codigo Unico de Identificacion - Tributaria (CUIT) number. - -.. class:: ar.forms.ARProvinceSelect - - A ``Select`` widget that uses a list of Argentina's provinces and autonomous - cities as its choices. - -Australia (``au``) -============================================= - -.. class:: au.forms.AUPostCodeField - - A form field that validates input as an Australian postcode. - -.. class:: au.forms.AUPhoneNumberField - - A form field that validates input as an Australian phone number. Valid numbers - have ten digits. - -.. class:: au.forms.AUStateSelect - - A ``Select`` widget that uses a list of Australian states/territories as its - choices. - -Austria (``at``) -================ - -.. class:: at.forms.ATZipCodeField - - A form field that validates its input as an Austrian zip code. - -.. class:: at.forms.ATStateSelect - - A ``Select`` widget that uses a list of Austrian states as its choices. - -.. class:: at.forms.ATSocialSecurityNumberField - - A form field that validates its input as an Austrian social security number. - -Brazil (``br``) -=============== - -.. class:: br.forms.BRPhoneNumberField - - A form field that validates input as a Brazilian phone number, with the format - XX-XXXX-XXXX. - -.. class:: br.forms.BRZipCodeField - - A form field that validates input as a Brazilian zip code, with the format - XXXXX-XXX. - -.. class:: br.forms.BRStateSelect - - A ``Select`` widget that uses a list of Brazilian states/territories as its - choices. - -.. class:: br.forms.BRCPFField - - A form field that validates input as `Brazilian CPF`_. - - Input can either be of the format XXX.XXX.XXX-VD or be a group of 11 digits. - -.. _Brazilian CPF: http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas - -.. class:: br.forms.BRCNPJField - - A form field that validates input as `Brazilian CNPJ`_. - - Input can either be of the format XX.XXX.XXX/XXXX-XX or be a group of 14 - digits. - -.. _Brazilian CNPJ: http://en.wikipedia.org/wiki/National_identification_number#Brazil - -Canada (``ca``) -=============== - -.. class:: ca.forms.CAPhoneNumberField - - A form field that validates input as a Canadian phone number, with the format - XXX-XXX-XXXX. - -.. class:: ca.forms.CAPostalCodeField - - A form field that validates input as a Canadian postal code, with the format - XXX XXX. - -.. class:: ca.forms.CAProvinceField - - A form field that validates input as a Canadian province name or abbreviation. - -.. class:: ca.forms.CASocialInsuranceNumberField - - A form field that validates input as a Canadian Social Insurance Number (SIN). - A valid number must have the format XXX-XXX-XXX and pass a `Luhn mod-10 - checksum`_. - -.. _Luhn mod-10 checksum: http://en.wikipedia.org/wiki/Luhn_algorithm - -.. class:: ca.forms.CAProvinceSelect - - A ``Select`` widget that uses a list of Canadian provinces and territories as - its choices. - -Chile (``cl``) -============== - -.. class:: cl.forms.CLRutField - - A form field that validates input as a Chilean national identification number - ('Rol Unico Tributario' or RUT). The valid format is XX.XXX.XXX-X. - -.. class:: cl.forms.CLRegionSelect - - A ``Select`` widget that uses a list of Chilean regions (Regiones) as its - choices. - -Czech (``cz``) -============== - -.. class:: cz.forms.CZPostalCodeField - - A form field that validates input as a Czech postal code. Valid formats - are XXXXX or XXX XX, where X is a digit. - -.. class:: cz.forms.CZBirthNumberField - - A form field that validates input as a Czech Birth Number. - A valid number must be in format XXXXXX/XXXX (slash is optional). - -.. class:: cz.forms.CZICNumberField - - A form field that validates input as a Czech IC number field. - -.. class:: cz.forms.CZRegionSelect - - A ``Select`` widget that uses a list of Czech regions as its choices. - -Finland (``fi``) -================ - -.. class:: fi.forms.FISocialSecurityNumber - - A form field that validates input as a Finnish social security number. - -.. class:: fi.forms.FIZipCodeField - - A form field that validates input as a Finnish zip code. Valid codes - consist of five digits. - -.. class:: fi.forms.FIMunicipalitySelect - - A ``Select`` widget that uses a list of Finnish municipalities as its - choices. - -France (``fr``) -=============== - -.. class:: fr.forms.FRPhoneNumberField - - A form field that validates input as a French local phone number. The - correct format is 0X XX XX XX XX. 0X.XX.XX.XX.XX and 0XXXXXXXXX validate - but are corrected to 0X XX XX XX XX. - -.. class:: fr.forms.FRZipCodeField - - A form field that validates input as a French zip code. Valid codes - consist of five digits. - -.. class:: fr.forms.FRDepartmentSelect - - A ``Select`` widget that uses a list of French departments as its choices. - -Germany (``de``) -================ - -.. class:: de.forms.DEIdentityCardNumberField - - A form field that validates input as a German identity card number - (Personalausweis_). Valid numbers have the format - XXXXXXXXXXX-XXXXXXX-XXXXXXX-X, with no group consisting entirely of zeroes. - -.. _Personalausweis: http://de.wikipedia.org/wiki/Personalausweis - -.. class:: de.forms.DEZipCodeField - - A form field that validates input as a German zip code. Valid codes - consist of five digits. - -.. class:: de.forms.DEStateSelect - - A ``Select`` widget that uses a list of German states as its choices. - -The Netherlands (``nl``) -======================== - -.. class:: nl.forms.NLPhoneNumberField - - A form field that validates input as a Dutch telephone number. - -.. class:: nl.forms.NLSofiNumberField - - A form field that validates input as a Dutch social security number - (SoFI/BSN). - -.. class:: nl.forms.NLZipCodeField - - A form field that validates input as a Dutch zip code. - -.. class:: nl.forms.NLProvinceSelect - - A ``Select`` widget that uses a list of Dutch provinces as its list of - choices. - -Iceland (``is_``) -================= - -.. class:: is_.forms.ISIdNumberField - - A form field that validates input as an Icelandic identification number - (kennitala). The format is XXXXXX-XXXX. - -.. class:: is_.forms.ISPhoneNumberField - - A form field that validates input as an Icelandtic phone number (seven - digits with an optional hyphen or space after the first three digits). - -.. class:: is_.forms.ISPostalCodeSelect - - A ``Select`` widget that uses a list of Icelandic postal codes as its - choices. - -India (``in_``) -=============== - -.. class:: in.forms.INStateField - - A form field that validates input as an Indian state/territory name or - abbreviation. Input is normalized to the standard two-letter vehicle - registration abbreviation for the given state or territory. - -.. class:: in.forms.INZipCodeField - - A form field that validates input as an Indian zip code, with the - format XXXXXXX. - -.. class:: in.forms.INStateSelect - - A ``Select`` widget that uses a list of Indian states/territories as its - choices. - -Ireland (``ie``) -================ - -.. class:: ie.forms.IECountySelect - - A ``Select`` widget that uses a list of Irish Counties as its choices. - -Indonesia (``id``) -================== - -.. class:: id.forms.IDPostCodeField - - A form field that validates input as an Indonesian post code field. - -.. class:: id.forms.IDProvinceSelect - - A ``Select`` widget that uses a list of Indonesian provinces as its choices. - -.. class:: id.forms.IDPhoneNumberField - - A form field that validates input as an Indonesian telephone number. - -.. class:: id.forms.IDLicensePlatePrefixSelect - - A ``Select`` widget that uses a list of Indonesian license plate - prefix code as its choices. - -.. class:: id.forms.IDLicensePlateField - - A form field that validates input as an Indonesian vehicle license plate. - -.. class:: id.forms.IDNationalIdentityNumberField - - A form field that validates input as an Indonesian national identity - number (`NIK`_/KTP). The output will be in the format of - 'XX.XXXX.DDMMYY.XXXX'. Dots or spaces can be used in the input to break - down the numbers. - -.. _NIK: http://en.wikipedia.org/wiki/Indonesian_identity_card - -Italy (``it``) -============== - -.. class:: it.forms.ITSocialSecurityNumberField - - A form field that validates input as an Italian social security number - (`codice fiscale`_). - -.. _codice fiscale: http://www.agenziaentrate.it/ilwwcm/connect/Nsi/Servizi/Codice+fiscale+-+tessera+sanitaria/NSI+Informazioni+sulla+codificazione+delle+persone+fisiche - -.. class:: it.forms.ITVatNumberField - - A form field that validates Italian VAT numbers (partita IVA). - -.. class:: it.forms.ITZipCodeField - - A form field that validates input as an Italian zip code. Valid codes - must have five digits. - -.. class:: it.forms.ITProvinceSelect - - A ``Select`` widget that uses a list of Italian provinces as its choices. - -.. class:: it.forms.ITRegionSelect - - A ``Select`` widget that uses a list of Italian regions as its choices. - -Japan (``jp``) -============== - -.. class:: jp.forms.JPPostalCodeField - - A form field that validates input as a Japanese postcode. It accepts seven - digits, with or without a hyphen. - -.. class:: jp.forms.JPPrefectureSelect - - A ``Select`` widget that uses a list of Japanese prefectures as its choices. - -Kuwait (``kw``) -=============== - -.. class:: kw.forms.KWCivilIDNumberField - - A form field that validates input as a Kuwaiti Civil ID number. A valid - Civil ID number must obey the following rules: - - * The number consist of 12 digits. - * The birthdate of the person is a valid date. - * The calculated checksum equals to the last digit of the Civil ID. - -Mexico (``mx``) -=============== - -.. class:: mx.forms.MXStateSelect - - A ``Select`` widget that uses a list of Mexican states as its choices. - -Norway (``no``) -=============== - -.. class:: no.forms.NOSocialSecurityNumber - - A form field that validates input as a Norwegian social security number - (personnummer_). - -.. _personnummer: http://no.wikipedia.org/wiki/Personnummer - -.. class:: no.forms.NOZipCodeField - - A form field that validates input as a Norwegian zip code. Valid codes - have four digits. - -.. class:: no.forms.NOMunicipalitySelect - - A ``Select`` widget that uses a list of Norwegian municipalities (fylker) as - its choices. - -Peru (``pe``) -============= - -.. class:: pe.forms.PEDNIField - - A form field that validates input as a DNI (Peruvian national identity) - number. - -.. class:: pe.forms.PERUCField - - A form field that validates input as an RUC (Registro Unico de - Contribuyentes) number. Valid RUC numbers have 11 digits. - -.. class:: pe.forms.PEDepartmentSelect - - A ``Select`` widget that uses a list of Peruvian Departments as its choices. - -Poland (``pl``) -=============== - -.. class:: pl.forms.PLPESELField - - A form field that validates input as a Polish national identification number - (PESEL_). - -.. _PESEL: http://en.wikipedia.org/wiki/PESEL - -.. class:: pl.forms.PLREGONField - - A form field that validates input as a Polish National Official Business - Register Number (REGON_), having either seven or nine digits. The checksum - algorithm used for REGONs is documented at - http://wipos.p.lodz.pl/zylla/ut/nip-rego.html. - -.. _REGON: http://www.stat.gov.pl/bip/regon_ENG_HTML.htm - -.. class:: pl.forms.PLPostalCodeField - - A form field that validates input as a Polish postal code. The valid format - is XX-XXX, where X is a digit. - -.. class:: pl.forms.PLNIPField - - A form field that validates input as a Polish Tax Number (NIP). Valid - formats are XXX-XXX-XX-XX or XX-XX-XXX-XXX. The checksum algorithm used - for NIPs is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html. - -.. class:: pl.forms.PLCountySelect - - A ``Select`` widget that uses a list of Polish administrative units as its - choices. - -.. class:: pl.forms.PLProvinceSelect - - A ``Select`` widget that uses a list of Polish voivodeships (administrative - provinces) as its choices. - -Portugal (``pt``) -================= - -.. class:: pt.forms.PTZipCodeField - - A form field that validates input as a Portuguese zip code. - -.. class:: pt.forms.PTPhoneNumberField - - A form field that validates input as a Portuguese phone number. - Valid numbers have 9 digits (may include spaces) or start by 00 - or + (international). - -Romania (``ro``) -================ - -.. class:: ro.forms.ROCIFField - - A form field that validates Romanian fiscal identification codes (CIF). The - return value strips the leading RO, if given. - -.. class:: ro.forms.ROCNPField - - A form field that validates Romanian personal numeric codes (CNP). - -.. class:: ro.forms.ROCountyField - - A form field that validates its input as a Romanian county (judet) name or - abbreviation. It normalizes the input to the standard vehicle registration - abbreviation for the given county. This field will only accept names written - with diacritics; consider using ROCountySelect as an alternative. - -.. class:: ro.forms.ROCountySelect - - A ``Select`` widget that uses a list of Romanian counties (judete) as its - choices. - -.. class:: ro.forms.ROIBANField - - A form field that validates its input as a Romanian International Bank - Account Number (IBAN). The valid format is ROXX-XXXX-XXXX-XXXX-XXXX-XXXX, - with or without hyphens. - -.. class:: ro.forms.ROPhoneNumberField - - A form field that validates Romanian phone numbers, short special numbers - excluded. - -.. class:: ro.forms.ROPostalCodeField - - A form field that validates Romanian postal codes. - -Slovakia (``sk``) -================= - -.. class:: sk.forms.SKPostalCodeField - - A form field that validates input as a Slovak postal code. Valid formats - are XXXXX or XXX XX, where X is a digit. - -.. class:: sk.forms.SKDistrictSelect - - A ``Select`` widget that uses a list of Slovak districts as its choices. - -.. class:: sk.forms.SKRegionSelect - - A ``Select`` widget that uses a list of Slovak regions as its choices. - -South Africa (``za``) -===================== - -.. class:: za.forms.ZAIDField - - A form field that validates input as a South African ID number. Validation - uses the Luhn checksum and a simplistic (i.e., not entirely accurate) check - for birth date. - -.. class:: za.forms.ZAPostCodeField - - A form field that validates input as a South African postcode. Valid - postcodes must have four digits. - -Spain (``es``) -============== - -.. class:: es.forms.ESIdentityCardNumberField - - A form field that validates input as a Spanish NIF/NIE/CIF (Fiscal - Identification Number) code. - -.. class:: es.forms.ESCCCField - - A form field that validates input as a Spanish bank account number (Codigo - Cuenta Cliente or CCC). A valid CCC number has the format - EEEE-OOOO-CC-AAAAAAAAAA, where the E, O, C and A digits denote the entity, - office, checksum and account, respectively. The first checksum digit - validates the entity and office. The second checksum digit validates the - account. It is also valid to use a space as a delimiter, or to use no - delimiter. - -.. class:: es.forms.ESPhoneNumberField - - A form field that validates input as a Spanish phone number. Valid numbers - have nine digits, the first of which is 6, 8 or 9. - -.. class:: es.forms.ESPostalCodeField - - A form field that validates input as a Spanish postal code. Valid codes - have five digits, the first two being in the range 01 to 52, representing - the province. - -.. class:: es.forms.ESProvinceSelect - - A ``Select`` widget that uses a list of Spanish provinces as its choices. - -.. class:: es.forms.ESRegionSelect - - A ``Select`` widget that uses a list of Spanish regions as its choices. - -Sweden (``se``) -=============== - -.. class:: se.forms.SECountySelect - - A Select form widget that uses a list of the Swedish counties (län) as its - choices. - - The cleaned value is the official county code -- see - http://en.wikipedia.org/wiki/Counties_of_Sweden for a list. - -.. class:: se.forms.SEOrganisationNumber - - A form field that validates input as a Swedish organisation number - (organisationsnummer). - - It accepts the same input as SEPersonalIdentityField (for sole - proprietorships (enskild firma). However, co-ordination numbers are not - accepted. - - It also accepts ordinary Swedish organisation numbers with the format - NNNNNNNNNN. - - The return value will be YYYYMMDDXXXX for sole proprietors, and NNNNNNNNNN - for other organisations. - -.. class:: se.forms.SEPersonalIdentityNumber - - A form field that validates input as a Swedish personal identity number - (personnummer). - - The correct formats are YYYYMMDD-XXXX, YYYYMMDDXXXX, YYMMDD-XXXX, - YYMMDDXXXX and YYMMDD+XXXX. - - A \+ indicates that the person is older than 100 years, which will be taken - into consideration when the date is validated. - - The checksum will be calculated and checked. The birth date is checked - to be a valid date. - - By default, co-ordination numbers (samordningsnummer) will be accepted. To - only allow real personal identity numbers, pass the keyword argument - coordination_number=False to the constructor. - - The cleaned value will always have the format YYYYMMDDXXXX. - -.. class:: se.forms.SEPostalCodeField - - A form field that validates input as a Swedish postal code (postnummer). - Valid codes consist of five digits (XXXXX). The number can optionally be - formatted with a space after the third digit (XXX XX). - - The cleaned value will never contain the space. - -Switzerland (``ch``) -==================== - -.. class:: ch.forms.CHIdentityCardNumberField - - A form field that validates input as a Swiss identity card number. - A valid number must confirm to the X1234567<0 or 1234567890 format and - have the correct checksums -- see http://adi.kousz.ch/artikel/IDCHE.htm. - -.. class:: ch.forms.CHPhoneNumberField - - A form field that validates input as a Swiss phone number. The correct - format is 0XX XXX XX XX. 0XX.XXX.XX.XX and 0XXXXXXXXX validate but are - corrected to 0XX XXX XX XX. - -.. class:: ch.forms.CHZipCodeField - - A form field that validates input as a Swiss zip code. Valid codes - consist of four digits. - -.. class:: ch.forms.CHStateSelect - - A ``Select`` widget that uses a list of Swiss states as its choices. - -United Kingdom (``uk``) -======================= - -.. class:: uk.forms.UKPostcodeField - - A form field that validates input as a UK postcode. The regular - expression used is sourced from the schema for British Standard BS7666 - address types at http://www.cabinetoffice.gov.uk/media/291293/bs7666-v2-0.xml. - -.. class:: uk.forms.UKCountySelect - - A ``Select`` widget that uses a list of UK counties/regions as its choices. - -.. class:: uk.forms.UKNationSelect - - A ``Select`` widget that uses a list of UK nations as its choices. - -United States of America (``us``) -================================= - -.. class:: us.forms.USPhoneNumberField - - A form field that validates input as a U.S. phone number. - -.. class:: us.forms.USSocialSecurityNumberField - - A form field that validates input as a U.S. Social Security Number (SSN). - A valid SSN must obey the following rules: - - * Format of XXX-XX-XXXX - * No group of digits consisting entirely of zeroes - * Leading group of digits cannot be 666 - * Number not in promotional block 987-65-4320 through 987-65-4329 - * Number not one known to be invalid due to widespread promotional - use or distribution (e.g., the Woolworth's number or the 1962 - promotional number) - -.. class:: us.forms.USStateField - - A form field that validates input as a U.S. state name or abbreviation. It - normalizes the input to the standard two-letter postal service abbreviation - for the given state. - -.. class:: us.forms.USZipCodeField - - A form field that validates input as a U.S. ZIP code. Valid formats are - XXXXX or XXXXX-XXXX. - -.. class:: us.forms.USStateSelect - - A form ``Select`` widget that uses a list of U.S. states/territories as its - choices. - -.. class:: us.models.PhoneNumberField - - A :class:`CharField` that checks that the value is a valid U.S.A.-style phone - number (in the format ``XXX-XXX-XXXX``). - -.. class:: us.models.USStateField - - A model field that forms represent as a ``forms.USStateField`` field and - stores the two-letter U.S. state abbreviation in the database. - -Uruguay (``uy``) -================ - -.. class:: uy.forms.UYCIField - - A field that validates Uruguayan 'Cedula de identidad' (CI) numbers. - -.. class:: uy.forms.UYDepartamentSelect - - A ``Select`` widget that uses a list of Uruguayan departaments as its - choices. diff --git a/parts/django/docs/ref/contrib/markup.txt b/parts/django/docs/ref/contrib/markup.txt deleted file mode 100644 index 9282313..0000000 --- a/parts/django/docs/ref/contrib/markup.txt +++ /dev/null @@ -1,42 +0,0 @@ -===================== -django.contrib.markup -===================== - -.. module:: django.contrib.markup - :synopsis: A collection of template filters that implement common markup languages. - -Django provides template filters that implement the following markup -languages: - - * ``textile`` -- implements `Textile`_ -- requires `PyTextile`_ - * ``markdown`` -- implements `Markdown`_ -- requires `Python-markdown`_ - * ``restructuredtext`` -- implements `reST (reStructured Text)`_ - -- requires `doc-utils`_ - -In each case, the filter expects formatted markup as a string and -returns a string representing the marked-up text. For example, the -``textile`` filter converts text that is marked-up in Textile format -to HTML. - -To activate these filters, add ``'django.contrib.markup'`` to your -:setting:`INSTALLED_APPS` setting. Once you've done that, use -``{% load markup %}`` in a template, and you'll have access to these filters. -For more documentation, read the source code in -:file:`django/contrib/markup/templatetags/markup.py`. - -.. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29 -.. _Markdown: http://en.wikipedia.org/wiki/Markdown -.. _reST (reStructured Text): http://en.wikipedia.org/wiki/ReStructuredText -.. _PyTextile: http://loopcore.com/python-textile/ -.. _Python-markdown: http://www.freewisdom.org/projects/python-markdown -.. _doc-utils: http://docutils.sf.net/ - -reStructured Text ------------------ - -When using the ``restructuredtext`` markup filter you can define a -:setting:`RESTRUCTUREDTEXT_FILTER_SETTINGS` in your django settings to -override the default writer settings. See the `restructuredtext writer -settings`_ for details on what these settings are. - -.. _restructuredtext writer settings: http://docutils.sourceforge.net/docs/user/config.html#html4css1-writer diff --git a/parts/django/docs/ref/contrib/messages.txt b/parts/django/docs/ref/contrib/messages.txt deleted file mode 100644 index 3081f27..0000000 --- a/parts/django/docs/ref/contrib/messages.txt +++ /dev/null @@ -1,411 +0,0 @@ -====================== -The messages framework -====================== - -.. module:: django.contrib.messages - :synopsis: Provides cookie- and session-based temporary message storage. - -Django provides full support for cookie- and session-based messaging, for -both anonymous and authenticated clients. The messages framework allows you -to temporarily store messages in one request and retrieve them for display -in a subsequent request (usually the next one). Every message is tagged -with a specific ``level`` that determines its priority (e.g., ``info``, -``warning``, or ``error``). - -.. versionadded:: 1.2 - The messages framework was added. - -Enabling messages -================= - -Messages are implemented through a :doc:`middleware </ref/middleware>` -class and corresponding :doc:`context processor </ref/templates/api>`. - -To enable message functionality, do the following: - - * Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure - it contains ``'django.contrib.messages.middleware.MessageMiddleware'``. - - If you are using a :ref:`storage backend <message-storage-backends>` that - relies on :doc:`sessions </topics/http/sessions>` (the default), - ``'django.contrib.sessions.middleware.SessionMiddleware'`` must be - enabled and appear before ``MessageMiddleware`` in your - :setting:`MIDDLEWARE_CLASSES`. - - * Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure - it contains ``'django.contrib.messages.context_processors.messages'``. - - * Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS` - setting - -The default ``settings.py`` created by ``django-admin.py startproject`` has -``MessageMiddleware`` activated and the ``django.contrib.messages`` app -installed. Also, the default value for :setting:`TEMPLATE_CONTEXT_PROCESSORS` -contains ``'django.contrib.messages.context_processors.messages'``. - -If you don't want to use messages, you can remove the -``MessageMiddleware`` line from :setting:`MIDDLEWARE_CLASSES`, the ``messages`` -context processor from :setting:`TEMPLATE_CONTEXT_PROCESSORS` and -``'django.contrib.messages'`` from your :setting:`INSTALLED_APPS`. - -Configuring the message engine -============================== - -.. _message-storage-backends: - -Storage backends ----------------- - -The messages framework can use different backends to store temporary messages. -To change which backend is being used, add a `MESSAGE_STORAGE`_ to your -settings, referencing the module and class of the storage class. For -example:: - - MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' - -The value should be the full path of the desired storage class. - -Four storage classes are included: - -``'django.contrib.messages.storage.session.SessionStorage'`` - This class stores all messages inside of the request's session. It - requires Django's ``contrib.sessions`` application. - -``'django.contrib.messages.storage.cookie.CookieStorage'`` - This class stores the message data in a cookie (signed with a secret hash - to prevent manipulation) to persist notifications across requests. Old - messages are dropped if the cookie data size would exceed 4096 bytes. - -``'django.contrib.messages.storage.fallback.FallbackStorage'`` - This class first uses CookieStorage for all messages, falling back to using - SessionStorage for the messages that could not fit in a single cookie. - - Since it is uses SessionStorage, it also requires Django's - ``contrib.session`` application. - -``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'`` - This is the default temporary storage class. - - This class extends FallbackStorage and adds compatibility methods to - to retrieve any messages stored in the user Message model by code that - has not yet been updated to use the new API. This storage is temporary - (because it makes use of code that is pending deprecation) and will be - removed in Django 1.4. At that time, the default storage will become - ``django.contrib.messages.storage.fallback.FallbackStorage``. For more - information, see `LegacyFallbackStorage`_ below. - -To write your own storage class, subclass the ``BaseStorage`` class in -``django.contrib.messages.storage.base`` and implement the ``_get`` and -``_store`` methods. - -LegacyFallbackStorage -^^^^^^^^^^^^^^^^^^^^^ - -The ``LegacyFallbackStorage`` is a temporary tool to facilitate the transition -from the deprecated ``user.message_set`` API and will be removed in Django 1.4 -according to Django's standard deprecation policy. For more information, see -the full :doc:`release process documentation </internals/release-process>`. - -In addition to the functionality in the ``FallbackStorage``, it adds a custom, -read-only storage class that retrieves messages from the user ``Message`` -model. Any messages that were stored in the ``Message`` model (e.g., by code -that has not yet been updated to use the messages framework) will be retrieved -first, followed by those stored in a cookie and in the session, if any. Since -messages stored in the ``Message`` model do not have a concept of levels, they -will be assigned the ``INFO`` level by default. - -Message levels --------------- - -The messages framework is based on a configurable level architecture similar -to that of the Python logging module. Message levels allow you to group -messages by type so they can be filtered or displayed differently in views and -templates. - -The built-in levels (which can be imported from ``django.contrib.messages`` -directly) are: - -=========== ======== -Constant Purpose -=========== ======== -``DEBUG`` Development-related messages that will be ignored (or removed) in a production deployment -``INFO`` Informational messages for the user -``SUCCESS`` An action was successful, e.g. "Your profile was updated successfully" -``WARNING`` A failure did not occur but may be imminent -``ERROR`` An action was **not** successful or some other failure occurred -=========== ======== - -The `MESSAGE_LEVEL`_ setting can be used to change the minimum recorded level -(or it can be `changed per request`_). Attempts to add messages of a level less -than this will be ignored. - -.. _`changed per request`: `Changing the minimum recorded level per-request`_ - -Message tags ------------- - -Message tags are a string representation of the message level plus any -extra tags that were added directly in the view (see -`Adding extra message tags`_ below for more details). Tags are stored in a -string and are separated by spaces. Typically, message tags -are used as CSS classes to customize message style based on message type. By -default, each level has a single tag that's a lowercase version of its own -constant: - -============== =========== -Level Constant Tag -============== =========== -``DEBUG`` ``debug`` -``INFO`` ``info`` -``SUCCESS`` ``success`` -``WARNING`` ``warning`` -``ERROR`` ``error`` -============== =========== - -To change the default tags for a message level (either built-in or custom), -set the `MESSAGE_TAGS`_ setting to a dictionary containing the levels -you wish to change. As this extends the default tags, you only need to provide -tags for the levels you wish to override:: - - from django.contrib.messages import constants as messages - MESSAGE_TAGS = { - messages.INFO: '', - 50: 'critical', - } - -Using messages in views and templates -===================================== - -Adding a message ----------------- - -To add a message, call:: - - from django.contrib import messages - messages.add_message(request, messages.INFO, 'Hello world.') - -Some shortcut methods provide a standard way to add messages with commonly -used tags (which are usually represented as HTML classes for the message):: - - messages.debug(request, '%s SQL statements were executed.' % count) - messages.info(request, 'Three credits remain in your account.') - messages.success(request, 'Profile details updated.') - messages.warning(request, 'Your account expires in three days.') - messages.error(request, 'Document deleted.') - -Displaying messages -------------------- - -In your template, use something like:: - - {% if messages %} - <ul class="messages"> - {% for message in messages %} - <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> - {% endfor %} - </ul> - {% endif %} - -If you're using the context processor, your template should be rendered with a -``RequestContext``. Otherwise, ensure ``messages`` is available to -the template context. - -Creating custom message levels ------------------------------- - -Messages levels are nothing more than integers, so you can define your own -level constants and use them to create more customized user feedback, e.g.:: - - CRITICAL = 50 - - def my_view(request): - messages.add_message(request, CRITICAL, 'A serious error occurred.') - -When creating custom message levels you should be careful to avoid overloading -existing levels. The values for the built-in levels are: - -.. _message-level-constants: - -============== ===== -Level Constant Value -============== ===== -``DEBUG`` 10 -``INFO`` 20 -``SUCCESS`` 25 -``WARNING`` 30 -``ERROR`` 40 -============== ===== - -If you need to identify the custom levels in your HTML or CSS, you need to -provide a mapping via the `MESSAGE_TAGS`_ setting. - -.. note:: - If you are creating a reusable application, it is recommended to use - only the built-in `message levels`_ and not rely on any custom levels. - -Changing the minimum recorded level per-request ------------------------------------------------ - -The minimum recorded level can be set per request via the ``set_level`` -method:: - - from django.contrib import messages - - # Change the messages level to ensure the debug message is added. - messages.set_level(request, messages.DEBUG) - messages.debug(request, 'Test message...') - - # In another request, record only messages with a level of WARNING and higher - messages.set_level(request, messages.WARNING) - messages.success(request, 'Your profile was updated.') # ignored - messages.warning(request, 'Your account is about to expire.') # recorded - - # Set the messages level back to default. - messages.set_level(request, None) - -Similarly, the current effective level can be retrieved with ``get_level``:: - - from django.contrib import messages - current_level = messages.get_level(request) - -For more information on how the minimum recorded level functions, see -`Message levels`_ above. - -Adding extra message tags -------------------------- - -For more direct control over message tags, you can optionally provide a string -containing extra tags to any of the add methods:: - - messages.add_message(request, messages.INFO, 'Over 9000!', - extra_tags='dragonball') - messages.error(request, 'Email box full', extra_tags='email') - -Extra tags are added before the default tag for that level and are space -separated. - -Failing silently when the message framework is disabled -------------------------------------------------------- - -If you're writing a reusable app (or other piece of code) and want to include -messaging functionality, but don't want to require your users to enable it -if they don't want to, you may pass an additional keyword argument -``fail_silently=True`` to any of the ``add_message`` family of methods. For -example:: - - messages.add_message(request, messages.SUCCESS, 'Profile details updated.', - fail_silently=True) - messages.info(request, 'Hello world.', fail_silently=True) - -Internally, Django uses this functionality in the create, update, and delete -:doc:`generic views </topics/http/generic-views>` so that they work even if the -message framework is disabled. - -.. note:: - Setting ``fail_silently=True`` only hides the ``MessageFailure`` that would - otherwise occur when the messages framework disabled and one attempts to - use one of the ``add_message`` family of methods. It does not hide failures - that may occur for other reasons. - -Expiration of messages -====================== - -The messages are marked to be cleared when the storage instance is iterated -(and cleared when the response is processed). - -To avoid the messages being cleared, you can set the messages storage to -``False`` after iterating:: - - storage = messages.get_messages(request) - for message in storage: - do_something_with(message) - storage.used = False - -Behavior of parallel requests -============================= - -Due to the way cookies (and hence sessions) work, **the behavior of any -backends that make use of cookies or sessions is undefined when the same -client makes multiple requests that set or get messages in parallel**. For -example, if a client initiates a request that creates a message in one window -(or tab) and then another that fetches any uniterated messages in another -window, before the first window redirects, the message may appear in the -second window instead of the first window where it may be expected. - -In short, when multiple simultaneous requests from the same client are -involved, messages are not guaranteed to be delivered to the same window that -created them nor, in some cases, at all. Note that this is typically not a -problem in most applications and will become a non-issue in HTML5, where each -window/tab will have its own browsing context. - -Settings -======== - -A few :doc:`Django settings </ref/settings>` give you control over message -behavior: - -MESSAGE_LEVEL -------------- - -Default: ``messages.INFO`` - -This sets the minimum message that will be saved in the message storage. See -`Message levels`_ above for more details. - -.. admonition:: Important - - If you override ``MESSAGE_LEVEL`` in your settings file and rely on any of - the built-in constants, you must import the constants module directly to - avoid the potential for circular imports, e.g.:: - - from django.contrib.messages import constants as message_constants - MESSAGE_LEVEL = message_constants.DEBUG - - If desired, you may specify the numeric values for the constants directly - according to the values in the above :ref:`constants table - <message-level-constants>`. - -MESSAGE_STORAGE ---------------- - -Default: ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'`` - -Controls where Django stores message data. Valid values are: - - * ``'django.contrib.messages.storage.fallback.FallbackStorage'`` - * ``'django.contrib.messages.storage.session.SessionStorage'`` - * ``'django.contrib.messages.storage.cookie.CookieStorage'`` - * ``'django.contrib.messages.storage.user_messages.LegacyFallbackStorage'`` - -See `Storage backends`_ for more details. - -MESSAGE_TAGS ------------- - -Default:: - - {messages.DEBUG: 'debug', - messages.INFO: 'info', - messages.SUCCESS: 'success', - messages.WARNING: 'warning', - messages.ERROR: 'error',} - -This sets the mapping of message level to message tag, which is typically -rendered as a CSS class in HTML. If you specify a value, it will extend -the default. This means you only have to specify those values which you need -to override. See `Displaying messages`_ above for more details. - -.. admonition:: Important - - If you override ``MESSAGE_TAGS`` in your settings file and rely on any of - the built-in constants, you must import the ``constants`` module directly to - avoid the potential for circular imports, e.g.:: - - from django.contrib.messages import constants as message_constants - MESSAGE_TAGS = {message_constants.INFO: ''} - - If desired, you may specify the numeric values for the constants directly - according to the values in the above :ref:`constants table - <message-level-constants>`. - -.. _Django settings: ../settings/ diff --git a/parts/django/docs/ref/contrib/redirects.txt b/parts/django/docs/ref/contrib/redirects.txt deleted file mode 100644 index f1a58cb..0000000 --- a/parts/django/docs/ref/contrib/redirects.txt +++ /dev/null @@ -1,70 +0,0 @@ -================= -The redirects app -================= - -.. module:: django.contrib.redirects - :synopsis: A framework for managing redirects. - -Django comes with an optional redirects application. It lets you store simple -redirects in a database and handles the redirecting for you. - -Installation -============ - -To install the redirects app, follow these steps: - - 1. Add ``'django.contrib.redirects'`` to your :setting:`INSTALLED_APPS` - setting. - 2. Add ``'django.contrib.redirects.middleware.RedirectFallbackMiddleware'`` - to your :setting:`MIDDLEWARE_CLASSES` setting. - 3. Run the command :djadmin:`manage.py syncdb <syncdb>`. - -How it works -============ - -``manage.py syncdb`` creates a ``django_redirect`` table in your database. This -is a simple lookup table with ``site_id``, ``old_path`` and ``new_path`` fields. - -The ``RedirectFallbackMiddleware`` does all of the work. Each time any Django -application raises a 404 error, this middleware checks the redirects database -for the requested URL as a last resort. Specifically, it checks for a redirect -with the given ``old_path`` with a site ID that corresponds to the -:setting:`SITE_ID` setting. - - * If it finds a match, and ``new_path`` is not empty, it redirects to - ``new_path``. - * If it finds a match, and ``new_path`` is empty, it sends a 410 ("Gone") - HTTP header and empty (content-less) response. - * If it doesn't find a match, the request continues to be processed as - usual. - -The middleware only gets activated for 404s -- not for 500s or responses of any -other status code. - -Note that the order of :setting:`MIDDLEWARE_CLASSES` matters. Generally, you -can put ``RedirectFallbackMiddleware`` at the end of the list, because it's a -last resort. - -For more on middleware, read the :doc:`middleware docs -</topics/http/middleware>`. - -How to add, change and delete redirects -======================================= - -Via the admin interface ------------------------ - -If you've activated the automatic Django admin interface, you should see a -"Redirects" section on the admin index page. Edit redirects as you edit any -other object in the system. - -Via the Python API ------------------- - -.. class:: models.Redirect - - Redirects are represented by a standard :doc:`Django model </topics/db/models>`, - which lives in `django/contrib/redirects/models.py`_. You can access redirect - objects via the :doc:`Django database API </topics/db/queries>`. - -.. _django/contrib/redirects/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/redirects/models.py diff --git a/parts/django/docs/ref/contrib/sitemaps.txt b/parts/django/docs/ref/contrib/sitemaps.txt deleted file mode 100644 index eb29c6c..0000000 --- a/parts/django/docs/ref/contrib/sitemaps.txt +++ /dev/null @@ -1,351 +0,0 @@ -===================== -The sitemap framework -===================== - -.. module:: django.contrib.sitemaps - :synopsis: A framework for generating Google sitemap XML files. - -Django comes with a high-level sitemap-generating framework that makes -creating sitemap_ XML files easy. - -.. _sitemap: http://www.sitemaps.org/ - -Overview -======== - -A sitemap is an XML file on your Web site that tells search-engine indexers how -frequently your pages change and how "important" certain pages are in relation -to other pages on your site. This information helps search engines index your -site. - -The Django sitemap framework automates the creation of this XML file by letting -you express this information in Python code. - -It works much like Django's :doc:`syndication framework -</ref/contrib/syndication>`. To create a sitemap, just write a -:class:`~django.contrib.sitemaps.Sitemap` class and point to it in your -:doc:`URLconf </topics/http/urls>`. - -Installation -============ - -To install the sitemap app, follow these steps: - - 1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS` - setting. - - 2. Make sure ``'django.template.loaders.app_directories.Loader'`` - is in your :setting:`TEMPLATE_LOADERS` setting. It's in there by default, - so you'll only need to change this if you've changed that setting. - - 3. Make sure you've installed the - :mod:`sites framework <django.contrib.sites>`. - -(Note: The sitemap application doesn't install any database tables. The only -reason it needs to go into :setting:`INSTALLED_APPS` is so that the -:func:`~django.template.loaders.app_directories.Loader` template -loader can find the default templates.) - -Initialization -============== - -To activate sitemap generation on your Django site, add this line to your -:doc:`URLconf </topics/http/urls>`:: - - (r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}) - -This tells Django to build a sitemap when a client accesses :file:`/sitemap.xml`. - -The name of the sitemap file is not important, but the location is. Search -engines will only index links in your sitemap for the current URL level and -below. For instance, if :file:`sitemap.xml` lives in your root directory, it may -reference any URL in your site. However, if your sitemap lives at -:file:`/content/sitemap.xml`, it may only reference URLs that begin with -:file:`/content/`. - -The sitemap view takes an extra, required argument: ``{'sitemaps': sitemaps}``. -``sitemaps`` should be a dictionary that maps a short section label (e.g., -``blog`` or ``news``) to its :class:`~django.contrib.sitemaps.Sitemap` class -(e.g., ``BlogSitemap`` or ``NewsSitemap``). It may also map to an *instance* of -a :class:`~django.contrib.sitemaps.Sitemap` class (e.g., -``BlogSitemap(some_var)``). - -Sitemap classes -=============== - -A :class:`~django.contrib.sitemaps.Sitemap` class is a simple Python -class that represents a "section" of entries in your sitemap. For example, -one :class:`~django.contrib.sitemaps.Sitemap` class could represent -all the entries of your Weblog, while another could represent all of the -events in your events calendar. - -In the simplest case, all these sections get lumped together into one -:file:`sitemap.xml`, but it's also possible to use the framework to generate a -sitemap index that references individual sitemap files, one per section. (See -`Creating a sitemap index`_ below.) - -:class:`~django.contrib.sitemaps.Sitemap` classes must subclass -``django.contrib.sitemaps.Sitemap``. They can live anywhere in your codebase. - -A simple example -================ - -Let's assume you have a blog system, with an ``Entry`` model, and you want your -sitemap to include all the links to your individual blog entries. Here's how -your sitemap class might look:: - - from django.contrib.sitemaps import Sitemap - from blog.models import Entry - - class BlogSitemap(Sitemap): - changefreq = "never" - priority = 0.5 - - def items(self): - return Entry.objects.filter(is_draft=False) - - def lastmod(self, obj): - return obj.pub_date - -Note: - - * :attr:`~Sitemap.changefreq` and :attr:`~Sitemap.priority` are class - attributes corresponding to ``<changefreq>`` and ``<priority>`` elements, - respectively. They can be made callable as functions, as - :attr:`~Sitemap.lastmod` was in the example. - * :attr:`~Sitemap.items()` is simply a method that returns a list of - objects. The objects returned will get passed to any callable methods - corresponding to a sitemap property (:attr:`~Sitemap.location`, - :attr:`~Sitemap.lastmod`, :attr:`~Sitemap.changefreq`, and - :attr:`~Sitemap.priority`). - * :attr:`~Sitemap.lastmod` should return a Python ``datetime`` object. - * There is no :attr:`~Sitemap.location` method in this example, but you - can provide it in order to specify the URL for your object. By default, - :attr:`~Sitemap.location()` calls ``get_absolute_url()`` on each object - and returns the result. - -Sitemap class reference -======================= - -.. class:: Sitemap - - A ``Sitemap`` class can define the following methods/attributes: - - .. attribute:: Sitemap.items - - **Required.** A method that returns a list of objects. The framework - doesn't care what *type* of objects they are; all that matters is that - these objects get passed to the :attr:`~Sitemap.location()`, - :attr:`~Sitemap.lastmod()`, :attr:`~Sitemap.changefreq()` and - :attr:`~Sitemap.priority()` methods. - - .. attribute:: Sitemap.location - - **Optional.** Either a method or attribute. - - If it's a method, it should return the absolute path for a given object - as returned by :attr:`~Sitemap.items()`. - - If it's an attribute, its value should be a string representing an - absolute path to use for *every* object returned by - :attr:`~Sitemap.items()`. - - In both cases, "absolute path" means a URL that doesn't include the - protocol or domain. Examples: - - * Good: :file:`'/foo/bar/'` - * Bad: :file:`'example.com/foo/bar/'` - * Bad: :file:`'http://example.com/foo/bar/'` - - If :attr:`~Sitemap.location` isn't provided, the framework will call - the ``get_absolute_url()`` method on each object as returned by - :attr:`~Sitemap.items()`. - - .. attribute:: Sitemap.lastmod - - **Optional.** Either a method or attribute. - - If it's a method, it should take one argument -- an object as returned by - :attr:`~Sitemap.items()` -- and return that object's last-modified date/time, as a Python - ``datetime.datetime`` object. - - If it's an attribute, its value should be a Python ``datetime.datetime`` object - representing the last-modified date/time for *every* object returned by - :attr:`~Sitemap.items()`. - - .. attribute:: Sitemap.changefreq - - **Optional.** Either a method or attribute. - - If it's a method, it should take one argument -- an object as returned by - :attr:`~Sitemap.items()` -- and return that object's change frequency, as a Python string. - - If it's an attribute, its value should be a string representing the change - frequency of *every* object returned by :attr:`~Sitemap.items()`. - - Possible values for :attr:`~Sitemap.changefreq`, whether you use a method or attribute, are: - - * ``'always'`` - * ``'hourly'`` - * ``'daily'`` - * ``'weekly'`` - * ``'monthly'`` - * ``'yearly'`` - * ``'never'`` - - .. method:: Sitemap.priority - - **Optional.** Either a method or attribute. - - If it's a method, it should take one argument -- an object as returned by - :attr:`~Sitemap.items()` -- and return that object's priority, as either a string or float. - - If it's an attribute, its value should be either a string or float representing - the priority of *every* object returned by :attr:`~Sitemap.items()`. - - Example values for :attr:`~Sitemap.priority`: ``0.4``, ``1.0``. The default priority of a - page is ``0.5``. See the `sitemaps.org documentation`_ for more. - - .. _sitemaps.org documentation: http://www.sitemaps.org/protocol.html#prioritydef - -Shortcuts -========= - -The sitemap framework provides a couple convenience classes for common cases: - -.. class:: FlatPageSitemap - - The :class:`django.contrib.sitemaps.FlatPageSitemap` class looks at all - publicly visible :mod:`flatpages <django.contrib.flatpages>` - defined for the current :setting:`SITE_ID` (see the - :mod:`sites documentation <django.contrib.sites>`) and - creates an entry in the sitemap. These entries include only the - :attr:`~Sitemap.location` attribute -- not :attr:`~Sitemap.lastmod`, - :attr:`~Sitemap.changefreq` or :attr:`~Sitemap.priority`. - -.. class:: GenericSitemap - - The :class:`django.contrib.sitemaps.GenericSitemap` class works with any - :doc:`generic views </ref/generic-views>` you already have. - To use it, create an instance, passing in the same :data:`info_dict` you pass to - the generic views. The only requirement is that the dictionary have a - :data:`queryset` entry. It may also have a :data:`date_field` entry that specifies a - date field for objects retrieved from the :data:`queryset`. This will be used for - the :attr:`~Sitemap.lastmod` attribute in the generated sitemap. You may - also pass :attr:`~Sitemap.priority` and :attr:`~Sitemap.changefreq` - keyword arguments to the :class:`~django.contrib.sitemaps.GenericSitemap` - constructor to specify these attributes for all URLs. - -Example -------- - -Here's an example of a :doc:`URLconf </topics/http/urls>` using both:: - - from django.conf.urls.defaults import * - from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap - from blog.models import Entry - - info_dict = { - 'queryset': Entry.objects.all(), - 'date_field': 'pub_date', - } - - sitemaps = { - 'flatpages': FlatPageSitemap, - 'blog': GenericSitemap(info_dict, priority=0.6), - } - - urlpatterns = patterns('', - # some generic view using info_dict - # ... - - # the sitemap - (r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}) - ) - -.. _URLconf: ../url_dispatch/ - -Creating a sitemap index -======================== - -The sitemap framework also has the ability to create a sitemap index that -references individual sitemap files, one per each section defined in your -:data:`sitemaps` dictionary. The only differences in usage are: - - * You use two views in your URLconf: :func:`django.contrib.sitemaps.views.index` - and :func:`django.contrib.sitemaps.views.sitemap`. - * The :func:`django.contrib.sitemaps.views.sitemap` view should take a - :data:`section` keyword argument. - -Here's what the relevant URLconf lines would look like for the example above:: - - (r'^sitemap\.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps}), - (r'^sitemap-(?P<section>.+)\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}), - -This will automatically generate a :file:`sitemap.xml` file that references both -:file:`sitemap-flatpages.xml` and :file:`sitemap-blog.xml`. The -:class:`~django.contrib.sitemaps.Sitemap` classes and the :data:`sitemaps` dict -don't change at all. - -You should create an index file if one of your sitemaps has more than 50,000 -URLs. In this case, Django will automatically paginate the sitemap, and the -index will reflect that. - -Pinging Google -============== - -You may want to "ping" Google when your sitemap changes, to let it know to -reindex your site. The sitemaps framework provides a function to do just -that: :func:`django.contrib.sitemaps.ping_google()`. - -.. function:: ping_google - - :func:`ping_google` takes an optional argument, :data:`sitemap_url`, - which should be the absolute path to your site's sitemap (e.g., - :file:`'/sitemap.xml'`). If this argument isn't provided, - :func:`ping_google` will attempt to figure out your - sitemap by performing a reverse looking in your URLconf. - - :func:`ping_google` raises the exception - :exc:`django.contrib.sitemaps.SitemapNotFound` if it cannot determine your - sitemap URL. - -.. admonition:: Register with Google first! - - The :func:`ping_google` command only works if you have registered your - site with `Google Webmaster Tools`_. - -.. _`Google Webmaster Tools`: http://www.google.com/webmasters/tools/ - -One useful way to call :func:`ping_google` is from a model's ``save()`` -method:: - - from django.contrib.sitemaps import ping_google - - class Entry(models.Model): - # ... - def save(self, force_insert=False, force_update=False): - super(Entry, self).save(force_insert, force_update) - try: - ping_google() - except Exception: - # Bare 'except' because we could get a variety - # of HTTP-related exceptions. - pass - -A more efficient solution, however, would be to call :func:`ping_google` from a -cron script, or some other scheduled task. The function makes an HTTP request -to Google's servers, so you may not want to introduce that network overhead -each time you call ``save()``. - -Pinging Google via `manage.py` ------------------------------- - -.. django-admin:: ping_google - -.. versionadded:: 1.0 - -Once the sitemaps application is added to your project, you may also -ping Google using the ``ping_google`` management command:: - - python manage.py ping_google [/sitemap.xml] diff --git a/parts/django/docs/ref/contrib/sites.txt b/parts/django/docs/ref/contrib/sites.txt deleted file mode 100644 index 6d795d0..0000000 --- a/parts/django/docs/ref/contrib/sites.txt +++ /dev/null @@ -1,415 +0,0 @@ -===================== -The "sites" framework -===================== - -.. module:: django.contrib.sites - :synopsis: Lets you operate multiple Web sites from the same database and - Django project - -Django comes with an optional "sites" framework. It's a hook for associating -objects and functionality to particular Web sites, and it's a holding place for -the domain names and "verbose" names of your Django-powered sites. - -Use it if your single Django installation powers more than one site and you -need to differentiate between those sites in some way. - -The whole sites framework is based on a simple model: - -.. class:: django.contrib.sites.models.Site - -This model has :attr:`~django.contrib.sites.models.Site.domain` and -:attr:`~django.contrib.sites.models.Site.name` fields. The :setting:`SITE_ID` -setting specifies the database ID of the -:class:`~django.contrib.sites.models.Site` object associated with that -particular settings file. - -How you use this is up to you, but Django uses it in a couple of ways -automatically via simple conventions. - -Example usage -============= - -Why would you use sites? It's best explained through examples. - -Associating content with multiple sites ---------------------------------------- - -The Django-powered sites LJWorld.com_ and Lawrence.com_ are operated by the -same news organization -- the Lawrence Journal-World newspaper in Lawrence, -Kansas. LJWorld.com focuses on news, while Lawrence.com focuses on local -entertainment. But sometimes editors want to publish an article on *both* -sites. - -The brain-dead way of solving the problem would be to require site producers to -publish the same story twice: once for LJWorld.com and again for Lawrence.com. -But that's inefficient for site producers, and it's redundant to store -multiple copies of the same story in the database. - -The better solution is simple: Both sites use the same article database, and an -article is associated with one or more sites. In Django model terminology, -that's represented by a :class:`~django.db.models.ManyToManyField` in the -``Article`` model:: - - from django.db import models - from django.contrib.sites.models import Site - - class Article(models.Model): - headline = models.CharField(max_length=200) - # ... - sites = models.ManyToManyField(Site) - -This accomplishes several things quite nicely: - - * It lets the site producers edit all content -- on both sites -- in a - single interface (the Django admin). - - * It means the same story doesn't have to be published twice in the - database; it only has a single record in the database. - - * It lets the site developers use the same Django view code for both sites. - The view code that displays a given story just checks to make sure the - requested story is on the current site. It looks something like this:: - - from django.conf import settings - - def article_detail(request, article_id): - try: - a = Article.objects.get(id=article_id, sites__id__exact=settings.SITE_ID) - except Article.DoesNotExist: - raise Http404 - # ... - -.. _ljworld.com: http://www.ljworld.com/ -.. _lawrence.com: http://www.lawrence.com/ - -Associating content with a single site --------------------------------------- - -Similarly, you can associate a model to the :class:`~django.contrib.sites.models.Site` -model in a many-to-one relationship, using -:class:`~django.db.models.fields.related.ForeignKey`. - -For example, if an article is only allowed on a single site, you'd use a model -like this:: - - from django.db import models - from django.contrib.sites.models import Site - - class Article(models.Model): - headline = models.CharField(max_length=200) - # ... - site = models.ForeignKey(Site) - -This has the same benefits as described in the last section. - -Hooking into the current site from views ----------------------------------------- - -You can use the sites framework in your Django views to do -particular things based on the site in which the view is being called. -For example:: - - from django.conf import settings - - def my_view(request): - if settings.SITE_ID == 3: - # Do something. - else: - # Do something else. - -Of course, it's ugly to hard-code the site IDs like that. This sort of -hard-coding is best for hackish fixes that you need done quickly. A slightly -cleaner way of accomplishing the same thing is to check the current site's -domain:: - - from django.conf import settings - from django.contrib.sites.models import Site - - def my_view(request): - current_site = Site.objects.get(id=settings.SITE_ID) - if current_site.domain == 'foo.com': - # Do something - else: - # Do something else. - -The idiom of retrieving the :class:`~django.contrib.sites.models.Site` object -for the value of :setting:`settings.SITE_ID <SITE_ID>` is quite common, so -the :class:`~django.contrib.sites.models.Site` model's manager has a -``get_current()`` method. This example is equivalent to the previous one:: - - from django.contrib.sites.models import Site - - def my_view(request): - current_site = Site.objects.get_current() - if current_site.domain == 'foo.com': - # Do something - else: - # Do something else. - -.. versionchanged:: 1.3 - -For code which relies on getting the current domain but cannot be certain -that the sites framework will be installed for any given project, there is a -utility function :func:`~django.contrib.sites.models.get_current_site` that -takes a request object as an argument and returns either a Site instance (if -the sites framework is installed) or a RequestSite instance (if it is not). -This allows loose coupling with the sites framework and provides a usable -fallback for cases where it is not installed. - -Getting the current domain for display --------------------------------------- - -LJWorld.com and Lawrence.com both have e-mail alert functionality, which lets -readers sign up to get notifications when news happens. It's pretty basic: A -reader signs up on a Web form, and he immediately gets an e-mail saying, -"Thanks for your subscription." - -It'd be inefficient and redundant to implement this signup-processing code -twice, so the sites use the same code behind the scenes. But the "thank you for -signing up" notice needs to be different for each site. By using -:class:`~django.contrib.sites.models.Site` -objects, we can abstract the "thank you" notice to use the values of the -current site's :attr:`~django.contrib.sites.models.Site.name` and -:attr:`~django.contrib.sites.models.Site.domain`. - -Here's an example of what the form-handling view looks like:: - - from django.contrib.sites.models import Site - from django.core.mail import send_mail - - def register_for_newsletter(request): - # Check form values, etc., and subscribe the user. - # ... - - current_site = Site.objects.get_current() - send_mail('Thanks for subscribing to %s alerts' % current_site.name, - 'Thanks for your subscription. We appreciate it.\n\n-The %s team.' % current_site.name, - 'editor@%s' % current_site.domain, - [user.email]) - - # ... - -On Lawrence.com, this e-mail has the subject line "Thanks for subscribing to -lawrence.com alerts." On LJWorld.com, the e-mail has the subject "Thanks for -subscribing to LJWorld.com alerts." Same goes for the e-mail's message body. - -Note that an even more flexible (but more heavyweight) way of doing this would -be to use Django's template system. Assuming Lawrence.com and LJWorld.com have -different template directories (:setting:`TEMPLATE_DIRS`), you could simply farm out -to the template system like so:: - - from django.core.mail import send_mail - from django.template import loader, Context - - def register_for_newsletter(request): - # Check form values, etc., and subscribe the user. - # ... - - subject = loader.get_template('alerts/subject.txt').render(Context({})) - message = loader.get_template('alerts/message.txt').render(Context({})) - send_mail(subject, message, 'editor@ljworld.com', [user.email]) - - # ... - -In this case, you'd have to create :file:`subject.txt` and :file:`message.txt` template -files for both the LJWorld.com and Lawrence.com template directories. That -gives you more flexibility, but it's also more complex. - -It's a good idea to exploit the :class:`~django.contrib.sites.models.Site` -objects as much as possible, to remove unneeded complexity and redundancy. - -Getting the current domain for full URLs ----------------------------------------- - -Django's ``get_absolute_url()`` convention is nice for getting your objects' -URL without the domain name, but in some cases you might want to display the -full URL -- with ``http://`` and the domain and everything -- for an object. -To do this, you can use the sites framework. A simple example:: - - >>> from django.contrib.sites.models import Site - >>> obj = MyModel.objects.get(id=3) - >>> obj.get_absolute_url() - '/mymodel/objects/3/' - >>> Site.objects.get_current().domain - 'example.com' - >>> 'http://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url()) - 'http://example.com/mymodel/objects/3/' - -Caching the current ``Site`` object -=================================== - -.. versionadded:: 1.0 - -As the current site is stored in the database, each call to -``Site.objects.get_current()`` could result in a database query. But Django is a -little cleverer than that: on the first request, the current site is cached, and -any subsequent call returns the cached data instead of hitting the database. - -If for any reason you want to force a database query, you can tell Django to -clear the cache using ``Site.objects.clear_cache()``:: - - # First call; current site fetched from database. - current_site = Site.objects.get_current() - # ... - - # Second call; current site fetched from cache. - current_site = Site.objects.get_current() - # ... - - # Force a database query for the third call. - Site.objects.clear_cache() - current_site = Site.objects.get_current() - -The ``CurrentSiteManager`` -========================== - -.. class:: django.contrib.sites.managers.CurrentSiteManager - -If :class:`~django.contrib.sites.models.Site` plays a key role in your -application, consider using the helpful -:class:`~django.contrib.sites.managers.CurrentSiteManager` in your -model(s). It's a model :doc:`manager </topics/db/managers>` that -automatically filters its queries to include only objects associated -with the current :class:`~django.contrib.sites.models.Site`. - -Use :class:`~django.contrib.sites.managers.CurrentSiteManager` by adding it to -your model explicitly. For example:: - - from django.db import models - from django.contrib.sites.models import Site - from django.contrib.sites.managers import CurrentSiteManager - - class Photo(models.Model): - photo = models.FileField(upload_to='/home/photos') - photographer_name = models.CharField(max_length=100) - pub_date = models.DateField() - site = models.ForeignKey(Site) - objects = models.Manager() - on_site = CurrentSiteManager() - -With this model, ``Photo.objects.all()`` will return all ``Photo`` objects in -the database, but ``Photo.on_site.all()`` will return only the ``Photo`` objects -associated with the current site, according to the :setting:`SITE_ID` setting. - -Put another way, these two statements are equivalent:: - - Photo.objects.filter(site=settings.SITE_ID) - Photo.on_site.all() - -How did :class:`~django.contrib.sites.managers.CurrentSiteManager` -know which field of ``Photo`` was the -:class:`~django.contrib.sites.models.Site`? By default, -:class:`~django.contrib.sites.managers.CurrentSiteManager` looks for a -either a :class:`~django.db.models.fields.related.ForeignKey` called -``site`` or a -:class:`~django.db.models.fields.related.ManyToManyField` called -``sites`` to filter on. If you use a field named something other than -``site`` or ``sites`` to identify which -:class:`~django.contrib.sites.models.Site` objects your object is -related to, then you need to explicitly pass the custom field name as -a parameter to -:class:`~django.contrib.sites.managers.CurrentSiteManager` on your -model. The following model, which has a field called ``publish_on``, -demonstrates this:: - - from django.db import models - from django.contrib.sites.models import Site - from django.contrib.sites.managers import CurrentSiteManager - - class Photo(models.Model): - photo = models.FileField(upload_to='/home/photos') - photographer_name = models.CharField(max_length=100) - pub_date = models.DateField() - publish_on = models.ForeignKey(Site) - objects = models.Manager() - on_site = CurrentSiteManager('publish_on') - -If you attempt to use :class:`~django.contrib.sites.managers.CurrentSiteManager` -and pass a field name that doesn't exist, Django will raise a :exc:`ValueError`. - -Finally, note that you'll probably want to keep a normal -(non-site-specific) ``Manager`` on your model, even if you use -:class:`~django.contrib.sites.managers.CurrentSiteManager`. As -explained in the :doc:`manager documentation </topics/db/managers>`, if -you define a manager manually, then Django won't create the automatic -``objects = models.Manager()`` manager for you. Also note that certain -parts of Django -- namely, the Django admin site and generic views -- -use whichever manager is defined *first* in the model, so if you want -your admin site to have access to all objects (not just site-specific -ones), put ``objects = models.Manager()`` in your model, before you -define :class:`~django.contrib.sites.managers.CurrentSiteManager`. - -How Django uses the sites framework -=================================== - -Although it's not required that you use the sites framework, it's strongly -encouraged, because Django takes advantage of it in a few places. Even if your -Django installation is powering only a single site, you should take the two -seconds to create the site object with your ``domain`` and ``name``, and point -to its ID in your :setting:`SITE_ID` setting. - -Here's how Django uses the sites framework: - -* In the :mod:`redirects framework <django.contrib.redirects>`, each - redirect object is associated with a particular site. When Django searches - for a redirect, it takes into account the current :setting:`SITE_ID`. - -* In the comments framework, each comment is associated with a particular - site. When a comment is posted, its - :class:`~django.contrib.sites.models.Site` is set to the current - :setting:`SITE_ID`, and when comments are listed via the appropriate - template tag, only the comments for the current site are displayed. - -* In the :mod:`flatpages framework <django.contrib.flatpages>`, each - flatpage is associated with a particular site. When a flatpage is created, - you specify its :class:`~django.contrib.sites.models.Site`, and the - :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` - checks the current :setting:`SITE_ID` in retrieving flatpages to display. - -* In the :mod:`syndication framework <django.contrib.syndication>`, the - templates for ``title`` and ``description`` automatically have access to a - variable ``{{ site }}``, which is the - :class:`~django.contrib.sites.models.Site` object representing the current - site. Also, the hook for providing item URLs will use the ``domain`` from - the current :class:`~django.contrib.sites.models.Site` object if you don't - specify a fully-qualified domain. - -* In the :mod:`authentication framework <django.contrib.auth>`, the - :func:`django.contrib.auth.views.login` view passes the current - :class:`~django.contrib.sites.models.Site` name to the template as - ``{{ site_name }}``. - -* The shortcut view (:func:`django.views.defaults.shortcut`) uses the domain - of the current :class:`~django.contrib.sites.models.Site` object when - calculating an object's URL. - -* In the admin framework, the "view on site" link uses the current - :class:`~django.contrib.sites.models.Site` to work out the domain for the - site that it will redirect to. - - -``RequestSite`` objects -======================= - -.. _requestsite-objects: - -.. versionadded:: 1.0 - -Some :doc:`django.contrib </ref/contrib/index>` applications take advantage of -the sites framework but are architected in a way that doesn't *require* the -sites framework to be installed in your database. (Some people don't want to, or -just aren't *able* to install the extra database table that the sites framework -requires.) For those cases, the framework provides a -:class:`~django.contrib.sites.models.RequestSite` class, which can be used as a -fallback when the database-backed sites framework is not available. - -A :class:`~django.contrib.sites.models.RequestSite` object has a similar -interface to a normal :class:`~django.contrib.sites.models.Site` object, except -its :meth:`~django.contrib.sites.models.RequestSite.__init__()` method takes an -:class:`~django.http.HttpRequest` object. It's able to deduce the -:attr:`~django.contrib.sites.models.RequestSite.domain` and -:attr:`~django.contrib.sites.models.RequestSite.name` by looking at the -request's domain. It has :meth:`~django.contrib.sites.models.RequestSite.save()` -and :meth:`~django.contrib.sites.models.RequestSite.delete()` methods to match -the interface of :class:`~django.contrib.sites.models.Site`, but the methods -raise :exc:`NotImplementedError`. diff --git a/parts/django/docs/ref/contrib/syndication.txt b/parts/django/docs/ref/contrib/syndication.txt deleted file mode 100644 index 04f14b5..0000000 --- a/parts/django/docs/ref/contrib/syndication.txt +++ /dev/null @@ -1,949 +0,0 @@ -============================== -The syndication feed framework -============================== - -.. module:: django.contrib.syndication - :synopsis: A framework for generating syndication feeds, in RSS and Atom, - quite easily. - -Django comes with a high-level syndication-feed-generating framework -that makes creating RSS_ and Atom_ feeds easy. - -To create any syndication feed, all you have to do is write a short -Python class. You can create as many feeds as you want. - -Django also comes with a lower-level feed-generating API. Use this if -you want to generate feeds outside of a Web context, or in some other -lower-level way. - -.. _RSS: http://www.whatisrss.com/ -.. _Atom: http://www.atomenabled.org/ - -The high-level framework -======================== - -.. versionchanged:: 1.2 - The high-level feeds framework was refactored in Django 1.2. The - pre-1.2 interface still exists, but it has been deprecated, and - will be removed in Django 1.4. If you need to maintain an old-style - Django feed, please consult the Django 1.1 documentation. For - details on updating to use the new high-level feed framework, see - the :ref:`Django 1.2 release notes <1.2-updating-feeds>`. - -Overview --------- - -The high-level feed-generating framework is supplied by the -:class:`~django.contrib.syndication.views.Feed` class. To create a -feed, write a :class:`~django.contrib.syndication.views.Feed` class -and point to an instance of it in your :doc:`URLconf -</topics/http/urls>`. - -Feed classes ------------- - -A :class:`~django.contrib.syndication.views.Feed` class is a Python -class that represents a syndication feed. A feed can be simple (e.g., -a "site news" feed, or a basic feed displaying the latest entries of a -blog) or more complex (e.g., a feed displaying all the blog entries in -a particular category, where the category is variable). - -Feed classes subclass :class:`django.contrib.syndication.views.Feed`. -They can live anywhere in your codebase. - -Instances of :class:`~django.contrib.syndication.views.Feed` classes -are views which can be used in your :doc:`URLconf </topics/http/urls>`. - -A simple example ----------------- - -This simple example, taken from `chicagocrime.org`_, describes a feed of the -latest five news items:: - - from django.contrib.syndication.views import Feed - from chicagocrime.models import NewsItem - - class LatestEntriesFeed(Feed): - title = "Chicagocrime.org site news" - link = "/sitenews/" - description = "Updates on changes and additions to chicagocrime.org." - - def items(self): - return NewsItem.objects.order_by('-pub_date')[:5] - - def item_title(self, item): - return item.title - - def item_description(self, item): - return item.description - -To connect a URL to this feed, put an instance of the Feed object in -your :doc:`URLconf </topics/http/urls>`. For example:: - - from django.conf.urls.defaults import * - from myproject.feeds import LatestEntriesFeed - - urlpatterns = patterns('', - # ... - (r'^latest/feed/$', LatestEntriesFeed()), - # ... - ) - -Note: - -* The Feed class subclasses :class:`django.contrib.syndication.views.Feed`. - -* :attr:`title`, :attr:`link` and :attr:`description` correspond to the - standard RSS ``<title>``, ``<link>`` and ``<description>`` elements, - respectively. - -* :meth:`items()` is, simply, a method that returns a list of objects that - should be included in the feed as ``<item>`` elements. Although this - example returns ``NewsItem`` objects using Django's - :doc:`object-relational mapper </ref/models/querysets>`, :meth:`items()` - doesn't have to return model instances. Although you get a few bits of - functionality "for free" by using Django models, :meth:`items()` can - return any type of object you want. - -* If you're creating an Atom feed, rather than an RSS feed, set the - :attr:`subtitle` attribute instead of the :attr:`description` attribute. - See `Publishing Atom and RSS feeds in tandem`_, later, for an example. - -One thing is left to do. In an RSS feed, each ``<item>`` has a ``<title>``, -``<link>`` and ``<description>``. We need to tell the framework what data to put -into those elements. - - * For the contents of ``<title>`` and ``<description>``, Django tries - calling the methods :meth:`item_title()` and :meth:`item_description()` on - the :class:`~django.contrib.syndication.views.Feed` class. They are passed - a single parameter, :attr:`item`, which is the object itself. These are - optional; by default, the unicode representation of the object is used for - both. - - If you want to do any special formatting for either the title or - description, :doc:`Django templates </topics/templates>` can be used - instead. Their paths can be specified with the ``title_template`` and - ``description_template`` attributes on the - :class:`~django.contrib.syndication.views.Feed` class. The templates are - rendered for each item and are passed two template context variables: - - * ``{{ obj }}`` -- The current object (one of whichever objects you - returned in :meth:`items()`). - - * ``{{ site }}`` -- A :class:`django.contrib.sites.models.Site` object - representing the current site. This is useful for ``{{ site.domain - }}`` or ``{{ site.name }}``. If you do *not* have the Django sites - framework installed, this will be set to a - :class:`django.contrib.sites.models.RequestSite` object. See the - :ref:`RequestSite section of the sites framework documentation - <requestsite-objects>` for more. - - See `a complex example`_ below that uses a description template. - - * To specify the contents of ``<link>``, you have two options. For each item - in :meth:`items()`, Django first tries calling the - :meth:`item_link()` method on the - :class:`~django.contrib.syndication.views.Feed` class. In a similar way to - the title and description, it is passed it a single parameter, - :attr:`item`. If that method doesn't exist, Django tries executing a - ``get_absolute_url()`` method on that object. Both - :meth:`get_absolute_url()` and :meth:`item_link()` should return the - item's URL as a normal Python string. As with ``get_absolute_url()``, the - result of :meth:`item_link()` will be included directly in the URL, so you - are responsible for doing all necessary URL quoting and conversion to - ASCII inside the method itself. - -.. _chicagocrime.org: http://www.chicagocrime.org/ - -A complex example ------------------ - -The framework also supports more complex feeds, via arguments. - -For example, `chicagocrime.org`_ offers an RSS feed of recent crimes for every -police beat in Chicago. It'd be silly to create a separate -:class:`~django.contrib.syndication.views.Feed` class for each police beat; that -would violate the :ref:`DRY principle <dry>` and would couple data to -programming logic. Instead, the syndication framework lets you access the -arguments passed from your :doc:`URLconf </topics/http/urls>` so feeds can output -items based on information in the feed's URL. - -On chicagocrime.org, the police-beat feeds are accessible via URLs like this: - - * :file:`/beats/613/rss/` -- Returns recent crimes for beat 613. - * :file:`/beats/1424/rss/` -- Returns recent crimes for beat 1424. - -These can be matched with a :doc:`URLconf </topics/http/urls>` line such as:: - - (r'^beats/(?P<beat_id>\d+)/rss/$', BeatFeed()), - -Like a view, the arguments in the URL are passed to the :meth:`get_object()` -method along with the request object. - -.. versionchanged:: 1.2 - Prior to version 1.2, ``get_object()`` only accepted a ``bits`` argument. - -Here's the code for these beat-specific feeds:: - - from django.contrib.syndication.views import FeedDoesNotExist - from django.shortcuts import get_object_or_404 - - class BeatFeed(Feed): - description_template = 'feeds/beat_description.html' - - def get_object(self, request, beat_id): - return get_object_or_404(Beat, pk=beat_id) - - def title(self, obj): - return "Chicagocrime.org: Crimes for beat %s" % obj.beat - - def link(self, obj): - return obj.get_absolute_url() - - def description(self, obj): - return "Crimes recently reported in police beat %s" % obj.beat - - def items(self, obj): - return Crime.objects.filter(beat=obj).order_by('-crime_date')[:30] - -To generate the feed's ``<title>``, ``<link>`` and ``<description>``, Django -uses the :meth:`title()`, :meth:`link()` and :meth:`description()` methods. In -the previous example, they were simple string class attributes, but this example -illustrates that they can be either strings *or* methods. For each of -:attr:`title`, :attr:`link` and :attr:`description`, Django follows this -algorithm: - - * First, it tries to call a method, passing the ``obj`` argument, where - ``obj`` is the object returned by :meth:`get_object()`. - - * Failing that, it tries to call a method with no arguments. - - * Failing that, it uses the class attribute. - -Also note that :meth:`items()` also follows the same algorithm -- first, it -tries :meth:`items(obj)`, then :meth:`items()`, then finally an :attr:`items` -class attribute (which should be a list). - -We are using a template for the item descriptions. It can be very simple: - -.. code-block:: html+django - - {{ obj.description }} - -However, you are free to add formatting as desired. - -The ``ExampleFeed`` class below gives full documentation on methods and -attributes of :class:`~django.contrib.syndication.views.Feed` classes. - -Specifying the type of feed ---------------------------- - -By default, feeds produced in this framework use RSS 2.0. - -To change that, add a ``feed_type`` attribute to your -:class:`~django.contrib.syndication.views.Feed` class, like so:: - - from django.utils.feedgenerator import Atom1Feed - - class MyFeed(Feed): - feed_type = Atom1Feed - -Note that you set ``feed_type`` to a class object, not an instance. - -Currently available feed types are: - - * :class:`django.utils.feedgenerator.Rss201rev2Feed` (RSS 2.01. Default.) - * :class:`django.utils.feedgenerator.RssUserland091Feed` (RSS 0.91.) - * :class:`django.utils.feedgenerator.Atom1Feed` (Atom 1.0.) - -Enclosures ----------- - -To specify enclosures, such as those used in creating podcast feeds, use the -:attr:`item_enclosure_url`, :attr:`item_enclosure_length` and -:attr:`item_enclosure_mime_type` hooks. See the ``ExampleFeed`` class below for -usage examples. - -Language --------- - -Feeds created by the syndication framework automatically include the -appropriate ``<language>`` tag (RSS 2.0) or ``xml:lang`` attribute (Atom). This -comes directly from your :setting:`LANGUAGE_CODE` setting. - -URLs ----- - -The :attr:`link` method/attribute can return either an absolute path (e.g. -:file:`"/blog/"`) or a URL with the fully-qualified domain and protocol (e.g. -``"http://www.example.com/blog/"``). If :attr:`link` doesn't return the domain, -the syndication framework will insert the domain of the current site, according -to your :setting:`SITE_ID setting <SITE_ID>`. - -Atom feeds require a ``<link rel="self">`` that defines the feed's current -location. The syndication framework populates this automatically, using the -domain of the current site according to the :setting:`SITE_ID` setting. - -Publishing Atom and RSS feeds in tandem ---------------------------------------- - -Some developers like to make available both Atom *and* RSS versions of their -feeds. That's easy to do with Django: Just create a subclass of your -:class:`~django.contrib.syndication.views.Feed` -class and set the :attr:`feed_type` to something different. Then update your -URLconf to add the extra versions. - -Here's a full example:: - - from django.contrib.syndication.views import Feed - from chicagocrime.models import NewsItem - from django.utils.feedgenerator import Atom1Feed - - class RssSiteNewsFeed(Feed): - title = "Chicagocrime.org site news" - link = "/sitenews/" - description = "Updates on changes and additions to chicagocrime.org." - - def items(self): - return NewsItem.objects.order_by('-pub_date')[:5] - - class AtomSiteNewsFeed(RssSiteNewsFeed): - feed_type = Atom1Feed - subtitle = RssSiteNewsFeed.description - -.. Note:: - In this example, the RSS feed uses a :attr:`description` while the Atom - feed uses a :attr:`subtitle`. That's because Atom feeds don't provide for - a feed-level "description," but they *do* provide for a "subtitle." - - If you provide a :attr:`description` in your - :class:`~django.contrib.syndication.views.Feed` class, Django will *not* - automatically put that into the :attr:`subtitle` element, because a - subtitle and description are not necessarily the same thing. Instead, you - should define a :attr:`subtitle` attribute. - - In the above example, we simply set the Atom feed's :attr:`subtitle` to the - RSS feed's :attr:`description`, because it's quite short already. - -And the accompanying URLconf:: - - from django.conf.urls.defaults import * - from myproject.feeds import RssSiteNewsFeed, AtomSiteNewsFeed - - urlpatterns = patterns('', - # ... - (r'^sitenews/rss/$', RssSiteNewsFeed()), - (r'^sitenews/atom/$', AtomSiteNewsFeed()), - # ... - ) - -Feed class reference --------------------- - -.. class:: django.contrib.syndication.views.Feed - -This example illustrates all possible attributes and methods for a -:class:`~django.contrib.syndication.views.Feed` class:: - - from django.contrib.syndication.views import Feed - from django.utils import feedgenerator - - class ExampleFeed(Feed): - - # FEED TYPE -- Optional. This should be a class that subclasses - # django.utils.feedgenerator.SyndicationFeed. This designates - # which type of feed this should be: RSS 2.0, Atom 1.0, etc. If - # you don't specify feed_type, your feed will be RSS 2.0. This - # should be a class, not an instance of the class. - - feed_type = feedgenerator.Rss201rev2Feed - - # TEMPLATE NAMES -- Optional. These should be strings - # representing names of Django templates that the system should - # use in rendering the title and description of your feed items. - # Both are optional. If a template is not specified, the - # item_title() or item_description() methods are used instead. - - title_template = None - description_template = None - - # TITLE -- One of the following three is required. The framework - # looks for them in this order. - - def title(self, obj): - """ - Takes the object returned by get_object() and returns the - feed's title as a normal Python string. - """ - - def title(self): - """ - Returns the feed's title as a normal Python string. - """ - - title = 'foo' # Hard-coded title. - - # LINK -- One of the following three is required. The framework - # looks for them in this order. - - def link(self, obj): - """ - # Takes the object returned by get_object() and returns the feed's - # link as a normal Python string. - """ - - def link(self): - """ - Returns the feed's link as a normal Python string. - """ - - link = '/foo/bar/' # Hard-coded link. - - # GUID -- One of the following three is optional. The framework looks - # for them in this order. This property is only used for Atom feeds - # (where it is the feed-level ID element). If not provided, the feed - # link is used as the ID. - - def feed_guid(self, obj): - """ - Takes the object returned by get_object() and returns the globally - unique ID for the feed as a normal Python string. - """ - - def feed_guid(self): - """ - Returns the feed's globally unique ID as a normal Python string. - """ - - feed_guid = '/foo/bar/1234' # Hard-coded guid. - - # DESCRIPTION -- One of the following three is required. The framework - # looks for them in this order. - - def description(self, obj): - """ - Takes the object returned by get_object() and returns the feed's - description as a normal Python string. - """ - - def description(self): - """ - Returns the feed's description as a normal Python string. - """ - - description = 'Foo bar baz.' # Hard-coded description. - - # AUTHOR NAME --One of the following three is optional. The framework - # looks for them in this order. - - def author_name(self, obj): - """ - Takes the object returned by get_object() and returns the feed's - author's name as a normal Python string. - """ - - def author_name(self): - """ - Returns the feed's author's name as a normal Python string. - """ - - author_name = 'Sally Smith' # Hard-coded author name. - - # AUTHOR E-MAIL --One of the following three is optional. The framework - # looks for them in this order. - - def author_email(self, obj): - """ - Takes the object returned by get_object() and returns the feed's - author's e-mail as a normal Python string. - """ - - def author_email(self): - """ - Returns the feed's author's e-mail as a normal Python string. - """ - - author_email = 'test@example.com' # Hard-coded author e-mail. - - # AUTHOR LINK --One of the following three is optional. The framework - # looks for them in this order. In each case, the URL should include - # the "http://" and domain name. - - def author_link(self, obj): - """ - Takes the object returned by get_object() and returns the feed's - author's URL as a normal Python string. - """ - - def author_link(self): - """ - Returns the feed's author's URL as a normal Python string. - """ - - author_link = 'http://www.example.com/' # Hard-coded author URL. - - # CATEGORIES -- One of the following three is optional. The framework - # looks for them in this order. In each case, the method/attribute - # should return an iterable object that returns strings. - - def categories(self, obj): - """ - Takes the object returned by get_object() and returns the feed's - categories as iterable over strings. - """ - - def categories(self): - """ - Returns the feed's categories as iterable over strings. - """ - - categories = ("python", "django") # Hard-coded list of categories. - - # COPYRIGHT NOTICE -- One of the following three is optional. The - # framework looks for them in this order. - - def feed_copyright(self, obj): - """ - Takes the object returned by get_object() and returns the feed's - copyright notice as a normal Python string. - """ - - def feed_copyright(self): - """ - Returns the feed's copyright notice as a normal Python string. - """ - - feed_copyright = 'Copyright (c) 2007, Sally Smith' # Hard-coded copyright notice. - - # TTL -- One of the following three is optional. The framework looks - # for them in this order. Ignored for Atom feeds. - - def ttl(self, obj): - """ - Takes the object returned by get_object() and returns the feed's - TTL (Time To Live) as a normal Python string. - """ - - def ttl(self): - """ - Returns the feed's TTL as a normal Python string. - """ - - ttl = 600 # Hard-coded Time To Live. - - # ITEMS -- One of the following three is required. The framework looks - # for them in this order. - - def items(self, obj): - """ - Takes the object returned by get_object() and returns a list of - items to publish in this feed. - """ - - def items(self): - """ - Returns a list of items to publish in this feed. - """ - - items = ('Item 1', 'Item 2') # Hard-coded items. - - # GET_OBJECT -- This is required for feeds that publish different data - # for different URL parameters. (See "A complex example" above.) - - def get_object(self, request, *args, **kwargs): - """ - Takes the current request and the arguments from the URL, and - returns an object represented by this feed. Raises - django.core.exceptions.ObjectDoesNotExist on error. - """ - - # ITEM TITLE AND DESCRIPTION -- If title_template or - # description_template are not defined, these are used instead. Both are - # optional, by default they will use the unicode representation of the - # item. - - def item_title(self, item): - """ - Takes an item, as returned by items(), and returns the item's - title as a normal Python string. - """ - - def item_title(self): - """ - Returns the title for every item in the feed. - """ - - item_title = 'Breaking News: Nothing Happening' # Hard-coded title. - - def item_description(self, item): - """ - Takes an item, as returned by items(), and returns the item's - description as a normal Python string. - """ - - def item_description(self): - """ - Returns the description for every item in the feed. - """ - - item_description = 'A description of the item.' # Hard-coded description. - - # ITEM LINK -- One of these three is required. The framework looks for - # them in this order. - - # First, the framework tries the two methods below, in - # order. Failing that, it falls back to the get_absolute_url() - # method on each item returned by items(). - - def item_link(self, item): - """ - Takes an item, as returned by items(), and returns the item's URL. - """ - - def item_link(self): - """ - Returns the URL for every item in the feed. - """ - - # ITEM_GUID -- The following method is optional. If not provided, the - # item's link is used by default. - - def item_guid(self, obj): - """ - Takes an item, as return by items(), and returns the item's ID. - """ - - # ITEM AUTHOR NAME -- One of the following three is optional. The - # framework looks for them in this order. - - def item_author_name(self, item): - """ - Takes an item, as returned by items(), and returns the item's - author's name as a normal Python string. - """ - - def item_author_name(self): - """ - Returns the author name for every item in the feed. - """ - - item_author_name = 'Sally Smith' # Hard-coded author name. - - # ITEM AUTHOR E-MAIL --One of the following three is optional. The - # framework looks for them in this order. - # - # If you specify this, you must specify item_author_name. - - def item_author_email(self, obj): - """ - Takes an item, as returned by items(), and returns the item's - author's e-mail as a normal Python string. - """ - - def item_author_email(self): - """ - Returns the author e-mail for every item in the feed. - """ - - item_author_email = 'test@example.com' # Hard-coded author e-mail. - - # ITEM AUTHOR LINK -- One of the following three is optional. The - # framework looks for them in this order. In each case, the URL should - # include the "http://" and domain name. - # - # If you specify this, you must specify item_author_name. - - def item_author_link(self, obj): - """ - Takes an item, as returned by items(), and returns the item's - author's URL as a normal Python string. - """ - - def item_author_link(self): - """ - Returns the author URL for every item in the feed. - """ - - item_author_link = 'http://www.example.com/' # Hard-coded author URL. - - # ITEM ENCLOSURE URL -- One of these three is required if you're - # publishing enclosures. The framework looks for them in this order. - - def item_enclosure_url(self, item): - """ - Takes an item, as returned by items(), and returns the item's - enclosure URL. - """ - - def item_enclosure_url(self): - """ - Returns the enclosure URL for every item in the feed. - """ - - item_enclosure_url = "/foo/bar.mp3" # Hard-coded enclosure link. - - # ITEM ENCLOSURE LENGTH -- One of these three is required if you're - # publishing enclosures. The framework looks for them in this order. - # In each case, the returned value should be either an integer, or a - # string representation of the integer, in bytes. - - def item_enclosure_length(self, item): - """ - Takes an item, as returned by items(), and returns the item's - enclosure length. - """ - - def item_enclosure_length(self): - """ - Returns the enclosure length for every item in the feed. - """ - - item_enclosure_length = 32000 # Hard-coded enclosure length. - - # ITEM ENCLOSURE MIME TYPE -- One of these three is required if you're - # publishing enclosures. The framework looks for them in this order. - - def item_enclosure_mime_type(self, item): - """ - Takes an item, as returned by items(), and returns the item's - enclosure MIME type. - """ - - def item_enclosure_mime_type(self): - """ - Returns the enclosure MIME type for every item in the feed. - """ - - item_enclosure_mime_type = "audio/mpeg" # Hard-coded enclosure MIME type. - - # ITEM PUBDATE -- It's optional to use one of these three. This is a - # hook that specifies how to get the pubdate for a given item. - # In each case, the method/attribute should return a Python - # datetime.datetime object. - - def item_pubdate(self, item): - """ - Takes an item, as returned by items(), and returns the item's - pubdate. - """ - - def item_pubdate(self): - """ - Returns the pubdate for every item in the feed. - """ - - item_pubdate = datetime.datetime(2005, 5, 3) # Hard-coded pubdate. - - # ITEM CATEGORIES -- It's optional to use one of these three. This is - # a hook that specifies how to get the list of categories for a given - # item. In each case, the method/attribute should return an iterable - # object that returns strings. - - def item_categories(self, item): - """ - Takes an item, as returned by items(), and returns the item's - categories. - """ - - def item_categories(self): - """ - Returns the categories for every item in the feed. - """ - - item_categories = ("python", "django") # Hard-coded categories. - - # ITEM COPYRIGHT NOTICE (only applicable to Atom feeds) -- One of the - # following three is optional. The framework looks for them in this - # order. - - def item_copyright(self, obj): - """ - Takes an item, as returned by items(), and returns the item's - copyright notice as a normal Python string. - """ - - def item_copyright(self): - """ - Returns the copyright notice for every item in the feed. - """ - - item_copyright = 'Copyright (c) 2007, Sally Smith' # Hard-coded copyright notice. - - -The low-level framework -======================= - -Behind the scenes, the high-level RSS framework uses a lower-level framework -for generating feeds' XML. This framework lives in a single module: -`django/utils/feedgenerator.py`_. - -You use this framework on your own, for lower-level feed generation. You can -also create custom feed generator subclasses for use with the ``feed_type`` -``Feed`` option. - -``SyndicationFeed`` classes ---------------------------- - -The :mod:`~django.utils.feedgenerator` module contains a base class: - -.. class:: django.utils.feedgenerator.SyndicationFeed - -and several subclasses: - -.. class:: django.utils.feedgenerator.RssUserland091Feed -.. class:: django.utils.feedgenerator.Rss201rev2Feed -.. class:: django.utils.feedgenerator.Atom1Feed - -Each of these three classes knows how to render a certain type of feed as XML. -They share this interface: - -.. method:: SyndicationFeed.__init__(**kwargs) - - Initialize the feed with the given dictionary of metadata, which applies to - the entire feed. Required keyword arguments are: - - * ``title`` - * ``link`` - * ``description`` - - There's also a bunch of other optional keywords: - - * ``language`` - * ``author_email`` - * ``author_name`` - * ``author_link`` - * ``subtitle`` - * ``categories`` - * ``feed_url`` - * ``feed_copyright`` - * ``feed_guid`` - * ``ttl`` - - Any extra keyword arguments you pass to ``__init__`` will be stored in - ``self.feed`` for use with `custom feed generators`_. - - All parameters should be Unicode objects, except ``categories``, which - should be a sequence of Unicode objects. - -.. method:: SyndicationFeed.add_item(**kwargs) - - Add an item to the feed with the given parameters. - - Required keyword arguments are: - - * ``title`` - * ``link`` - * ``description`` - - Optional keyword arguments are: - - * ``author_email`` - * ``author_name`` - * ``author_link`` - * ``pubdate`` - * ``comments`` - * ``unique_id`` - * ``enclosure`` - * ``categories`` - * ``item_copyright`` - * ``ttl`` - - Extra keyword arguments will be stored for `custom feed generators`_. - - All parameters, if given, should be Unicode objects, except: - - * ``pubdate`` should be a `Python datetime object`_. - * ``enclosure`` should be an instance of ``feedgenerator.Enclosure``. - * ``categories`` should be a sequence of Unicode objects. - -.. method:: SyndicationFeed.write(outfile, encoding) - - Outputs the feed in the given encoding to outfile, which is a file-like object. - -.. method:: SyndicationFeed.writeString(encoding) - - 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:: - - >>> from django.utils import feedgenerator - >>> from datetime import datetime - >>> f = feedgenerator.Atom1Feed( - ... title=u"My Weblog", - ... link=u"http://www.example.com/", - ... description=u"In which I write about what I ate today.", - ... language=u"en", - ... author_name=u"Myself", - ... feed_url=u"http://example.com/atom.xml") - >>> f.add_item(title=u"Hot dog today", - ... link=u"http://www.example.com/entries/1/", - ... pubdate=datetime.now(), - ... description=u"<p>Today I had a Vienna Beef hot dog. It was pink, plump and perfect.</p>") - >>> print f.writeString('UTF-8') - <?xml version="1.0" encoding="UTF-8"?> - <feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"> - ... - </feed> - -.. _django/utils/feedgenerator.py: http://code.djangoproject.com/browser/django/trunk/django/utils/feedgenerator.py -.. _Python datetime object: http://docs.python.org/library/datetime.html#datetime-objects - -Custom feed generators ----------------------- - -If you need to produce a custom feed format, you've got a couple of options. - -If the feed format is totally custom, you'll want to subclass -``SyndicationFeed`` and completely replace the ``write()`` and -``writeString()`` methods. - -However, if the feed format is a spin-off of RSS or Atom (i.e. GeoRSS_, Apple's -`iTunes podcast format`_, etc.), you've got a better choice. These types of -feeds typically add extra elements and/or attributes to the underlying format, -and there are a set of methods that ``SyndicationFeed`` calls to get these extra -attributes. Thus, you can subclass the appropriate feed generator class -(``Atom1Feed`` or ``Rss201rev2Feed``) and extend these callbacks. They are: - -.. _georss: http://georss.org/ -.. _itunes podcast format: http://www.apple.com/itunes/podcasts/specs.html - -``SyndicationFeed.root_attributes(self, )`` - Return a ``dict`` of attributes to add to the root feed element - (``feed``/``channel``). - -``SyndicationFeed.add_root_elements(self, handler)`` - Callback to add elements inside the root feed element - (``feed``/``channel``). ``handler`` is an `XMLGenerator`_ from Python's - built-in SAX library; you'll call methods on it to add to the XML - document in process. - -``SyndicationFeed.item_attributes(self, item)`` - Return a ``dict`` of attributes to add to each item (``item``/``entry``) - element. The argument, ``item``, is a dictionary of all the data passed to - ``SyndicationFeed.add_item()``. - -``SyndicationFeed.add_item_elements(self, handler, item)`` - Callback to add elements to each item (``item``/``entry``) element. - ``handler`` and ``item`` are as above. - -.. warning:: - - If you override any of these methods, be sure to call the superclass methods - since they add the required elements for each feed format. - -For example, you might start implementing an iTunes RSS feed generator like so:: - - class iTunesFeed(Rss201rev2Feed): - def root_attributes(self): - attrs = super(iTunesFeed, self).root_attributes() - attrs['xmlns:itunes'] = 'http://www.itunes.com/dtds/podcast-1.0.dtd' - return attrs - - def add_root_elements(self, handler): - super(iTunesFeed, self).add_root_elements(handler) - handler.addQuickElement('itunes:explicit', 'clean') - -Obviously there's a lot more work to be done for a complete custom feed class, -but the above example should demonstrate the basic idea. - -.. _XMLGenerator: http://docs.python.org/dev/library/xml.sax.utils.html#xml.sax.saxutils.XMLGenerator diff --git a/parts/django/docs/ref/contrib/webdesign.txt b/parts/django/docs/ref/contrib/webdesign.txt deleted file mode 100644 index d355d03..0000000 --- a/parts/django/docs/ref/contrib/webdesign.txt +++ /dev/null @@ -1,56 +0,0 @@ -======================== -django.contrib.webdesign -======================== - -.. module:: django.contrib.webdesign - :synopsis: Helpers and utilities targeted primarily at Web *designers* - rather than Web *developers*. - -The ``django.contrib.webdesign`` package, part of the -:doc:`"django.contrib" add-ons </ref/contrib/index>`, provides various Django -helpers that are particularly useful to Web *designers* (as opposed to -developers). - -At present, the package contains only a single template tag. If you have ideas -for Web-designer-friendly functionality in Django, please -:doc:`suggest them </internals/contributing>`. - -Template tags -============= - -To use these template tags, add ``'django.contrib.webdesign'`` to your -:setting:`INSTALLED_APPS` setting. Once you've done that, use -``{% load webdesign %}`` in a template to give your template access to the tags. - - -lorem -===== - -Displays random "lorem ipsum" Latin text. This is useful for providing sample -data in templates. - -Usage:: - - {% lorem [count] [method] [random] %} - -The ``{% lorem %}`` tag can be used with zero, one, two or three arguments. -The arguments are: - - =========== ============================================================= - Argument Description - =========== ============================================================= - ``count`` A number (or variable) containing the number of paragraphs or - words to generate (default is 1). - ``method`` Either ``w`` for words, ``p`` for HTML paragraphs or ``b`` - for plain-text paragraph blocks (default is ``b``). - ``random`` The word ``random``, which if given, does not use the common - paragraph ("Lorem ipsum dolor sit amet...") when generating - text. - =========== ============================================================= - -Examples: - - * ``{% lorem %}`` will output the common "lorem ipsum" paragraph. - * ``{% lorem 3 p %}`` will output the common "lorem ipsum" paragraph - and two random paragraphs each wrapped in HTML ``<p>`` tags. - * ``{% lorem 2 w random %}`` will output two random Latin words. |