BACKWARDS-INCOMPATIBLE CHANGE -- Moved flatpages and redirects to standalone apps in django.contrib that are NOT installed by default. See http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges for full migration information.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@1166 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a11a1d5e16
commit
1b035c35d9
|
@ -135,9 +135,6 @@ ALLOWED_INCLUDE_ROOTS = ()
|
|||
# is an admin.
|
||||
ADMIN_FOR = ()
|
||||
|
||||
# Whether to check the flat-pages table as a last resort for all 404 errors.
|
||||
USE_FLAT_PAGES = True
|
||||
|
||||
# 404s that may be ignored.
|
||||
IGNORABLE_404_STARTS = ('/cgi-bin/', '/_vti_bin', '/_vti_inf')
|
||||
IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', 'favicon.ico', '.php')
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
from django.contrib.flatpages.views import flatpage
|
||||
from django.conf.settings import DEBUG
|
||||
|
||||
class FlatpageFallbackMiddleware:
|
||||
def process_response(self, request, response):
|
||||
if response.status_code != 404:
|
||||
return response # No need to check for a flatpage for non-404 responses.
|
||||
try:
|
||||
return flatpage(request, request.path)
|
||||
# Return the original response if any errors happened. Because this
|
||||
# is a middleware, we can't assume the errors will be caught elsewhere.
|
||||
except:
|
||||
if DEBUG:
|
||||
raise
|
||||
return response
|
|
@ -0,0 +1 @@
|
|||
__all__ = ['flatpages']
|
|
@ -0,0 +1,33 @@
|
|||
from django.core import meta, validators
|
||||
from django.models.core import Site
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class FlatPage(meta.Model):
|
||||
url = meta.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL],
|
||||
help_text=_("Example: '/about/contact/'. Make sure to have leading and trailing slashes."))
|
||||
title = meta.CharField(_('title'), maxlength=200)
|
||||
content = meta.TextField(_('content'))
|
||||
enable_comments = meta.BooleanField(_('enable comments'))
|
||||
template_name = meta.CharField(_('template name'), maxlength=70, blank=True,
|
||||
help_text=_("Example: 'flatpages/contact_page'. If this isn't provided, the system will use 'flatpages/default'."))
|
||||
registration_required = meta.BooleanField(_('registration required'), help_text=_("If this is checked, only logged-in users will be able to view the page."))
|
||||
sites = meta.ManyToManyField(Site)
|
||||
class META:
|
||||
db_table = 'django_flatpages'
|
||||
verbose_name = _('flat page')
|
||||
verbose_name_plural = _('flat pages')
|
||||
ordering = ('url',)
|
||||
admin = meta.Admin(
|
||||
fields = (
|
||||
(None, {'fields': ('url', 'title', 'content', 'sites')}),
|
||||
('Advanced options', {'classes': 'collapse', 'fields': ('enable_comments', 'registration_required', 'template_name')}),
|
||||
),
|
||||
list_filter = ('sites',),
|
||||
search_fields = ('url', 'title'),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s -- %s" % (self.url, self.title)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.url
|
|
@ -1,5 +1,5 @@
|
|||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('django.views',
|
||||
(r'^(?P<url>.*)$', 'core.flatfiles.flat_file'),
|
||||
(r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage'),
|
||||
)
|
|
@ -1,28 +1,28 @@
|
|||
from django.core import template_loader
|
||||
from django.core.extensions import get_object_or_404, DjangoContext
|
||||
from django.models.core import flatfiles
|
||||
from django.models.flatpages import flatpages
|
||||
from django.utils.httpwrappers import HttpResponse
|
||||
from django.conf.settings import SITE_ID
|
||||
|
||||
DEFAULT_TEMPLATE = 'flatfiles/default'
|
||||
DEFAULT_TEMPLATE = 'flatpages/default'
|
||||
|
||||
def flat_file(request, url):
|
||||
def flatpage(request, url):
|
||||
"""
|
||||
Flat file view
|
||||
Flat page view.
|
||||
|
||||
Models: `core.flatfiles`
|
||||
Models: `flatpages.flatpages`
|
||||
Templates: Uses the template defined by the ``template_name`` field,
|
||||
or `flatfiles/default` if template_name is not defined.
|
||||
or `flatpages/default` if template_name is not defined.
|
||||
Context:
|
||||
flatfile
|
||||
`flatfiles.flatfiles` object
|
||||
flatpage
|
||||
`flatpages.flatpages` object
|
||||
"""
|
||||
if not url.startswith('/'):
|
||||
url = "/" + url
|
||||
f = get_object_or_404(flatfiles, url__exact=url, sites__id__exact=SITE_ID)
|
||||
f = get_object_or_404(flatpages, url__exact=url, sites__id__exact=SITE_ID)
|
||||
# If registration is required for accessing this page, and the user isn't
|
||||
# logged in, redirect to the login page.
|
||||
if request.user.is_anonymous() and f.registration_required:
|
||||
if f.registration_required and request.user.is_anonymous():
|
||||
from django.views.auth.login import redirect_to_login
|
||||
return redirect_to_login(request.path)
|
||||
if f.template_name:
|
||||
|
@ -30,6 +30,6 @@ def flat_file(request, url):
|
|||
else:
|
||||
t = template_loader.get_template(DEFAULT_TEMPLATE)
|
||||
c = DjangoContext(request, {
|
||||
'flatfile': f,
|
||||
'flatpage': f,
|
||||
})
|
||||
return HttpResponse(t.render(c))
|
|
@ -0,0 +1,27 @@
|
|||
from django.models.redirects import redirects
|
||||
from django.utils import httpwrappers
|
||||
from django.conf.settings import APPEND_SLASH, SITE_ID
|
||||
|
||||
class RedirectFallbackMiddleware:
|
||||
def process_response(self, request, response):
|
||||
if response.status_code != 404:
|
||||
return response # No need to check for a redirect for non-404 responses.
|
||||
path = request.get_full_path()
|
||||
try:
|
||||
r = redirects.get_object(site__id__exact=SITE_ID, old_path__exact=path)
|
||||
except redirects.RedirectDoesNotExist:
|
||||
r = None
|
||||
if r is None and APPEND_SLASH:
|
||||
# Try removing the trailing slash.
|
||||
try:
|
||||
r = redirects.get_object(site__id__exact=SITE_ID,
|
||||
old_path__exact=path[:path.rfind('/')]+path[path.rfind('/')+1:])
|
||||
except redirects.RedirectDoesNotExist:
|
||||
pass
|
||||
if r is not None:
|
||||
if r == '':
|
||||
return httpwrappers.HttpResponseGone()
|
||||
return httpwrappers.HttpResponseRedirect(r.new_path)
|
||||
|
||||
# No redirect was found. Return the response.
|
||||
return response
|
|
@ -0,0 +1 @@
|
|||
__all__ = ['redirects']
|
|
@ -0,0 +1,23 @@
|
|||
from django.core import meta
|
||||
from django.models.core import Site
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class Redirect(meta.Model):
|
||||
site = meta.ForeignKey(Site, radio_admin=meta.VERTICAL)
|
||||
old_path = meta.CharField(_('redirect from'), maxlength=200, db_index=True,
|
||||
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
|
||||
new_path = meta.CharField(_('redirect to'), maxlength=200, blank=True,
|
||||
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
|
||||
class META:
|
||||
verbose_name = _('redirect')
|
||||
verbose_name_plural = _('redirects')
|
||||
db_table = 'django_redirects'
|
||||
unique_together=(('site', 'old_path'),)
|
||||
ordering = ('old_path',)
|
||||
admin = meta.Admin(
|
||||
list_filter = ('site',),
|
||||
search_fields = ('old_path', 'new_path'),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s ---> %s" % (self.old_path, self.new_path)
|
|
@ -1,8 +1,6 @@
|
|||
from django.conf import settings
|
||||
from django.core import exceptions
|
||||
from django.utils import httpwrappers
|
||||
from django.core.mail import mail_managers
|
||||
from django.views.core.flatfiles import flat_file
|
||||
import md5, os
|
||||
|
||||
class CommonMiddleware:
|
||||
|
@ -17,9 +15,6 @@ class CommonMiddleware:
|
|||
- ETags: If the USE_ETAGS setting is set, ETags will be calculated from
|
||||
the entire page content and Not Modified responses will be returned
|
||||
appropriately.
|
||||
|
||||
- Flat files: For 404 responses, a flat file matching the given path
|
||||
will be looked up and used if found.
|
||||
"""
|
||||
|
||||
def process_request(self, request):
|
||||
|
@ -55,12 +50,6 @@ class CommonMiddleware:
|
|||
def process_response(self, request, response):
|
||||
"Check for a flat page (for 404s) and calculate the Etag, if needed."
|
||||
if response.status_code == 404:
|
||||
if settings.USE_FLAT_PAGES:
|
||||
try:
|
||||
return flat_file(request, request.path)
|
||||
except exceptions.Http404:
|
||||
pass
|
||||
|
||||
if settings.SEND_BROKEN_LINK_EMAILS:
|
||||
# If the referrer was from an internal link or a non-search-engine site,
|
||||
# send a note to the managers.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import base64, md5, random, sys
|
||||
import cPickle as pickle
|
||||
from django.core import meta, validators
|
||||
from django.core import meta
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class Site(meta.Model):
|
||||
|
@ -63,56 +63,6 @@ class ContentType(meta.Model):
|
|||
"""
|
||||
return self.get_model_module().get_object(**kwargs)
|
||||
|
||||
class Redirect(meta.Model):
|
||||
site = meta.ForeignKey(Site, radio_admin=meta.VERTICAL)
|
||||
old_path = meta.CharField(_('redirect from'), maxlength=200, db_index=True,
|
||||
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
|
||||
new_path = meta.CharField(_('redirect to'), maxlength=200, blank=True,
|
||||
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
|
||||
class META:
|
||||
verbose_name = _('redirect')
|
||||
verbose_name_plural = _('redirects')
|
||||
db_table = 'redirects'
|
||||
unique_together=(('site', 'old_path'),)
|
||||
ordering = ('old_path',)
|
||||
admin = meta.Admin(
|
||||
list_filter = ('site',),
|
||||
search_fields = ('old_path', 'new_path'),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s ---> %s" % (self.old_path, self.new_path)
|
||||
|
||||
class FlatFile(meta.Model):
|
||||
url = meta.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL],
|
||||
help_text=_("Example: '/about/contact/'. Make sure to have leading and trailing slashes."))
|
||||
title = meta.CharField(_('title'), maxlength=200)
|
||||
content = meta.TextField(_('content'))
|
||||
enable_comments = meta.BooleanField(_('enable comments'))
|
||||
template_name = meta.CharField(_('template name'), maxlength=70, blank=True,
|
||||
help_text=_("Example: 'flatfiles/contact_page'. If this isn't provided, the system will use 'flatfiles/default'."))
|
||||
registration_required = meta.BooleanField(_('registration required'), help_text=_("If this is checked, only logged-in users will be able to view the page."))
|
||||
sites = meta.ManyToManyField(Site)
|
||||
class META:
|
||||
db_table = 'flatfiles'
|
||||
verbose_name = _('flat page')
|
||||
verbose_name_plural = _('flat pages')
|
||||
ordering = ('url',)
|
||||
admin = meta.Admin(
|
||||
fields = (
|
||||
(None, {'fields': ('url', 'title', 'content', 'sites')}),
|
||||
('Advanced options', {'classes': 'collapse', 'fields': ('enable_comments', 'registration_required', 'template_name')}),
|
||||
),
|
||||
list_filter = ('sites',),
|
||||
search_fields = ('url', 'title'),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s -- %s" % (self.url, self.title)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.url
|
||||
|
||||
class Session(meta.Model):
|
||||
session_key = meta.CharField(_('session key'), maxlength=40, primary_key=True)
|
||||
session_data = meta.TextField(_('session data'))
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.models.core import sites, contenttypes
|
|||
from django.utils import httpwrappers
|
||||
|
||||
def shortcut(request, content_type_id, object_id):
|
||||
"""Redirect to an object's page based on a content-type ID and an object ID"""
|
||||
"Redirect to an object's page based on a content-type ID and an object ID."
|
||||
# Look up the object, making sure it's got a get_absolute_url() function.
|
||||
try:
|
||||
content_type = contenttypes.get_object(pk=content_type_id)
|
||||
|
@ -15,23 +15,23 @@ def shortcut(request, content_type_id, object_id):
|
|||
absurl = obj.get_absolute_url()
|
||||
except AttributeError:
|
||||
raise Http404, "%s objects don't have get_absolute_url() methods" % content_type.name
|
||||
|
||||
# Try to figure out the object's domain so we can do a cross-site redirect
|
||||
# if necessary
|
||||
|
||||
# Try to figure out the object's domain, so we can do a cross-site redirect
|
||||
# if necessary.
|
||||
|
||||
# If the object actually defines a domain, we're done.
|
||||
if absurl.startswith('http://'):
|
||||
return httpwrappers.HttpResponseRedirect(absurl)
|
||||
|
||||
object_domain = None
|
||||
|
||||
|
||||
# Next, look for an many-to-many relationship to sites
|
||||
if hasattr(obj, 'get_site_list'):
|
||||
site_list = obj.get_site_list()
|
||||
if site_list:
|
||||
object_domain = site_list[0].domain
|
||||
|
||||
# Next, look for a many-to-one relationship to sites
|
||||
|
||||
# Next, look for a many-to-one relationship to sites
|
||||
elif hasattr(obj, 'get_site'):
|
||||
try:
|
||||
object_domain = obj.get_site().domain
|
||||
|
@ -55,34 +55,15 @@ def page_not_found(request):
|
|||
Templates: `404`
|
||||
Context: None
|
||||
"""
|
||||
from django.models.core import redirects
|
||||
from django.conf.settings import APPEND_SLASH, SITE_ID
|
||||
path = request.get_full_path()
|
||||
try:
|
||||
r = redirects.get_object(site__id__exact=SITE_ID, old_path__exact=path)
|
||||
except redirects.RedirectDoesNotExist:
|
||||
r = None
|
||||
if r is None and APPEND_SLASH:
|
||||
# Try removing the trailing slash.
|
||||
try:
|
||||
r = redirects.get_object(site__id__exact=SITE_ID, old_path__exact=path[:path.rfind('/')]+path[path.rfind('/')+1:])
|
||||
except redirects.RedirectDoesNotExist:
|
||||
pass
|
||||
if r is not None:
|
||||
if r == '':
|
||||
return httpwrappers.HttpResponseGone()
|
||||
return httpwrappers.HttpResponseRedirect(r.new_path)
|
||||
t = loader.get_template('404')
|
||||
c = Context()
|
||||
return httpwrappers.HttpResponseNotFound(t.render(c))
|
||||
return httpwrappers.HttpResponseNotFound(t.render(Context()))
|
||||
|
||||
def server_error(request):
|
||||
"""
|
||||
500 Error handler
|
||||
500 error handler.
|
||||
|
||||
Templates: `500`
|
||||
Context: None
|
||||
"""
|
||||
t = loader.get_template('500')
|
||||
c = Context()
|
||||
return httpwrappers.HttpResponseServerError(t.render(c))
|
||||
return httpwrappers.HttpResponseServerError(t.render(Context()))
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
=================
|
||||
The flatpages app
|
||||
=================
|
||||
|
||||
Django comes with an optional "flatpages" application. It lets you store simple
|
||||
"flat" HTML content in a database and handles the management for you.
|
||||
|
||||
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.
|
||||
|
||||
Here are some examples of flatpages on Django-powered sites:
|
||||
|
||||
* http://www.chicagocrime.org/about/
|
||||
* http://www.lawrence.com/about/contact/
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To install the flatpages app, follow these two steps:
|
||||
|
||||
1. Add ``"django.contrib.flatpages"`` to your INSTALLED_APPS_ setting.
|
||||
2. Add ``"django.contrib.flatpages.middleware.FlatpageFallbackMiddleware"``
|
||||
to your MIDDLEWARE_CLASSES_ setting.
|
||||
3. Run the command ``django-admin.py install flatpages``.
|
||||
|
||||
.. _INSTALLED_APPS: http://www.djangoproject.com/documentation/settings/#installed-apps
|
||||
.. _MIDDLEWARE_CLASSES: http://www.djangoproject.com/documentation/settings/#middleware-classes
|
||||
|
||||
How it works
|
||||
============
|
||||
|
||||
``django-admin.py install flatpages`` creates two tables in your database:
|
||||
``django_flatpages`` and ``django_flatpages_sites``. ``django_flatpages`` is a
|
||||
simple lookup table that essentially maps a URL to a title and bunch of text
|
||||
content. ``django_flatpages_sites`` associates a flatpage with a site.
|
||||
|
||||
The ``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 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 ``flatpages/default``.
|
||||
* It passes that template a single context variable, ``flatpage``, which is
|
||||
the flatpage object. It uses DjangoContext_ 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.
|
||||
|
||||
Note that the order of ``MIDDLEWARE_CLASSES`` matters. Generally, you can put
|
||||
``FlatpageFallbackMiddleware`` at the end of the list, because it's a last
|
||||
resort.
|
||||
|
||||
For more on middleware, read the `middleware docs`_.
|
||||
|
||||
.. _SITE_ID: http://www.djangoproject.com/documentation/settings/#site-id
|
||||
.. _DjangoContext: http://www.djangoproject.com/documentation/templates_python/#subclassing-context-djangocontext
|
||||
.. _middleware docs: http://www.djangoproject.com/documentation/middleware/
|
||||
|
||||
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
|
||||
------------------
|
||||
|
||||
Flatpages are represented by a standard `Django model`_, which lives in
|
||||
`django/contrib/flatpages/models/flatpages.py`_. You can access flatpage
|
||||
objects via the `Django database API`_.
|
||||
|
||||
.. _Django model: http://www.djangoproject.com/documentation/model_api/
|
||||
.. _django/contrib/flatpages/models/flatpages.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/flatpages/models/flatpages.py
|
||||
.. _Django database API: http://www.djangoproject.com/documentation/db_api/
|
||||
|
||||
Flatpage templates
|
||||
==================
|
||||
|
||||
By default, flatpages are rendered via the template ``flatpages/default``, but
|
||||
you can override that for a particular flatpage.
|
||||
|
||||
Creating the ``flatpages/default`` template is your responsibility; in your
|
||||
template directory, just create a ``flatpages`` directory containing a file
|
||||
``default.html``.
|
||||
|
||||
Flatpage templates are passed a single context variable, ``flatpage``, which is
|
||||
the flatpage object.
|
||||
|
||||
Here's a sample ``flatpages/default`` template::
|
||||
|
||||
<!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>
|
|
@ -69,10 +69,7 @@ following names:
|
|||
* ``sites``
|
||||
* ``packages``
|
||||
* ``content_types``
|
||||
* ``redirects``
|
||||
* ``flatfiles``
|
||||
* ``core_sessions``
|
||||
* ``flatfiles_sites``
|
||||
* ``auth_permissions``
|
||||
* ``auth_groups``
|
||||
* ``auth_users``
|
||||
|
|
|
@ -72,10 +72,6 @@ Adds a few conveniences for perfectionists:
|
|||
MD5-hashing the page content, and it'll take care of sending
|
||||
``Not Modified`` responses, if appropriate.
|
||||
|
||||
* Handles flat pages. Every time Django encounters a 404 -- either within
|
||||
a view or as a result of no URLconfs matching -- it will check the
|
||||
database of flat pages based on the current URL.
|
||||
|
||||
django.middleware.doc.XViewMiddleware
|
||||
-------------------------------------
|
||||
|
||||
|
|
|
@ -831,7 +831,7 @@ object, which takes the following parameters. All are optional.
|
|||
"click to expand" link. Fieldsets with the ``wide`` style will be
|
||||
given extra horizontal space.
|
||||
|
||||
For example (taken from the ``core.flatfiles`` model)::
|
||||
For example (taken from the ``django.contrib.flatpages`` model)::
|
||||
|
||||
fields = (
|
||||
(None, {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
=================
|
||||
The redirects app
|
||||
=================
|
||||
|
||||
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 two steps:
|
||||
|
||||
1. Add ``"django.contrib.redirects"`` to your INSTALLED_APPS_ setting.
|
||||
2. Add ``"django.contrib.redirects.middleware.RedirectFallbackMiddleware"``
|
||||
to your MIDDLEWARE_CLASSES_ setting.
|
||||
3. Run the command ``django-admin.py install redirects``.
|
||||
|
||||
.. _INSTALLED_APPS: http://www.djangoproject.com/documentation/settings/#installed-apps
|
||||
.. _MIDDLEWARE_CLASSES: http://www.djangoproject.com/documentation/settings/#middleware-classes
|
||||
|
||||
How it works
|
||||
============
|
||||
|
||||
``django-admin.py install redirects`` creates a ``django_redirects`` 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 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 ``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 `middleware docs`_.
|
||||
|
||||
.. _SITE_ID: http://www.djangoproject.com/documentation/settings/#site-id
|
||||
.. _middleware docs: http://www.djangoproject.com/documentation/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
|
||||
------------------
|
||||
|
||||
Redirects are represented by a standard `Django model`_, which lives in
|
||||
`django/contrib/redirects/models/redirects.py`_. You can access redirect
|
||||
objects via the `Django database API`_.
|
||||
|
||||
.. _Django model: http://www.djangoproject.com/documentation/model_api/
|
||||
.. _django/contrib/redirects/models/redirects.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/redirects/models/redirects.py
|
||||
.. _Django database API: http://www.djangoproject.com/documentation/db_api/
|
|
@ -562,14 +562,6 @@ A boolean that specifies whether to output the "Etag" header. This saves
|
|||
bandwidth but slows down performance. This is only used if ``CommonMiddleware``
|
||||
is installed (see the `middleware docs`_).
|
||||
|
||||
USE_FLAT_PAGES
|
||||
--------------
|
||||
|
||||
Default: ``True``
|
||||
|
||||
Whether to check the flat-pages table as a last resort for all 404 errors. This
|
||||
is only used if ``CommonMiddleware`` is installed (see the `middleware docs`_).
|
||||
|
||||
.. _cache docs: http://www.djangoproject.com/documentation/cache/
|
||||
.. _middleware docs: http://www.djangoproject.com/documentation/middleware/
|
||||
.. _session docs: http://www.djangoproject.com/documentation/sessions/
|
||||
|
|
|
@ -56,7 +56,6 @@ module that will be used for the entire site. Here's the URLconf for the
|
|||
(r'^documentation/', include('django_website.apps.docs.urls.docs')),
|
||||
(r'^comments/', include('django.contrib.comments.urls.comments')),
|
||||
(r'^rss/', include('django.conf.urls.rss')),
|
||||
(r'', include('django.conf.urls.flatfiles')),
|
||||
)
|
||||
|
||||
Note that an included URLconf receives any captured parameters from parent
|
||||
|
|
Loading…
Reference in New Issue