You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

django-cms中根据屏幕分辨率使用不同模板的最佳实践问询

Great question! When CSS media queries aren’t enough and you need full template swaps based on screen resolution in django CMS, here are the most reliable production-proven approaches I’ve used:

1. Server-Side Template Selection with Frontend-to-Backend Resolution Sync

Since servers can’t natively detect a user’s screen resolution, you’ll first need to pass that data from the frontend to the backend. Here’s how to set this up:

Add a small script to your base template to capture the screen width and store it in a cookie (so subsequent requests include this data):

document.addEventListener('DOMContentLoaded', function() {
    const screenWidth = window.screen.width;
    // Set cookie with 1-day expiration
    document.cookie = `screen_res=${screenWidth}; max-age=86400; path=/`;
});

Create a middleware that reads the cookie and attaches the resolution data to the request object:

# myapp/middleware.py
class ScreenResolutionMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        screen_res = request.COOKIES.get('screen_res')
        if screen_res:
            request.screen_width = int(screen_res)
        else:
            # Fallback to a default (e.g., desktop)
            request.screen_width = 1200
        response = self.get_response(request)
        return response

Don’t forget to add this to your MIDDLEWARE setting in settings.py.

Step 3: Dynamic Template Loading in django CMS

You can override the template selection for CMS pages either via a custom apphook or by modifying the CMS page’s view. For example, in a custom apphook:

# myapp/cms_apps.py
from django_cms.apphook_pool import apphook_pool
from django_cms.app_base import CMSApp
from django.views.generic import TemplateView

class ResponsiveApphook(CMSApp):
    name = "Responsive App"
    urls = ["myapp.urls"]

apphook_pool.register(ResponsiveApphook)

# myapp/views.py
class ResponsivePageView(TemplateView):
    def get_template_names(self):
        # Define your breakpoints
        if self.request.screen_width < 768:
            return ["myapp/mobile_template.html"]
        elif self.request.screen_width < 1024:
            return ["myapp/tablet_template.html"]
        else:
            return ["myapp/desktop_template.html"]
2. Client-Side Full Template Swap (For Instant Window Resizing)

If you need the template to switch immediately when the user resizes their window (without a page reload), use client-side rendering:

Step 1: Load a Base Skeleton Template

Start with a minimal base template that only includes the necessary scripts and a placeholder for content:

<!-- base_skeleton.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
    <script src="{% static 'js/responsive_switcher.js' %}"></script>
</head>
<body>
    <div id="content-container"></div>
</body>
</html>

Step 2: Async Template Loading Script

Create a script that checks the window size, fetches the appropriate template via an API endpoint, and replaces the content container:

// static/js/responsive_switcher.js
function loadTemplate(width) {
    let templateUrl;
    if (width < 768) {
        templateUrl = '/api/templates/mobile/';
    } else if (width < 1024) {
        templateUrl = '/api/templates/tablet/';
    } else {
        templateUrl = '/api/templates/desktop/';
    }

    fetch(templateUrl)
        .then(response => response.text())
        .then(html => {
            document.getElementById('content-container').innerHTML = html;
        });
}

// Initial load
loadTemplate(window.screen.width);

// Listen for window resizing (debounce to avoid excessive requests)
let resizeTimeout;
window.addEventListener('resize', function() {
    clearTimeout(resizeTimeout);
    resizeTimeout = setTimeout(() => loadTemplate(window.innerWidth), 200);
});

Step 3: Create the API Endpoint

Add a view that returns the rendered template based on the request (you can reuse the screen width detection from the middleware here):

# myapp/views.py
from django.http import HttpResponse
from django.template.loader import render_to_string

def get_responsive_template(request):
    if request.screen_width < 768:
        html = render_to_string('myapp/mobile_template.html', request=request)
    elif request.screen_width < 1024:
        html = render_to_string('myapp/tablet_template.html', request=request)
    else:
        html = render_to_string('myapp/desktop_template.html', request=request)
    return HttpResponse(html, content_type='text/html')

Map this view to a URL in your urls.py.

3. Key Considerations for Production
  • Caching: django CMS’s page caching will cache the first rendered template. To avoid this, add the screen resolution to your cache key. You can use a custom cache backend or modify the CMS_CACHE_KEY_FUNCTION setting to include request.screen_width.
  • Fallback Behavior: Always include a default template for cases where the cookie isn’t set (e.g., first-time visitors without JavaScript).
  • Performance: For client-side swapping, debounce resize events and consider caching templates locally with localStorage to reduce API calls.

内容的提问来源于stack exchange,提问作者user3260061

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:17:09