The django.contrib.sites framework is a simple framework that provides a basic method of implementing multiple websites in the same Django installation. Using the sites framework, you can control which sites have access to content and also control the behavior of views.
This hour discusses implementing the sites framework and using the CurrentSiteManager class to control access to content.
Implementing the sites framework for a website is a simple process of creating a Site object and then setting the SITE_ID setting in the settings.py file to the ID of that object.
The following sections discuss the process of installing the sites framework in a website, and assigning content to multiple or single websites. Then they describe how to access the Site from views to modify behavior.
To install the sites framework, first add the following line to the INSTALLED_APPS setting in the settings.py file:
'django.contrib.sites',
The next step is to use the admin interface to create a Site object. The Site object contains only two fields—the name and the domain. The name allows you to set a name that can be used throughout your website. The domain can be used to build URLs for the website. You can create a Site object in the admin interface just like you would a User or Group object.
By the Way
Django automatically creates a site object named example.com when the project is initially created. If you do not create your own site object, Django uses this one.
After you have created the Site object, you need to assign the SITE_ID setting in the settings.py file the id of the new Site object. For example:
SITE_ID = 5
Did you Know?
The id of the Site object isn't displayed in the admin interface. However, it is easy to obtain from the shell. The following code snippet, run from the shell, displays the name and id of each Site object:
>>> from django.contrib.sites.models import Site >>> sites = Site.objects.all() >>> for s in sites: ... print '%s - %d' % (s.name, s.id)
To assign content to multiple sites, you need to add a Site object ManyToManyField relation. For example:
from django.contrib.sites.models import Site class myData(models.Model): . . . sites = models.ManyToManyField(Site)
Then, when you create objects, you can assign them to the Site object(s) that they should relate to. This allows you to define content that can appear in more than one site. If you have several sites, you can limit which sites can use the content by limiting which Site objects are included in the object's ManyToManyField.
Try It Yourself: Define a Model That Allows Access from Multiple SitesIn this section, you will create a new application called News. You will define a model in the application called Announcement that includes a ManyToManyField relation to the Site object. This will allow you to define multiple sites that the content can be viewed on. Follow these steps to define the multisite model:
Watch Out! Don't synchronize the database just yet. You will do that later. Listing 22.1. Full Contents of the iFriends/News/models.py File
|
To limit content to a single site, you can add a Site ForeignKey field to the model. For example:
from django.contrib.sites.models import Site class myData(models.Model): . . . site = models.ForeignKey (Site)
Then, when you create objects, you can assign them to the one Site object that they should be linked to. This allows you to define content that can appear in only one site.
Try It Yourself: Define a Model That Limits Access to One SiteIn this section, you will define a new model in the News application called Story. It will include a ForeignKey relation to the Site object so that you can define a single site that the content can be viewed on. Follow these steps to define the single-site model:
Watch Out! Don't synchronize the database just yet. You will do that later. Listing 22.2. The Story Class Definition in the iFriends/News/models.py File
|
So far you have learned how to define models so that they can be assigned to a single site or multiple sites. However, that doesn't stop the other sites from accessing the data. You need to do that in your view functions.
To limit content in your views, you need to match the site that is implementing the view function with the site(s) listed in the objects. Django gives you a simple way to determine which site is currently active for the view.
The Site.objects.get_current() function returns the Site object that is defined in the SITE_ID setting of the settings.py file. You can then use that Site object to modify the behavior of the view function. For example, the following code snippet gets the current site. Based on the site name, it builds the view differently:
from django.contrib.sites.models import Site def viewMovies(request): currentSite = Site.objects.get_current() if currentSite.name == 'SalesSite': #Build sales page elif currentSite.name == 'ReviewSite': #Build review page
Did you Know?
The initial call to Site.objects.get_current() results in a database query. To reduce overhead, Django caches the Site object from that initial query so that subsequent requests do not perform unneeded lookups. If you need to force the site to be queried from the database again, you can use the following line of code to clear the cached Site object:
Site.objects.clear_cache()