Django'网站'模型 - 'SITE_ID = 1'是什么和为什么?

don*_*yor 37 django django-sites

我正在尝试使用SitesDjango模型.

我不太明白为什么SITE_ID应该这样SITE_ID = 1.

在文档中:

django_site数据库表中当前站点的ID(整数).这样可以使应用程序数据挂钩到特定站点,单个数据库可以管理多个站点的内容.

为什么1?是什么current site?这在文档中没有明确解释.

比方说,我有www.somecoolsite.com和其他一些子域名喜欢www.wow.coolsite.comwww.awesome.coolsite.com

我想根据域名呈现不同的内容.

我的问题是,或更好,是:

  1. 我是否必须将所有这些域添加到SitesDB中的表中?
  2. 如果是这样,我应该如何SITE_ID设置?我必须设置像所有的ID SITE_ID = 1,SITE_ID = 2..等等?
  3. 与此current site有什么关系SITE_ID = 1

我在这里有点困惑.

我想,每个站点(例如www.wow.coolsite.com)应该是一个单独的django项目,以便他们可以拥有自己的settings.py?在每个settings.py中,我将从Sites表中设置该页面的id?但是有很多django项目对我来说也没有意义.

Bur*_*lid 26

Django是由一组在报纸上开发的脚本创建的,用于在多个域上发布内容; 使用一个单一的内容库.

这就是"站点"模块的用武之地.它的目的是标记要为不同域显示的内容.

在以前的django版本中,startproject脚本自动添加了django.contrib.sites应用程序INSTALLED_APPS,当你这样做时syncdb,带有URL的默认站点example.com被添加到你的数据库中,因为这是第一个站点,所以它的ID就是1设置的来源.

请记住,从1.6开始,默认情况下不启用此框架.因此,如果您需要它,您必须启用它

SITE_ID设置设置项目的默认站点.因此,如果您未指定网站,则会使用此网站.

因此,要为不同的域配置应用程序:

  1. 启用站点框架
  2. 将默认站点更改为默认example.com域.您可以从django shell或管理员执行此操作.
  3. 将要向其发布内容的其他网站添加到网站应用程序.同样,您可以像任何其他应用程序或管理员一样从django shell执行此操作.
  4. 在对象中为站点模型添加外键 site = models.ForeignKey(Site)
  5. 添加站点管理器 on_site = CurrentSiteManager()

现在,当您要过滤默认网站或特定网站的内容时:

foo = MyObj.on_site.all() # Filters site to whatever is `SITE_ID`
foo = MyObj.objects.all() # Get all objects, irrespective of what site
                          # they belong to
Run Code Online (Sandbox Code Playgroud)

文档包含一整套示例.

  • 谢谢,但我仍然不确定“SITE_ID”。如果我有 3 个站点怎么办?我是否必须将所有这 3 个站点 ID 添加到一个主要的 settings.py 中?这对我现在没有任何意义:( (2认同)

Rob*_*obM 14

如果Django的默认SiteAdmin在字段中包含id字段,那么事情会更容易理解list_display.

为此,您可以重新定义SiteAdmin(在您的应用中的任何位置,但我建议您使用admin.py或者您的urls.py),如下所示:

from django.contrib import admin
from django.contrib.sites.models import Site

admin.site.unregister(Site)
class SiteAdmin(admin.ModelAdmin):
    fields = ('id', 'name', 'domain')
    readonly_fields = ('id',)
    list_display = ('id', 'name', 'domain')
    list_display_links = ('name',)
    search_fields = ('name', 'domain')
admin.site.register(Site, SiteAdmin)
Run Code Online (Sandbox Code Playgroud)

包含此代码段后,每个"站点"的ID将显示在管理列表的第一列中,并在表单内显示为只读字段.这些'id'字段是您需要用作SITE_ID的字段:

修改后的管理页面显示了站点记录的ID

这个概念是每个不同的站点在不同的应用程序服务器实例中运行,使用不同的yourdomain_settings.py启动,然后包含base_settings.py和其他常见配置.

这些yourdomain_settings.py中的每一个都将定义自己的SITE_ID和所有其他不同的settings.py参数,它们需要查看并且彼此不同(静态资源,模板等),然后您将定义指向的DJANGO_SETTINGS_MODULE环境变量启动该域的应用程序服务器实例时特定的yourdomain_settings.py文件.

get_current_site(request)需要注意:确实需要request它可以工作.如果您的代码没有,您可以使用Site.objects.get_current()它,但是需要在正在运行的应用程序服务器的设置中正确定义的SITE_ID.


Edw*_*ner 6

这是一个迟到的答案,但对于其他有 SITE_ID 问题和站点问题的人来说。在数据库内部,django 有一个 django_site 表,其中包含(id、domain、name)。这是 django 存储 SITE_ID 的地方。我的数据库中实际上是 5,但我在设置中将其设置为 SITE_ID=1。

知道了这一点,我现在可以返回数据库并清除它以返回零或使用数据库中的实际 ID。


Jon*_*ter 6

这在Sites框架的文档中有所介绍:

为了在生产中为不同的站点提供服务,您需要为每个SITE_ID创建一个单独的设置文件(可能从公共设置文件导入以避免重复共享设置),然后为每个站点指定相应的DJANGO_SETTINGS_MODULE.

但如果您不想这样做,则根本无法进行设置SITE_ID,只需根据视图中的域名查找当前站点get_current_site:

from django.contrib.sites.shortcuts import get_current_site

def my_view(request):
    current_site = get_current_site(request)
    if current_site.domain == 'foo.com':
        # Do something
        pass
    else:
        # Do something else.
        pass
Run Code Online (Sandbox Code Playgroud)