You're right, using a single Django instance to serve multiple sites with overridden templates can be tricky. While a custom template loader might seem appealing, it's true that it doesn't accept the request object by default. Here's the breakdown and some alternative solutions:
The Challenge: - Django's default template loader doesn't consider the current domain when searching for templates. - You want to use a single Django instance but have domain-specific templates. Less Ugly Solutions: 1. Template Name Prefixing: - Prefix your template names with the domain name. For example, domain1/home.html and domain2/home.html. - In your views, construct the full template name based on the current domain (using get_current_site). - This approach is simple but can make template names lengthy and less readable. 2. Template Inheritance with Context Processors: - Create a base template with common elements. - Inherit from the base template for each domain-specific template. - Use a context processor to inject the current domain information into the context. - In your domain-specific templates, use the domain information to conditionally render specific content. - This approach offers flexibility but requires more code in templates and context processors. 3. Third-Party Packages: - Consider packages like django-sites-templates or django-multihost-template-loader. - These packages provide custom template loaders that can leverage the request object to determine the appropriate template based on the domain. - This approach can be a good option if the built-in solutions don't meet your needs. Middleware with Context Variables (Least Ugly Hack): - While not ideal, storing the request object in a context variable using middleware is a workable solution. - However, be mindful of potential issues like variable name conflicts and unnecessary data passed to every template. Choosing the Best Approach: The best solution depends on your project's complexity and preference. Here's a quick guide: - Simple Projects: Template Name Prefixing might suffice. - More Complex Projects: Consider Template Inheritance with Context Processors or Third-Party Packages for better maintainability. - Last Resort: Use the Middleware approach cautiously if other options aren't feasible. Remember, the key is to find a balance between simplicity and maintainability. Leverage built-in features and explore third-party packages before resorting to complex hacks. I'm available if you want further assistance or questions about it๐ Have a good day ahead. On Wed, May 29, 2024, 5:52 AM Mike Dewhirst <mi...@dewhirst.com.au> wrote: > On 28/05/2024 9:09 pm, Antonis Christofides wrote: > > Hello, > > I use the sites framework for a Django project that serves many different > domains. But each of those domains has some templates overridden. > > > Might depend on what you are overriding - entire templates or just > includes or just vars. > > I would probably start by refactoring the templates so they were identical > for all sites and reduce/extract the differences to includes which can be > selected via contextvars after calling get_current_site() from the view. > > Have you looked at template tags? > > I use them for displaying additional information on the staging and dev > sites versus production. Not what you are doing so I haven't thought too > hard about that. Only worth a thought if you haven't considered it. > > > If I used a different instance of Django (i.e. a different gunicorn > service) for each domain, I'd have different settings for each site. But > I'm using a single instance to serve all sites and, wherever I need to, I > use things that extract the domain from the request, like > `get_current_site()`. But this doesn't seem to work with templates. A > custom template loader won't work without a fight because its methods don't > accept the request object as an argument. > > All solutions I've thought about are ugly hacks. > > > Practicality beats purity > > The least ugly seems to be to create middleware that stores the request > object in a contextvar > <https://docs.python.org/3/library/contextvars.html>. But it strikes me > that I can't find a simpler solution for this. Is what I want that > uncommon, or am I missing something? > > There's an old closed "wontfix" ticket > <https://code.djangoproject.com/ticket/13500> about this but without > adequate explanation. > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/175b4601-2038-479b-9581-48d9c196df7cn%40googlegroups.com > <https://groups.google.com/d/msgid/django-users/175b4601-2038-479b-9581-48d9c196df7cn%40googlegroups.com?utm_medium=email&utm_source=footer> > . > > > > -- > We recommend signal.org > > Signed email is an absolute defence against phishing. This email has > been signed with my private key. If you import my public key you can > automatically decrypt my signature and be sure it came from me. Your > email software can handle signing. > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/befa4ac2-40b8-44da-87c2-cbbe3ed307c6%40dewhirst.com.au > <https://groups.google.com/d/msgid/django-users/befa4ac2-40b8-44da-87c2-cbbe3ed307c6%40dewhirst.com.au?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAP3eejx6%3DoMLTNz7JUjkHA74-BWEsU98ntDxQwnDzu31EaN5DQ%40mail.gmail.com.