[英]django SITE_ID by query
我有一个 django 应用程序。 我正在添加第二个站点。
所以现在我需要正确设置 SITE_ID。 这很容易,除了因为它是 Site 表中的主键 id,这意味着该值取决于添加(并最终删除)站点的顺序。 这很脆弱,甚至没有讨论如果开发人员在该表中做了任何临时工作,他们将如何对其进行排序。 通过查询设置它要好得多。
SITE_ID = Site.objects.get(name='my_site_name').id
但是设置WSGI_APPLICATION
的settings_myapp.py
文件几乎是唯一可能知道我正在运行哪个应用程序的文件。 我可以尝试修改该站点特定settings
文件中的设置,但此时导入设置会导致SECRET_KEY
尚未定义的错误。
有没有一种强大的方法来做到这一点?
这是我如何解决我在问题中陈述的问题的总结。 当我问这个问题时,我并不知道,实际上有几个方面需要不同的方法。
一点中间件对已部署的实例(即,不是开发实例)有很大帮助。 此解决方案提供了 django 3.1 就绪代码片段,因为过去存在的解决方案不再与现代 django 兼容。
对于开发人员,我将其添加到我的settings.py
:
DEFAULT_SITE_ID = os.getenv('DEFAULT_SITE_ID')
所以上面的代码片段变成了这样:
class DynamicSiteDomainMiddleware:
default_site_id = None
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
self.default_site_id = settings.DEFAULT_SITE_ID
if self.default_site_id is not None:
current_site = Site.objects.get(id=self.default_site_id)
def __call__(self, request):
if self.default_site_id is None:
try:
current_site = Site.objects.get(domain=request.get_host())
except Site.DoesNotExist:
current_site = Site.objects.get(id=settings.DEFAULT_SITE_ID)
else:
current_site = Site.objects.get(id=self.default_site_id)
request.current_site = current_site
settings.SITE_ID = current_site.id
response = self.get_response(request)
return response
换句话说,如果开发人员已设置DEFAULT_SITE_ID
(例如,在调用manage.py
时在命令行上),则使用该值。 否则,我们会根据请求查看 SNI。
这留下了一个未解之谜:如何处理urlpatterns
? 我有两个站点(很快三个),它们的 URL 方案略有不同。 但是在主urls.py
中,站点信息在这个聪明的中间件解决方案下尚不可用,因为 urlpatterns (自然且必然)在任何请求发生之前设置。
对我来说最好闻的方法设置环境变量,以便settings.py
可以为其特定情况设置ROOT_URLCONF
。
ROOT_URLCONF = os.getenv('ROOT_URLCONF', 'transport_nantes.urls_tn')
一个明显的缺点是我们最终遇到了两种不兼容的设置站点数据的机制: DEFAULT_SITE_ID
+ SNI 和ROOT_URLCONF
。 然而,这并不像看起来那么糟糕,因为这是问题的两个独立方面:我是什么站点以及我打算拥有的 URL 方案。 这需要对生产和暂存部署代码进行非常小的更改以设置适当的环境变量。
最后,在每个url_XYZ.py
文件中,我为该版本网站的基本模板设置了一个变量。 (问题在于链接不同。如果只是更改徽标,那会更容易。)我将字典中的值传递给包含的 url 文件,因此我可以在渲染视图时使用该知识,即使视图功能通常在多个站点和 URL 方案之间共享。
那么为什么不也为SITE_ID
设置一个环境变量呢? 这又回到了最初的问题:站点 id 是脆弱的,它是站点表中的主键。 可以合理地想象一些维护会使站点表保持不变,除了更改的主键(例如,无意删除然后重新创建记录)。 因此,按名称查找值更加健壮。
另一方面, ROOT_URLCONF
变量的优点是它不绑定到站点表。 例如,站点 X 有一个特定的 URL 方案,无论 X 是在生产中运行还是在暂存或测试中运行,都是如此,所有这些都有不同的 FQDN。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.