How to enable per-site templates within Mezzanine multi-tenancy - django

We're expanding our business into Europe and I'm using Mezzanine's multi-tenancy feature to host both the US and EU versions of the site on the same Django installation. We have a /locations page on each site that I would like to serve with different templates, based on the SITE_ID.
I've followed Mezzanine's sparse documentation here and added the following to settings.py
HOST_THEMES = [
('domain.com', 'domain_app'),
('domain.eu', 'domain_eu')
]
I've added domain_eu to INSTALLED_APPS after the base theme and used python manage.py startapp domain_eu to generate the directory and manually created the domain_eu/templates/pages/locations.html file.
I then copied the locations page and assigned it to the EU site.
The page still renders with the locations template located in the base theme domain_app/templates/pages/locations.html
I've confirmed that the correct SITE_ID is set in the request.
How do I get the page to render with the template in its corresponding theme/app directory based on the current SITE_ID?

After digging into Mezzanine's code I figured out why my eu theme template was not rendering. The crucial bit of code can be found in mezzanine/utils/sites.py
def host_theme_path(request):
"""
Returns the directory of the theme associated with the given host.
"""
for (host, theme) in settings.HOST_THEMES:
if host.lower() == request.get_host().split(":")[0].lower():
When I logged the result of request.get_host() I quickly realized the problem because it was localhost which obviously would not match any of the HOST_THEMES domains.
I had assumed that Mezzanine would use the session variable site_id as per their documentation but apparently not down this particular template rendering code path.
The solution therefore was simply to edit my /etc/hosts file with the following:
127.0.0.1 domain.eu
Now when I visit domain.eu/locations it renders the template from the correct theme directory (in a local dev environment)

Related

Multiple Domains django app on heroku

Django have nice sites framework, so i thought can it posissible to store on heroku app with multi-settings structure and join it with differents domains on one heroku instance?
According to the docs, you can use Django sites framework with Heroku if you set SITE_ID = None. In that case Django will automatically detect current site based on request.get_host() method. So you only have to add specific hosts in admin panel.
The SITE_ID setting specifies the database ID of the Site object associated with that particular settings file. If the setting is omitted, the get_current_site() function will try to get the current site by comparing the domain with the host name from the request.get_host() method.
https://docs.djangoproject.com/en/1.8/ref/contrib/sites/

Reversing urls in Django / Celery

I have been asked to send an email on friday with a list of projects matching a set of conditions. The database front end is written in Django and its an in house application. I would like to link to the admin page of the project in the email.
On my development machine I am trying
reverse("admin:index")
and I notice that it is only returning
admin
from the Celery task, whereas in standard Django views this would return
127.0.0.1:8000/admin/
Is there a way around this? I would prefer not to hard code the start of the urls.
I have set up Celery as described in the "first steps with Django" tutorial, and have a
myproject/myproject/celery.py
file defining the app (alongside settings.py and urls.py) and
project/myapp/tasks.py
file with the actual tasks.
reverse() always returns a domain-relative url, i.e. /admin/. One option to increase portability is to use the sites framework.
As you don't have a request object in your Celery task, you have to explicitly set the SITE_ID in your settings and set the site's name and domain in your database. Then you can do:
from django.contrib.sites.models import Site
url = "%s%s" % (Site.objects.get_current().domain, reverse('admin:index'))
Usually URLs in django are relative - i.e. the "127.0.0.1:8000" part you see when you hover the link comes from the fact that you are browsing the site from that location. Try looking at the href value of the URLs generated.
A simple solution to your problem is to concatenate the reverse output with the domain, i.e.
'http://example.com/'+reverse('admin:index')

hostgator not recognizing urls.py of Django project

I am working within the File Manager of Hostgator and have already set up a Django project which displays "It worked! Congratulations on your first Django-powered page." Following this, I ftp'ed my local Django project (which works fine on the local server) into File Manager and stored it into a temp folder, copying over the changes to the urls.py, views.py, and settings.py files of the new Django project along the settings path.
However, nothing appears to be changing on the website - it's still on the "Congratulations" page. I've tried moving various templates into different places to see if it responds, but that doesn't appear to be doing the trick. Thoughts?
You need to read documentation about how to manage your project on the hostgator servers

Django admin template overrides not working in production environment

Like this question, my admin overrides aren't working in my production environment but they are in my development environment (same django version). I've tried reordering the INSTALLED_APPS tuple in settings.py with no change (was the answer to the question linked above). Here's how I have my project constructed:
/WebDJ/ # project dir
+devices # unrelated app, but it uses templates (see below)
+sales
__init__.py
admin.py
models.py # has Customer and Transaction model classes
+templates
+admin
+sales
+Customer
change_form.html
+Transaction
change_form.html
+devices # lots of templates under here that work fine
404.html
500.html
also:
TEMPLATE_DIRS = ('/WebDJ/templates',)
is set in settings.py. The templates in the devices app are fine. What's not loading are the overrides in the admin directory - so the change form for Customer and Transaction has some extra stuff added to them (overriding the "after_field_sets" block).
Again, it works in my development environment (using PyCharm) but not in my production environment. Any ideas? I'm really stumped on this one.
Answer: on my production machine, apparently it didn't like "Customer" and "Transaction" despite that being the exact name of the models - it needed "customer" and "transaction".

Hosting Django Project at /test #login_required redirects to /accounts instead of /test/accounts

I'm moving a project to new hosting and would like to set it up such that it sits at mysite.com/test/ (this is under mod_wsgi on an Apache server). This seems to do alright for the application itself, but when I use #login_required to enforce authentication Django redirects to mysite.com/accounts/login instead of mysite.com/test/accounts/login as I would like. I also have a mysite.com/prod that I want to do this same thing on so I don't want to hard code this anywhere in settings... it should figure out where the root of its URL is and act accordingly.
How do I set it up so that Django automagically redirects to what Apache considers that application's web root?
You need to set LOGIN_URL and LOGOUT_URL to full URL path in Django settings file. See:
http://docs.djangoproject.com/en/1.3/ref/settings/#login-url
Django doesn't automatically insert the mount point at the start of those as so have to be fully qualified.
The same problem can be solved in a more generic way for all project URLs. You could checkout an alternative solution at Running a Django site on my local machine, am I redirecting my URLs properly? for an environment based ROOT URL support.