summaryrefslogtreecommitdiff
path: root/parts/django/docs/ref/contrib/sites.txt
diff options
context:
space:
mode:
Diffstat (limited to 'parts/django/docs/ref/contrib/sites.txt')
-rw-r--r--parts/django/docs/ref/contrib/sites.txt415
1 files changed, 0 insertions, 415 deletions
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`.