如何在Django中实现基于房间名称的子域名路由?
没问题!要在Django项目里实现房间名称作为子域名访问的需求,完全可以做到,django-subdomains这个库刚好能完美匹配你的需求,甚至不用第三方库也能手动实现,下面给你详细拆解两种方案:
方案一:使用django-subdomains库(推荐)
这个库专门为Django处理子域名路由设计,配置起来很省心:
- 安装库
先通过pip安装:
pip install django-subdomains
- 配置settings.py
- 把
subdomains添加到INSTALLED_APPS:INSTALLED_APPS = [ # 其他已有应用 'subdomains', ] - 添加子域名中间件到
MIDDLEWARE(注意顺序要靠前,放在常见中间件比如CommonMiddleware之前):MIDDLEWARE = [ 'subdomains.middleware.SubdomainMiddleware', # 其他中间件 ] - 配置域名和子域名路由映射:
DOMAIN_NAME = 'toto.fr' # 把房间子域名指向专门的URL配置文件,也可以直接映射到视图 SUBDOMAIN_URLCONFS = { None: 'your_project.urls', # 主域名(toto.fr)用主URL配置 '*': 'your_project.room_urls', # 所有其他子域名用房间专属URL配置 }
- 编写房间的URL配置(room_urls.py)
在这个文件里,你可以直接通过request.subdomain拿到房间名称,或者把它作为视图参数:
from django.urls import path from .views import room_detail urlpatterns = [ path('', room_detail, name='room-detail'), ]
- 编写视图逻辑
在视图里获取子域名,查询对应的房间对象,同时排除系统级子域名避免冲突:
from django.shortcuts import get_object_or_404, render from .models import Room def room_detail(request): # 从request.subdomain拿到房间名称 room_name = request.subdomain # 排除www、admin这类特殊子域名 if room_name in ['www', 'admin', 'api']: return render(request, '404.html') room = get_object_or_404(Room, name=room_name) return render(request, 'room/detail.html', {'room': room})
方案二:手动实现(不依赖第三方库)
如果不想额外引入依赖,也可以自己写中间件解析子域名:
- 自定义子域名中间件
在项目根目录创建middleware.py文件,添加以下代码:
class SubdomainMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): host = request.get_host().split(':')[0] # 去掉端口号 parts = host.split('.') # 处理二级域名场景(比如toto.fr) if len(parts) >= 2: subdomain = '.'.join(parts[:-2]) request.subdomain = subdomain if subdomain else None else: request.subdomain = None response = self.get_response(request) return response
然后把这个中间件添加到settings.py的MIDDLEWARE列表中。
- 在视图里使用子域名
和方案一的视图逻辑一致,直接通过request.subdomain获取房间名称,查询对应的Room对象即可。
关键注意事项
- DNS配置:要在域名服务商处设置通配符DNS记录(
*.toto.fr),指向你的服务器IP,这样所有子域名请求才能到达你的服务。 - Web服务器配置:比如用Nginx的话,要设置
server_name *.toto.fr;,并将请求转发到Django的WSGI接口。 - 开发环境测试:可以修改本地
hosts文件(Windows路径:C:\Windows\System32\drivers\etc\hosts;Linux/macOS路径:/etc/hosts),添加一行127.0.0.1 microsoft.toto.fr,就能在本地测试子域名访问了。 - 子域名冲突处理:提前规划好系统级子域名(比如www、admin、api),避免和用户创建的房间名称重复。
内容的提问来源于stack exchange,提问作者krowry
相关产品推荐
相关产品推荐

