mirror of
				https://github.com/django/django.git
				synced 2025-10-28 16:16:12 +00:00 
			
		
		
		
	Thanks Tim Graham for polishing the patch, updating the tests, and writing documentation. Thanks Carl Meyer for shepherding the DEP.
		
			
				
	
	
		
			364 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			364 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| =================
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Then either:
 | |
| 
 | |
| 3. Add an entry in your URLconf. For example::
 | |
| 
 | |
|     urlpatterns = [
 | |
|         url(r'^pages/', include('django.contrib.flatpages.urls')),
 | |
|     ]
 | |
| 
 | |
| or:
 | |
| 
 | |
| 3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'``
 | |
|    to your :setting:`MIDDLEWARE` setting.
 | |
| 
 | |
| 4. Run the command :djadmin:`manage.py migrate <migrate>`.
 | |
| 
 | |
| .. currentmodule:: django.contrib.flatpages.middleware
 | |
| 
 | |
| How it works
 | |
| ============
 | |
| 
 | |
| ``manage.py migrate`` creates two tables in your database: ``django_flatpage``
 | |
| and ``django_flatpage_sites``. ``django_flatpage`` is a simple lookup table
 | |
| that simply maps a URL to a title and bunch of text content.
 | |
| ``django_flatpage_sites`` associates a flatpage with a site.
 | |
| 
 | |
| Using the URLconf
 | |
| -----------------
 | |
| 
 | |
| There are several ways to include the flat pages in your URLconf. You can
 | |
| dedicate a particular path to flat pages::
 | |
| 
 | |
|     urlpatterns = [
 | |
|         url(r'^pages/', include('django.contrib.flatpages.urls')),
 | |
|     ]
 | |
| 
 | |
| You can also set it up as a "catchall" pattern. In this case, it is important
 | |
| to place the pattern at the end of the other urlpatterns::
 | |
| 
 | |
|     from django.contrib.flatpages import views
 | |
| 
 | |
|     # Your other patterns here
 | |
|     urlpatterns += [
 | |
|         url(r'^(?P<url>.*/)$', views.flatpage),
 | |
|     ]
 | |
| 
 | |
| .. warning::
 | |
| 
 | |
|     If you set :setting:`APPEND_SLASH` to ``False``, you must remove the slash
 | |
|     in the catchall pattern or flatpages without a trailing slash will not be
 | |
|     matched.
 | |
| 
 | |
| Another common setup is to use flat pages for a limited set of known pages and
 | |
| to hard code the urls, so you can reference them with the :ttag:`url` template
 | |
| tag::
 | |
| 
 | |
|     from django.contrib.flatpages import views
 | |
| 
 | |
|     urlpatterns += [
 | |
|         url(r'^about-us/$', views.flatpage, {'url': '/about-us/'}, name='about'),
 | |
|         url(r'^license/$', views.flatpage, {'url': '/license/'}, name='license'),
 | |
|     ]
 | |
| 
 | |
| Using the middleware
 | |
| --------------------
 | |
| 
 | |
| The :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`
 | |
| can do all of the work.
 | |
| 
 | |
| .. class:: FlatpageFallbackMiddleware
 | |
| 
 | |
|     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, ``flatpage``,
 | |
|       which is the flatpage object. It uses
 | |
|       :class:`~django.template.RequestContext` in rendering the
 | |
|       template.
 | |
| 
 | |
|     The middleware will only add a trailing slash and redirect (by looking
 | |
|     at the :setting:`APPEND_SLASH` setting) if the resulting URL refers to
 | |
|     a valid flatpage. Redirects are permanent (301 status code).
 | |
| 
 | |
|     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` matters. Generally, you can put
 | |
| :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` at the
 | |
| end of the list. This means it will run first when processing the response, and
 | |
| ensures that any other response-processing middlewares see the real flatpage
 | |
| response rather than the 404.
 | |
| 
 | |
| 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, 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.
 | |
| 
 | |
| .. currentmodule:: django.contrib.flatpages.models
 | |
| 
 | |
| How to add, change and delete flatpages
 | |
| =======================================
 | |
| 
 | |
| .. _flatpages-admin:
 | |
| 
 | |
| 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.
 | |
| 
 | |
| The ``FlatPage`` model has an ``enable_comments`` field that isn't used by
 | |
| ``contrib.flatpages``, but that could be useful for your project or third-party
 | |
| apps. It doesn't appear in the admin interface, but you can add it by
 | |
| registering a custom ``ModelAdmin`` for ``FlatPage``::
 | |
| 
 | |
|     from django.contrib import admin
 | |
|     from django.contrib.flatpages.admin import FlatPageAdmin
 | |
|     from django.contrib.flatpages.models import FlatPage
 | |
|     from django.utils.translation import ugettext_lazy as _
 | |
| 
 | |
|     # Define a new FlatPageAdmin
 | |
|     class FlatPageAdmin(FlatPageAdmin):
 | |
|         fieldsets = (
 | |
|             (None, {'fields': ('url', 'title', 'content', 'sites')}),
 | |
|             (_('Advanced options'), {
 | |
|                 'classes': ('collapse', ),
 | |
|                 'fields': (
 | |
|                     'enable_comments',
 | |
|                     'registration_required',
 | |
|                     'template_name',
 | |
|                 ),
 | |
|             }),
 | |
|         )
 | |
| 
 | |
|     # Re-register FlatPageAdmin
 | |
|     admin.site.unregister(FlatPage)
 | |
|     admin.site.register(FlatPage, FlatPageAdmin)
 | |
| 
 | |
| .. versionchanged:: 1.9
 | |
| 
 | |
|     The ``enable_comments`` field was removed from ``FlatPageAdmin``.
 | |
| 
 | |
| Via the Python API
 | |
| ------------------
 | |
| 
 | |
| .. class:: 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: https://github.com/django/django/blob/master/django/contrib/flatpages/models.py
 | |
| 
 | |
| .. currentmodule:: django.contrib.flatpages
 | |
| 
 | |
| .. admonition:: Check for duplicate flatpage URLs.
 | |
| 
 | |
|     If you add or modify flatpages via your own code, you will likely want to
 | |
|     check for duplicate flatpage URLs within the same site. The flatpage form
 | |
|     used in the admin performs this validation check, and can be imported from
 | |
|     ``django.contrib.flatpages.forms.FlatpageForm`` and used in your own
 | |
|     views.
 | |
| 
 | |
| 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, ``flatpage``,
 | |
| which is the flatpage object.
 | |
| 
 | |
| Here's a sample :file:`flatpages/default.html` template:
 | |
| 
 | |
| .. code-block:: html+django
 | |
| 
 | |
|     <!DOCTYPE html>
 | |
|     <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.
 | |
| 
 | |
| Getting a list of :class:`~django.contrib.flatpages.models.FlatPage` objects in your templates
 | |
| ==============================================================================================
 | |
| 
 | |
| The flatpages app provides a template tag that allows you to iterate
 | |
| over all of the available flatpages on the :ref:`current site
 | |
