Tabla de Contenidos

Sites framework

Based on the Site class which its important attribute is domain that specifies the domain name of the site.

Usage

  1. Add django.contrib.sites to your INSTALLED_APPS setting.
  2. Define a SITE_ID setting: SITE_ID = 1
  3. Run migrate.

django.contrib.sites registers a post_migrate signal handler which creates a default site named example.com with the domain example.com.

Basic example

from django.contrib.sites.models import Site
from django.db import models
 
class Article(models.Model):
    headline = models.CharField(max_length=200)
    # ...
    sites = models.ManyToManyField(Site)
    # or: site = models.ForeignKey(Site, on_delete=models.CASCADE)
 
# ...
 
from django.contrib.sites.shortcuts import get_current_site
 
def article_detail(request, article_id):
    try:
        a = Article.objects.get(id=article_id, sites__id=get_current_site(request).id)
    except Article.DoesNotExist:
        raise Http404("Article does not exist on this site")
    # ...

Current site

from django.contrib.sites.shortcuts import get_current_site
# ...
current_site = get_current_site(request)

If you don’t have access to the request object, you can use the get_current() method of the Site model’s manager. You should then ensure that your settings file does contain the SITE_ID setting.

from django.contrib.sites.models import Site
 
def my_function_without_request():
    current_site = Site.objects.get_current()
    if current_site.domain == 'foo.com':
        # Do something
        pass
    else:
        # Do something else.
        pass

The middleware

To add the site attribute to the request for a view just add django.contrib.sites.middleware.CurrentSiteMiddleware to MIDDLEWARE.

The full url

>>> 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'
>>> 'https://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url())
'https://example.com/mymodel/objects/3/'

Beheaving depending on the site

from django.conf import settings
 
def my_view(request):
    if settings.SITE_ID == 3:
        # Do something.
        pass
    else:
        # Do something else.
        pass

or…

from django.contrib.sites.shortcuts import get_current_site
 
def my_view(request):
    current_site = get_current_site(request)
    if current_site.domain == 'foo.com':
        # Do something
        pass
    else:
        # Do something else.
        pass

If you wanted to choose different templates refer to this link.

Querying depending on the site

from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager
from django.db import models
 
class Photo(models.Model):
    photo = models.FileField(upload_to='photos')
    photographer_name = models.CharField(max_length=100)
    pub_date = models.DateField()
    site = models.ForeignKey(Site, on_delete=models.CASCADE)
    objects = models.Manager()
    on_site = CurrentSiteManager()

Having this we can: