====== Sites framework ======
* https://docs.djangoproject.com/en/3.0/ref/contrib/sites
Based on the ''Site'' class which its important attribute is ''domain'' that specifies the domain name of the site.
===== Usage =====
- Add ''django.contrib.sites'' to your ''INSTALLED_APPS'' setting.
- Define a SITE_ID setting: ''SITE_ID = 1''
- 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 [[https://docs.djangoproject.com/en/3.0/ref/contrib/sites/#getting-the-current-domain-for-display|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:
* Query all Photo objects in the database with ''Photo.objects.all()''.
* Query only the Photo objects associated with the current site (according to the ''SITE_ID''): ''Photo.on_site.all()''