Sites App¶
Multi-site Django support wrapper for managing multiple website domains.
Quick Start¶
from django.contrib.sites.models import Site
from htk.apps.sites.utils import get_current_site, get_site_name, build_absolute_url
# Get current site
site = get_current_site(request)
domain = site.domain
name = site.name
# Build absolute URL
url = build_absolute_url(request, '/path/to/resource/')
# Use in templates
site_domain = request.site.domain
Multi-Site Setup¶
Configure Sites¶
# settings.py
SITE_ID = 1
# Create multiple sites
from django.contrib.sites.models import Site
# Site 1
site1 = Site.objects.get_or_create(
id=1,
defaults={
'domain': 'example.com',
'name': 'Example'
}
)
# Site 2 (different domain)
site2 = Site.objects.get_or_create(
id=2,
defaults={
'domain': 'example.co.uk',
'name': 'Example UK'
}
)
Get Current Site¶
from django.contrib.sites.shortcuts import get_current_site
from htk.apps.sites.utils import get_current_site as htk_get_current_site
# Django built-in
site = get_current_site(request)
# HTK wrapper with fallback
site = htk_get_current_site(request)
Common Patterns¶
Build URLs¶
from django.contrib.sites.shortcuts import get_current_site
def build_absolute_url(request, path):
"""Build absolute URL with domain"""
site = get_current_site(request)
protocol = 'https' if request.is_secure() else 'http'
return f'{protocol}://{site.domain}{path}'
# Usage
reset_link = build_absolute_url(request, f'/auth/reset/{token}/')
Site-Specific Settings¶
from django.contrib.sites.shortcuts import get_current_site
class SiteConfig:
CONFIGS = {
'example.com': {
'theme': 'default',
'language': 'en',
'timezone': 'US/Eastern'
},
'example.co.uk': {
'theme': 'uk',
'language': 'en-GB',
'timezone': 'Europe/London'
}
}
@classmethod
def get_config(cls, domain):
return cls.CONFIGS.get(domain, cls.CONFIGS['example.com'])
# Usage
def my_view(request):
site = get_current_site(request)
config = SiteConfig.get_config(site.domain)
return render(request, 'view.html', {'config': config})
Site-Specific Email Templates¶
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
def send_site_email(request, user, template_name, context):
"""Send email with site-specific template"""
site = get_current_site(request)
# Try site-specific template first
try:
html = render_to_string(
f'emails/{site.domain}/{template_name}',
context
)
except TemplateDoesNotExist:
# Fall back to default
html = render_to_string(
f'emails/{template_name}',
context
)
send_mail(
subject=f'Message from {site.name}',
message=html,
from_email=f'noreply@{site.domain}',
recipient_list=[user.email]
)
Site-Specific Content¶
from django.contrib.sites.models import Site
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
sites = models.ManyToManyField(Site) # Multi-site support
created = models.DateTimeField(auto_now_add=True)
def get_site_articles(site):
"""Get articles for specific site"""
return Article.objects.filter(sites=site)
Canonical URLs¶
from django.contrib.sites.shortcuts import get_current_site
def get_canonical_url(request, path):
"""Get canonical URL for SEO"""
site = get_current_site(request)
protocol = 'https'
return f'{protocol}://{site.domain}{path}'
# Usage in template
{% load sites %}
<link rel="canonical" href="{{ canonical_url }}" />
Redirect to Site Domain¶
from django.contrib.sites.shortcuts import get_current_site
from django.shortcuts import redirect
def enforce_site_domain(request):
"""Redirect if accessing from wrong domain"""
site = get_current_site(request)
if request.get_host() != site.domain:
protocol = 'https' if request.is_secure() else 'http'
url = f'{protocol}://{site.domain}{request.path}'
return redirect(url, permanent=True)
Template Usage¶
In Templates¶
{% load sites %}
<!-- Get current site -->
<footer>
<p>© {{ request.site.name }}</p>
<a href="https://{{ request.site.domain }}/">Home</a>
</footer>
<!-- Link to site URL -->
<a href="https://{{ request.site.domain }}/about/">About Us</a>
<!-- Email footer -->
<p>Contact: support@{{ request.site.domain }}</p>
Dynamic Base URL¶
{% load sites %}
{% url 'home' as home_url %}
<a href="https://{{ request.site.domain }}{{ home_url }}">
Go Home
</a>
Configuration¶
# settings.py
SITE_ID = 1 # Default site ID
# Enable sites framework
INSTALLED_APPS = [
'django.contrib.sites',
'htk.apps.sites',
# ...
]
# Site-specific settings
SITE_DOMAINS = {
1: 'example.com',
2: 'example.co.uk',
3: 'example.de',
}
SITE_THEMES = {
'example.com': 'default',
'example.co.uk': 'uk',
'example.de': 'de',
}
Best Practices¶
- Set SITE_ID in settings - Configure default site
- Use get_current_site() - Always get site dynamically
- Build absolute URLs - Include protocol and domain
- Site-specific content - Use through table for flexibility
- Canonical URLs - Set for SEO with multiple domains
- Email templates - Override per site
- Settings inheritance - Provide defaults + overrides