4👍
Marty!
I’ve found a great solution for my needs:
-
No need in
django-subdomains
, just use simple middleware taken from here:class SubdomainMiddleware: """ Make the subdomain publicly available to classes """ def process_request(self, request): domain_parts = request.get_host().split('.') if (len(domain_parts) > 2): subdomain = domain_parts[0] if (subdomain.lower() == 'www'): subdomain = None domain = '.'.join(domain_parts[1:]) else: subdomain = None domain = request.get_host() request.subdomain = subdomain request.domain = domain
-
If you don’t use ‘sitemap index‘ alter
sitemap
view indjango.contrib.sitemap.views
by adding two variablesreq_domain
andreq_subdomain
that are now in allrequest
s:
find
req_protocol = request.scheme
req_site = get_current_site(request)
add two new lines:
req_domain = request.domain
req_subdomain = request.subdomain
then find
urls.extend(site.get_urls(page=page, site=req_site,
protocol=req_protocol))
and make it look like this:
urls.extend(site.get_urls(page=page, site=req_site, r_domain=req_domain,
r_subdomain=req_subdomain, protocol=req_protocol))
- Now alter
__init__.py
insitemap
root dir:
in class Sitemap
make get_urls
function look like this def get_urls(self, page=1, r_domain=None, r_subdomain=None, site=None, protocol=None)
find th line domain = site.domain
, comment it out and add below:
domain = r_domain
subdomain = r_subdomain
now alter this code below:
if getattr(self, 'i18n', False):
urls = []
current_lang_code = translation.get_language()
for lang_code, lang_name in settings.LANGUAGES:
translation.activate(lang_code)
urls += self._urls(page, protocol, domain)
translation.activate(current_lang_code)
else:
urls = self._urls(page, protocol, domain)
return urls
so it looks like this:
if getattr(self, 'i18n', False):
urls = []
current_lang_code = translation.get_language()
for lang_code, lang_name in settings.LANGUAGES:
translation.activate(lang_code)
urls += self._urls(page, protocol, domain, subdomain)
translation.activate(current_lang_code)
else:
urls = self._urls(page, protocol, domain, subdomain)
return urls
- find
def _urls(self, page, protocol, domain)
function below and make it look like thisdef _urls(self, page, protocol, domain, subdomain)
and in this function below find:
loc = "%s://%s%s" % (protocol, domain, self.__get('location', item))
and replace it with this:
loc = "%s://%s.%s%s" % (protocol, subdomain, domain, self.__get('location', item))
- profit!
3👍
You can simply override _urls()
method in your sitemap class and include a super call with the domain as the subdomain + host form.
class BlogSitemap(Sitemap):
def _urls(self, page, protocol, domain):
return super(BlogSitemap, self)._urls(
page=page, protocol=protocol, domain='docs.djangoproject.com')
- [Django]-Python django rest framework. How to serialize foreign key UUID in some specific format?
- [Django]-Django CONN_MAX_AGE setting error
- [Django]-Implementing accent insensitive search on django using sqlite
1👍
My solution extends just two classes to create a set of reuseable components for sitemaps with subdomains.
First I created a new SubdomainSite class implementing the interface of django.contrib.sites.models.Site
from __future__ import unicode_literals
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class SubdomainSite(object):
"""
SubdomainSite shares the interface of Site and adds subdomain support.
"""
def __init__(self, subdomain, site=None):
self.subdomain = subdomain
self.extend_site(site)
def __str__(self):
return self.domain
def extend_site(self, site):
"""Always returns the root level site extended with subdomain."""
if issubclass(site.__class__, self.__class__):
return self.extend_site(site.root_site)
elif hasattr(site, 'domain'):
self.root_site = site
self.domain = self.name = '{0}.{1}'.format(self.subdomain, site)
return self
def save(self, force_insert=False, force_update=False):
raise NotImplementedError('RequestSite cannot be saved.')
def delete(self):
raise NotImplementedError('RequestSite cannot be deleted.')
This is then used with a class SubdomainSitemap
I created which extends Sitemap. This class only adds a subdomain attribute and adds two lines to get_urls
– it’s not as complicated as it looks, the original class just crams a little too much into one function.
from django.contrib.sitemaps import Sitemap
class SubdomainSitemap(Sitemap):
"""Adds subdomain support to sitemaps"""
subdomain = None
def get_urls(self, page=1, site=None, protocol=None):
"""Always uses this sitemap's subdomain if supplied."""
# Determine protocol
if self.protocol is not None:
protocol = self.protocol
if protocol is None:
protocol = 'http'
# Determine domain
if site is None and self.subdomain is None:
if django_apps.is_installed('django.contrib.sites'):
Site = django_apps.get_model('sites.Site')
try:
site = Site.objects.get_current()
except Site.DoesNotExist:
pass
if site is None:
raise ImproperlyConfigured(
"To use sitemaps, either enable the sites framework or pass "
"a Site/RequestSite object in your view."
)
else:
# Setting a subdomain site overrides supplied site
site = self.subdomain
domain = site.domain
if getattr(self, 'i18n', False):
urls = []
current_lang_code = translation.get_language()
for lang_code, lang_name in settings.LANGUAGES:
translation.activate(lang_code)
urls += self._urls(page, protocol, domain)
translation.activate(current_lang_code)
else:
urls = self._urls(page, protocol, domain)
return urls
Now tie it all together in your sitemaps classes!
from django.contrib.sites.models import Site
from sitemaps import SubdomainSite, SubdomainSitemap
from blog.models import Post
current_site = Site.objects.get_current()
class BlogSitemap(SubdomainSitemap):
changefreq = 'monthly'
subdomain = SubdomainSite('blog', current_site)
protocol = 'https'
def items(self):
return Post.objects.all()
Voila!
- [Django]-Django modelAdmin __init__ and inlines
- [Django]-Errno – 13 Permission denied: '/media/ – Django
- [Django]-How to use django-select2 widgets in django admin site?
- [Django]-Django Admin Inlines with many fields, possible to have inline add button create popup?
- [Django]-Can I use the Node.js packages along with Django?
1👍
For a more general version of All Іѕ Vаиітy answer you can use this for any subdomain you might need:
class FixedSitemap(Sitemap):
priority = 0.5
changefreq = 'monthly'
protocol = 'https'
def items(self):
# Add all your items here
return ['docs.yourdomain.io']
def location(self, obj):
return obj
def _urls(self, page, protocol, domain):
return super(FixedSitemap, self)._urls(page, protocol, '')
- [Django]-How to run django app binded with gunicorn?
- [Django]-Saving inlineformset in Django class-based views (CBV)
- [Django]-What's the easiest way to Import a CSV file into a Django Model?