| <hooking-into-current-site-from-views>`.
 | |
| 
 | |
| Like all custom template tags, you'll need to :ref:`load its custom
 | |
| tag library <loading-custom-template-libraries>` before you can use
 | |
| it. After loading the library, you can retrieve all current flatpages
 | |
| via the :ttag:`get_flatpages` tag:
 | |
| 
 | |
| .. code-block:: html+django
 | |
| 
 | |
|     {% load flatpages %}
 | |
|     {% get_flatpages as flatpages %}
 | |
|     <ul>
 | |
|         {% for page in flatpages %}
 | |
|             <li><a href="{{ page.url }}">{{ page.title }}</a></li>
 | |
|         {% endfor %}
 | |
|     </ul>
 | |
| 
 | |
| .. templatetag:: get_flatpages
 | |
| 
 | |
| Displaying ``registration_required`` flatpages
 | |
| ----------------------------------------------
 | |
| 
 | |
| By default, the :ttag:`get_flatpages` templatetag will only show
 | |
| flatpages that are marked ``registration_required = False``. If you
 | |
| want to display registration-protected flatpages, you need to specify
 | |
| an authenticated user using a ``for`` clause.
 | |
| 
 | |
| For example:
 | |
| 
 | |
| .. code-block:: html+django
 | |
| 
 | |
|     {% get_flatpages for someuser as about_pages %}
 | |
| 
 | |
| If you provide an anonymous user, :ttag:`get_flatpages` will behave
 | |
| the same as if you hadn't provided a user -- i.e., it will only show you
 | |
| public flatpages.
 | |
| 
 | |
| Limiting flatpages by base URL
 | |
| ------------------------------
 | |
| 
 | |
| An optional argument, ``starts_with``, can be applied to limit the
 | |
| returned pages to those beginning with a particular base URL. This
 | |
| argument may be passed as a string, or as a variable to be resolved
 | |
| from the context.
 | |
| 
 | |
| For example:
 | |
| 
 | |
| .. code-block:: html+django
 | |
| 
 | |
|     {% get_flatpages '/about/' as about_pages %}
 | |
|     {% get_flatpages about_prefix as about_pages %}
 | |
|     {% get_flatpages '/about/' for someuser as about_pages %}
 | |
| 
 | |
| Integrating with :mod:`django.contrib.sitemaps`
 | |
| ===============================================
 | |
| 
 | |
| .. currentmodule:: django.contrib.flatpages.sitemaps
 | |
| 
 | |
| .. class:: FlatPageSitemap
 | |
| 
 | |
|     The :class:`sitemaps.FlatPageSitemap
 | |
|     <django.contrib.flatpages.sitemaps.FlatPageSitemap>` class looks at all
 | |
|     publicly visible :mod:`~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:`~django.contrib.sitemaps.Sitemap.location`
 | |
|     attribute -- not :attr:`~django.contrib.sitemaps.Sitemap.lastmod`,
 | |
|     :attr:`~django.contrib.sitemaps.Sitemap.changefreq` or
 | |
|     :attr:`~django.contrib.sitemaps.Sitemap.priority`.
 | |
| 
 | |
| Example
 | |
| -------
 | |
| 
 | |
| Here's an example of a URLconf using :class:`FlatPageSitemap`::
 | |
| 
 | |
|     from django.conf.urls import url
 | |
|     from django.contrib.flatpages.sitemaps import FlatPageSitemap
 | |
|     from django.contrib.sitemaps.views import sitemap
 | |
| 
 | |
|     urlpatterns = [
 | |
|         # ...
 | |
| 
 | |
|         # the sitemap
 | |
|         url(r'^sitemap\.xml$', sitemap,
 | |
|             {'sitemaps': {'flatpages': FlatPageSitemap}},
 | |
|             name='django.contrib.sitemaps.views.sitemap'),
 | |
|     ]
 |