Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

models.py 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import string
  2. from django.core.exceptions import ImproperlyConfigured, ValidationError
  3. from django.db import models
  4. from django.db.models.signals import pre_delete, pre_save
  5. from django.http.request import split_domain_port
  6. from django.utils.translation import gettext_lazy as _
  7. SITE_CACHE = {}
  8. def _simple_domain_name_validator(value):
  9. """
  10. Validate that the given value contains no whitespaces to prevent common
  11. typos.
  12. """
  13. if not value:
  14. return
  15. checks = ((s in value) for s in string.whitespace)
  16. if any(checks):
  17. raise ValidationError(
  18. _("The domain name cannot contain any spaces or tabs."),
  19. code='invalid',
  20. )
  21. class SiteManager(models.Manager):
  22. use_in_migrations = True
  23. def _get_site_by_id(self, site_id):
  24. if site_id not in SITE_CACHE:
  25. site = self.get(pk=site_id)
  26. SITE_CACHE[site_id] = site
  27. return SITE_CACHE[site_id]
  28. def _get_site_by_request(self, request):
  29. host = request.get_host()
  30. try:
  31. # First attempt to look up the site by host with or without port.
  32. if host not in SITE_CACHE:
  33. SITE_CACHE[host] = self.get(domain__iexact=host)
  34. return SITE_CACHE[host]
  35. except Site.DoesNotExist:
  36. # Fallback to looking up site after stripping port from the host.
  37. domain, port = split_domain_port(host)
  38. if domain not in SITE_CACHE:
  39. SITE_CACHE[domain] = self.get(domain__iexact=domain)
  40. return SITE_CACHE[domain]
  41. def get_current(self, request=None):
  42. """
  43. Return the current Site based on the SITE_ID in the project's settings.
  44. If SITE_ID isn't defined, return the site with domain matching
  45. request.get_host(). The ``Site`` object is cached the first time it's
  46. retrieved from the database.
  47. """
  48. from django.conf import settings
  49. if getattr(settings, 'SITE_ID', ''):
  50. site_id = settings.SITE_ID
  51. return self._get_site_by_id(site_id)
  52. elif request:
  53. return self._get_site_by_request(request)
  54. raise ImproperlyConfigured(
  55. "You're using the Django \"sites framework\" without having "
  56. "set the SITE_ID setting. Create a site in your database and "
  57. "set the SITE_ID setting or pass a request to "
  58. "Site.objects.get_current() to fix this error."
  59. )
  60. def clear_cache(self):
  61. """Clear the ``Site`` object cache."""
  62. global SITE_CACHE
  63. SITE_CACHE = {}
  64. def get_by_natural_key(self, domain):
  65. return self.get(domain=domain)
  66. class Site(models.Model):
  67. domain = models.CharField(
  68. _('domain name'),
  69. max_length=100,
  70. validators=[_simple_domain_name_validator],
  71. unique=True,
  72. )
  73. name = models.CharField(_('display name'), max_length=50)
  74. objects = SiteManager()
  75. class Meta:
  76. db_table = 'django_site'
  77. verbose_name = _('site')
  78. verbose_name_plural = _('sites')
  79. ordering = ('domain',)
  80. def __str__(self):
  81. return self.domain
  82. def natural_key(self):
  83. return (self.domain,)
  84. def clear_site_cache(sender, **kwargs):
  85. """
  86. Clear the cache (if primed) each time a site is saved or deleted.
  87. """
  88. instance = kwargs['instance']
  89. using = kwargs['using']
  90. try:
  91. del SITE_CACHE[instance.pk]
  92. except KeyError:
  93. pass
  94. try:
  95. del SITE_CACHE[Site.objects.using(using).get(pk=instance.pk).domain]
  96. except (KeyError, Site.DoesNotExist):
  97. pass
  98. pre_save.connect(clear_site_cache, sender=Site)
  99. pre_delete.connect(clear_site_cache, sender=Site)