May 28, 2010

Django Contrib Revealed - Sites

Ok so the first element from django.contirbution I'm goin to write here about will be Sites package. What is Sites used for and what it's all about anyway ?
Let's say you have two sites connected together and sharing one database (i.e. community portal, and news site). You're using one login and authentication system there, one folder with uploaded pictures but different views for sites and different templates.
In settings file, community site has ID of 1 and news site's ID is equal to 2. How we would now build shared News model for both sites ?
from django.db import models
from django.contrib.sites.models import Site
from django.contrib.sites.managers import currentSiteManager

class News(models.Model):
    title = models.CharField(max_length=100)
    # ...
    site = models.ForeignKey(Site)
    objects = models.Manager()
    current_site = CurrentSiteManager()
As we can see from the code, we must add a field related to Site model in our class declaration (in this example it is many-to-one relationship). We can also notice two managers. The default objects is well known to us. It just serves .objects.all() . And for the second one it's a built in manager for serving objects specific to each site. So now News.objects.all() gives us all news (for example to feeds), and News.current_site.all() will return only News from current site. One thing to remember is that if our site-related field has different name than 'site' in CurrentSiteManager we need to specify this handler :
current_site = CurrentSiteManager('site_related_field')
And now for the views :
from django.conf.import settings

def simple_view(request):
    if settings.SITE_ID == 1:
        # code here
    else:
        # code here
But as you can see it's not the cleanest solution. It would be better if we had current site stored somewhere for the future use. Also, there is no need for refering to settings each time, because every Site model has a method .get_current() :
from django.contrib.sites.models import Site

def simple_view(request):
    current_site = Site.objects.get_current()
    #here we're using one of Site models field - domain.
    if current_site.domain == 'example.com':
        #code here
    else:
        # code here
Just to finish things up. Other field of Site model is name (which returns name of current site). And if you still prefere to use settings instead of get_current method, here's the code for that :
from django.conf import settings
from django.contrib.sites.models import Site

def simple_view(request):
    current_site = Site.objects.get(id=settings.SITE_ID)
    #here we're using one of Site models field - domain.
    if current_site.id == 1:
        #code here
    else:
        # code here

No comments:

Post a Comment