Previous Page Next Page

Hour 22. Implementing Multiple Websites

What You'll Learn in This Hour

  • How to install the sites framework

  • How to implement the sites framework

  • How to limit access to content to one class

  • How to assign content to multiple sites

  • How to use the Site object to modify the behavior of a view function

  • How to use the CurrentSiteManager class to limit access to objects in a view function

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

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.

Installing the sites Framework

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)


Try It Yourself: Create Multiple Site Objects

In this section, you will create a site object for the iFriends site and for a site called iNews. You will then assign the iFriends site to the iFriends project in the settings.py file.

Follow these steps to create and install the new site objects:

1.
In the admin interface, click the Add link next to Sites.

2.
Create a new Site object with the name set to iFriends and the domain set to iFriends.test.

3.
Create another new Site object with the name set to iNews and the domain set to iNews.test.

4.
Open the iFriends.settings.py file in an editor.

5.
Make certain that the following line is listed in the INSTALLED_APPS setting:

'django.contrib.sites',

6.
Set the SITE_ID setting to the id of the iFriends Site object you created in step 2:

SITE_ID = 2

If you didn't add any other Site objects previously, the SITE_ID setting will probably be 2. However, you should verify that.

7.
Save the iFriends.settings.py file.


Assigning Content to Multiple Sites

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 Sites

In 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:

1.
Stop the development server.

2.
From the root of the iFriends project, use the following command to create a new application called News:

python manage.py startapp News

3.
Open the iFriends/News/models.py file in an editor.

4.
Add the following imports, shown in Listing 22.1, to import the User and Site models:

from django.contrib.auth.models import User
from django.contrib.sites.models import Site

5.
Add the Announcement class definition, shown in Listing 22.1, with the following field. This will enable content generated for the class to be accessible from multiple sites:

sites = models.ManyToManyField(Site)

6.
Add the __str__ and Admin definitions shown in Listing 22.1.

7.
Save the iFriends/News/models.py file.

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

from django.db import models
from django.contrib.auth.models import User
from django.contrib.sites.models import Site

class Announcement(models.Model):
    userID = models.ForeignKey(User)
    title = models.CharField('Title', max_length=200)
    text = models.TextField('Text', max_length=1024)
    date = models.DateTimeField('Published')
    sites = models.ManyToManyField(Site)

    def __str__(self):
        return '%s' % (self.title)

    class Admin:
        pass


Assigning Content to a Single Site

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 Site

In 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:

1.
Open the iFriends/News/models.py file in an editor.

2.
Add the Story class definition, shown in Listing 22.2, with the following field to enable content generated for the class to be accessible from only one site:

sites = models.ManyToManyField(Site)

3.
Add the __str__ and Admin definitions shown in Listing 22.2.

4.
Save the iFriends/News/models.py file.

5.
Create some Story objects using the admin interface. Assign some of them to the iFriends site and some to the iNews site.

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

class Story(models.Model):
    userID = models.ForeignKey(User)
    title = models.CharField('Title', max_length=200)
    text = models.TextField('Text', max_length=1024)
    date = models.DateTimeField('Published')
    site = models.ForeignKey(Site)
    on_site = CurrentSiteManager()

    def __str__(self):
        return '%s' % (self.title)

    class Admin:
        pass


Accessing the Site from Views

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()


Previous Page Next Page