在学习mezzanine的过程中遇到了多site管理的问题。
本地服务器ip地址为192.168.0.105,端口为9000. 在浏览器中输入192.168.0.105可以正常访问网页。做了端口映射后通过域名(owenchenxy.vicp.io)访问站点则出现404错误。
图1 站点选择为owenchenxy.vicp.io时的page内容
图2 站点选择为192.168.0.105时的page内容
经过检查发现,如上图1,图2所示,站点分别为owenchenxy.vicp.io和192.168.0.105:9000时,page的内容不同。证明在浏览器中输入的域名导致mezzanine进入了不同的site。经过查阅相关信息,了解到mezzanine决定进入哪个站点的条件如下(原文链接:点击打开链接):
Here’s the list of checks in the pipeline, in order:
因此,针对以上问题,我想到以下两种解决方法:
- The session variable site_id. This allows a project to include features where a user’s session is explicitly associated with a site. Mezzanine uses this in its admin to allow admin users to switch between sites to manage, while accessing the admin on a single domain.
- The domain matching the host of the current request, as described above.
- The environment variable MEZZANINE_SITE_ID. This allows developers to specify the site for contexts outside of a HTTP request, such as management commands. Mezzanine includes a custommanage.py which will check for (and remove) a --site=ID argument.
- Finally, Mezzanine will fall back to the SITE_ID setting if none of the above checks can occur.
一.添加Site法:
- step1:由上述第二条匹配规则“The domain matching the host of the current request, as described above.”,由浏览器输入的域名决定站点,因此可以在数据库的Site表中添加所输入域名的条目,可以在/admin界面中添加,也可以通过命令行添加:
(mezzanine) [root@192 mezzsite]# python manage.py shell
Python 2.7.5 (default, Aug 4 2017, 00:39:18)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.contrib.sites.models import Site
>>> Site.objects.create(pk=3, domain='owenchenxy.vicp.io', name='owenchenxy.vicp.io')
<Site: owenchenxy.vicp.io>
- step2:添加完site条目后,如图1,选择对应域名的site(owenchenxy.vicp.io),编辑其对应的内容,当然,仍然与192.168.0.105:9000站点的内容不同。
二.匹配SITE_ID法:
方法一虽然可以避免因域名不能对应站点导致页面无法访问,但并没有解决一个根本问题,试想,我们在开发过程中一直使用192.168.0.105:9000作为访问站点的域名,当部署到服务器后,需要使用域名(owenchenxy.vicp.io)来访问,如果使用方法一的话,岂不是要把192.168.0.105:9000上的内容全部在owenchenxy.vicp.io这个site上重新做一遍,而我们做端口映射的目的正是想要通过owenchenxy.vicp.io直接访问与192.168.0.105:9000相同的内容。因此,我们想到可以通过SITE_ID来进行匹配,直接进入192.168.0.105:9000的本地site。
- step1:检查Site表中的条目,删除与域名匹配的条目(如果没有则跳过这步),也可以直接在/admin页面的sites里删除:
>>> Site.objects.get(pk=3)
<Site: owenchenxy.vicp.io>
>>> Site.objects.get(pk=3).delete()
(3, {u'conf.Setting': 0, u'redirects.Redirect': 0, u'pages.RichTextPage': 1, u'core.SitePermission_sites': 0, u'sites.Site': 1, u'pages.Page': 1})
- step2: 找到本地服务器对应的SITE_ID, 查看Django关于SITE_ID的说明点击打开链接,SITE_ID就是Site表中的ID字段:
Sites¶
Settings for django.contrib.sites.
SITE_ID¶
Default: Not defined
The ID, as an integer, of the current site in the django_site database table. This is used so that application data can hook into specific sites and a single database can manage content for multiple sites.
运行下面命令找出SITE_ID:
>>> Site.objects.get(domain__icontains="192.168.").id
2
- step3:修改settings.py文件中的SITE_ID参数,使其与上一步找出来的ID相等(本例中为2)
#settings.py
...
SITE_ID = 2
...
- step4:清除浏览器缓存,重新尝试用域名访问站点,则这次可以直接访问到192.168.0.105:9000站点的内容了。