Previous Page Next Page

Using the CurrentSiteManager Class

The preceding section discussed how to determine the current Site object inside a view function. Using the Site object, you can easily alter the view's behavior. You can also alter what data is displayed in the view if the model implements a ManyToManyField or ForeignKey field linked to the Site class.

For example, the Story model you created earlier includes the site field. You could use the following code in a view function to limit the Story objects to the current site:

from django.contrib.sites.models import Site
from iFriends.News.models import Story
def viewStories(request):
    currentSite = Site.objects.get_current()
    stories = Story.objects.filter(site=currentSite)

Django also provides the django.contrib.sites.managers.CurrentSiteManager class to provide a shortcut to limit content to the current class. The CurrentSiteManager class is a model manager that automatically filters queries to include only objects that are associated with the current Site.

You implement the CurrentSiteManager class by adding it to the on_site field of the model using the following syntax:

from django.contrib.sites.managers import CurrentSiteManager
class Story(models.Model):
    . . .
    site = models.ForiegnKey(Site)
    on_site = CurrentSiteManager()

If you still want to be able to perform queries that are not filtered on the site first, add your own objects model manager:

from django.contrib.sites.managers import CurrentSiteManager
class Story(models.Model):
    . . .
    site = models.ForiegnKey(Site)
    objects = models.Manager()
    on_site = CurrentSiteManager()

By the Way

The CurrentSiteManager class looks for a ManyToManyField or ForeignKey field called site. If you name the field that relates to the Site object something different, pass the name of the field into the CurrentSiteManager() function:

pubSite = models.ForiegnKey(Site)
on_site = CurrentSiteManager('pubSite')


Try It Yourself: Modify a View's Behavior and Content Based on the Site

In this section, you will add a CurrentSiteManager to the Story and Announcement models you created earlier in this hour. You will also modify the home_view() view function to render two different templates with different data depending on what the current site is.

Follow these steps to make the changes:

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

2.
Add the following lines, shown in Listing 22.3, to the Announcement class to implement the unfiltered manager object and the CurrentSiteManager on_site:

objects = models.Manager()
on_site = CurrentSiteManager('sites')

3.
Add the following lines, shown in Listing 22.3, to the Story class to implement the unfiltered manager object and the CurrentSiteManager on_site:

objects = models.Manager()
on_site = CurrentSiteManager()

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

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

6.
Add the following import statements, as shown in Listing 22.4, to import the Site, Story, and Announcement classes:

from django.contrib.sites.models import Site
from iFriends.News.models import Story, Announcement

7.
Modify the following render statement, as shown in Listing 22.4, to use the hpTemplate and rDict variables for the template name and context:

return render_to_response(hpTemplate, rDict,
                          context_instance = RequestContext(request))

8.
Add the following lines of code, as shown in Listing 22.4, to use the on_site field of the Story and Announcement objects. This builds lists of objects based on the current site:

    rDict['announceList'] = Announcement.on_site.all()
 . . .
        rDict['storyList'] = Story.on_site.all()

9.
Add the following lines of code, as shown in Listing 22.4, to use Site.objects.get_current() to get the current site object and use it to determine which template to render:

currentSite = Site.objects.get_current()
if (currentSite.domain == 'iFriends.test'):
        hpTemplate = 'home/homepage.html'
. . .
    elif (currentSite.domain == 'iNews.test'):
        hpTemplate = 'home/newshomepage.html'
. . .

10.
Add the rest of the code shown in Listing 22.4.

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

12.
Open the iFriends/templates/Home/homepage.html file in an editor.

13.
Find the table cell entry that displays the Largest Blog, and replace it with the contents of Listing 22.5, which display a list of Announcement objects for the current site.

14.
Save the iFriends/templates/Home/homepage.html file.

15.
Create and open a file called iFriends/templates/Home/newshomepage.html in an editor.

16.
Add the contents of Listing 22.6 to the file that renders a home page for the People, Announcement, and Story objects.

17.
Save the iFriends/templates/Home/newshomepage.html file.

18.
Synchronize the database by issuing the syncdb command at the root of the iFriends project.

19.
Start the development server.

20.
Create some Announcement and Story objects using the admin interface.

21.
Assign some of objects you just created to the iFriends site and some to the iNews site. Also assign some of the Announcement objects to both sites.

22.
Access the following URL in a browser to display the home_view() view. The SITE_ID should still be set to the iFriends site, so the view should display the rendered homepage.html, as shown in Figure 22.1:

http://127.0.0.1:8000/

Figure 22.1. The home_view() web page that is rendered for the iFriends site.


23.
Open the iFriends/settings.py file in an editor.

24.
Modify the SITE_ID setting to the id attribute of the iNews Site object. For example:

SITE_ID = 3

25.
Save the iFriends/settings.py file.

26.
Access the following URL again in a browser to display the home_view() view:

http://127.0.0.1:8000/

This time the view should display the rendered newshomepage.html, as shown in Figure 22.2. Only the Story and Announcement objects that were assigned to the iNews site should be displayed.

Figure 22.2. The home_view() web page that is rendered for the iNews site.


Listing 22.3. The Announcement and Story Class Definitions in the iFriends/News/models.py File

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)
    objects = models.Manager()
    on_site = CurrentSiteManager('sites')
. . .
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)
    objects = models.Manager()
    on_site = CurrentSiteManager()

Listing 22.4. The Additional Imports and the home_view() View Function in the iFriends/News/models.py File

from django.contrib.sites.models import Site
from iFriends.News.models import Story, Announcement
. . .
def home_view(request):
    rDict = {}
    rDict['pList'] = Person.objects.all()
    rDict['announceList'] = Announcement.on_site.all()

    currentSite = Site.objects.get_current()
    if (currentSite.domain == 'iFriends.test'):
        hpTemplate = 'home/homepage.html'
        rDict['quotes'] = Quote.objects.all()
    elif (currentSite.domain == 'iNews.test'):
        hpTemplate = 'home/newshomepage.html'
        rDict['storyList'] = Story.on_site.all()

    return render_to_response(hpTemplate, rDict,
                              context_instance = RequestContext(request))

Listing 22.5. The Table Cell Code for Announcements That Replaces the Largest Blog Table Cell in the iFriends/templates/Home/homepage.html File

. . .
<td width="30%">
<h2>Announcements</h2>
{% for a in announceList %}
    <li>
    <a href="{% url iFriends.News.views.announce_detail a.id %}">
        {{ a.title }}</a>
    </li>
{% endfor %}
</td>
. . .

Listing 22.6. Full Contents of the iFriends/templates/Home/newshomepage.html File

{% extends "iFriends_base.html" %}

{% block title %}News Home Page{% endblock %}
{% block content %}
{% load custom_tags %}
<table width=100%>
<tr bgcolor="aabbcc"><td colspan="3">
<font size="5" color="white">News Home Page</font>
</td></tr>
<tr valign="top">
<td width="30%">
<h2>People</h2>
{% for p in pList %}
    <li>
    <a href="{% url iFriends.People.views.details p.id %}">
        {{ p.name }}</a>
    </li>
{% endfor %}
</td>
<td width="30%">
<h2>Announcements</h2>
{% for a in announceList %}
    <li>
    <a href="{% url iFriends.News.views.announce_detail a.id %}">
        {{ a.title }}</a>
    </li>
{% endfor %}
</td>
<td width="40%">
<h2>News Stories</h2>
{% for s in storyList %}
    <li>
    <a href="{% url iFriends.News.views.story_detail s.id %}">
        {{ s.title }}</a>
    </li>
{% endfor %}
</td>
</tr>
{% endblock %}


					  


Previous Page Next Page