how to use multiple domains and mask a django project - python

I have a Django website that's configured on a particular domain example.com. Now I'm planning to use the same website for different countries where I have to use their language. For example China, I'm planning to create a sub domain chinese.example.com which will point to exactly the same example.com project but the language will be switched to chinese. Also I would like to mask this chinese.example.com sub domain with another domain chinaexample.com. Please advise how to accomplish this using Apache & Django.

First step - make sure that all of your domains are added into 'ALLOWED_HOSTS' in django config.
Next - if you will have some content that will be available only for particular domain, it will be handy to use sites framework built into django. But if you want to have one language on multiple domains and want some content to be available for language, not for domain, better solution might be to create own method for assigning content to domain (or language).
Third step - write middleware that will check your domain and activate language assigned to it. Example middleware can look like this:
class DomainLanguageMiddleware:
def process_request(self, request):
try:
host = request.META['HTTP_HOST']
host_port = host.split(':')
if len(host_port) == 2:
host = host_port[0]
if host in settings.LANG_MAP:
request.LANG = settings.LANG_MAP[host]
translation.activate(request.LANG)
request.LANGUAGE_CODE = request.LANG
except KeyError:
pass
This code is using LANG_MAP setting, that should be an dictionary containing domain as key and language assigned to that domain as value.
Using that solution, all domains or subdomains can point to one django instance, with one settings.py file.

Related

Using Django tenants on the same domain, rather than subdomains or multiple domains

If I am using django-tenant-schemas (or django-tenants fork), the way they appear to be set up is that you would access the tenants on a separate subdomain or separate domain.
This means accessing tenant1 using tenant1.mysite.com or tenant1.com.
However, I would like to access tenants using mysite.com/tenant1/, mysite.com/tenant2/.
This is because I am using DRF, and so I just want their information stored separately. And I want to access them via the API in the same way. So, for instance I can make calls to mysite.com/tenant1/api/token/.
How would I set this up?
You can use a custom middleware then substitute the default middleware with it. Advanced usage section of Django Tenant Schema documentation (which, i guess, is also the same in Django Tenants) described how to do that. Below is an example of how to use custom HTTP Headers.
class XHeaderTenantMiddleware(BaseTenantMiddleware):
"""
Determines tenant by the value of the ``X-DTS-SCHEMA`` HTTP header.
"""
def get_tenant(self, model, hostname, request):
schema_name = request.META.get('HTTP_X_DTS_SCHEMA', get_public_schema_name())
return model.objects.get(schema_name=schema_name)
In your case, instead of using HTTP Header you can get your tenants by extracting them from the URL path (maybe using string.split("delimiter")) then you set that as the value of the schema_name in the code above.

Django: setting a different SESSION_COOKIE_DOMAIN depending on the domain

I use the same Django project for various domains. Some are subdomains, some are entirely different domains, so I have these domains operating the same Django site:
a.example1.com
b.example1.com
c.example1.com
example1.com
example2.com
I do not use the sites framework for reasons unrelated to this query, and I have a single settings.py for all sites, which I'd like to maintain.
When someone logs onto a subdomain, I'd like them to be logged onto any of the other subdomains as well. In fact, if it were possible I'd like them to be logged onto the other sites as well but I doubt this is possible. In order to achieve logging into all subdomains at the same time, I set the following variable in settings.py:
SESSION_COOKIE_DOMAIN=".example1.com"
This works as advertised and the logins are now working across different sites. However, I am not able to log onto any of the other domains anymore (I assume the cookie is set for the wrong domain and subsequently not properly recognized). What I assume I should do is somehow set SESSION_COOKIE_DOMAIN to either .example1.com when on the main site, or .example2.com when I'm on a different site. But how to achieve this?
Here is a similar question and this answer seems to do what I am looking for through a lightweight solution. However, this is written for older Django versions. I tried rewriting this for Django 3 as follows:
class CrossDomainSessionMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
try:
if request.COOKIES:
host = request.get_host()
# check if it's a different domain
if host not in settings.SESSION_COOKIE_DOMAIN:
domain = ".{domain}".format(domain=host)
for cookie in request.COOKIES:
if "domain" in request.COOKIES[cookie]:
request.cookies[cookie]['domain'] = domain
except:
pass
return self.get_response(request)
But this doesn't seem to work. This condition:
if "domain" in request.COOKIES[cookie]:
Is simply never met. Not sure what I should change.

multi-tenancy solution with django

I want to create a multi-tenant application where each tenant will have its own domain and database.
Domains will be like this: store1.saas.com, store2.saas.com .. and their respective databases will be store1 and store 2..
I have decided to name it as such so that depending upon on the url, i can set the database with some middleware.
I have tried https://github.com/bernardopires/django-tenant-schemas this but it wont work as it specifically asks to create a model inheriting from TenantMixin, which then is defined in settings like this.TENANT_MODEL = 'catalogue.Product'. I have multiple TenantModels and this scheme wont allow multiple models (it takes string and then uses split by "." and does their stuff based on it).
Trouble with me is
how to create sub-domains
how to test them in local, like store1.127.0.0.1:8000 wont work?
You could try emulating the future real world as close as possible by editing your hosts file /etc/hosts and putting in there:
127.0.0.1 store1.saas.com
127.0.0.1 store2.saas.com
... etc
Then you can navigate to your localhost by store1.saas.com and so on.

Can namespaces enable multiple domains?

My gae app serves multiple domains by if..else.. conditions rather than namespaces.
I see someone else solved it with namespaces
"I have a single app with multiple namespaces defined.
I'd like to set up multiple domains
a.com b.com c.com
and have the app detect the domain and write the domain's data into
its respective namespace."
I don't know how to do it with namespaces and I want a better way to add a domain to the app for settings like content and languages. For example sending an email via a form then I use just a condition instead of namespace.
class FileUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
adminemail = 'admin#domain1.com' if gethost() is 'domain1' else 'admin#domain2.com'
message = mail.EmailMessage(sender=admin_email, subject=self.request.POST.get('subject'))
message.body = ...
message.to='info#domain...
message.send()
self.redirect('/customer_service.htm')
I use same workaround for queries, localization and in some cases even which template to render to while I should be able to make all domains able to be based on same templates and differ only by content so that my app doesn't hard-code the domains and other settings that should be easy to add and change.
Are namespaces a great idea in this case? The way a managed the problem with different domains so far is a variable for the entity which domains it came from
if util.get_host().find('my-dot-com') > 0:
url = 'www.my-dot-com.com'
I have a function that defines what I mean but it may confuse www.domain.com with domain.com or have problems with subdomains
def get_host():
return os.environ.get("HTTP_HOST", os.environ["SERVER_NAME"])
I'd be glad to know any idea if you have, or if I'm mistaken and shouldn't use namespaces in this case.
Thanks
Yes, namespaces are ideally suited to what you're doing. Simply store configuration data like admin emails in a per-domain configuration record, and store all the records for a given domain in a namespace named after that domain.

How do I redirect different domain names requests to the same ip in django

I have one ip for two domain name, e.g. "www.example.com" and "example.info", and I want each of them to be handled as a different domain (e.g. www.example.com/photos and example.info/photos will be ahndled each by its corresponding function). Is there an elegant way to do this in django?
You would do this by setting up different WSGI for each domain using a setting SITE_ID corresponding to the site id from the django.contrib.site app.

Categories