====== 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()''