56

我正在尝试使用SitesDjango 模型。

我不太明白为什么SITE_ID应该是SITE_ID = 1

在文档中:

django_site 数据库表中当前站点的 ID,整数形式。这用于使应用程序数据可以连接到特定站点,并且单个数据库可以管理多个站点的内容。

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

可以说,我有www.coolsite.com和其他一些子域,比如www.wow.coolsite.comwww.awesome.coolsite.com

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

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

  1. 我是否必须将所有这些域添加到Sites数据库中的表中?
  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 项目对我来说也没有意义。

4

5 回答 5

43

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

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

在以前版本的 django 中,startproject脚本会自动将django.contrib.sites应用程序添加到INSTALLED_APPS,当您这样做时syncdb带有 URL 的默认站点example.com会添加到您的数据库中,并且由于这是第一个站点,因此它的 ID 是1,这就是设置的来源。

请记住,从 1.6 开始,默认情况下不启用此框架。所以如果你需要它,你必须启用它

SITE_ID设置为您的项目设置默认站点。因此,如果您不指定 site,它将使用它。

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

  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

文档包含一整套示例。

于 2014-08-24T05:21:56.657 回答
19

如果 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)

包含此代码片段后,每个“站点”的 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。

于 2018-01-06T05:45:25.727 回答
6

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

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

于 2015-11-22T16:46:11.240 回答
5

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

为了在生产中为不同的站点提供服务,您需要为每个 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
于 2016-04-28T20:36:33.407 回答
1

这个链接解释它:

您需要为要添加的每个域创建单独的设置文件;每个都需要自己的 MEDIA_URL 和其他设置。您还需要做两件事以确保一切正常以管理不同的站点:

在您的管理员中为每个域创建一个新的 Site 对象,并将该站点的 id 作为 SITE_ID 放入其设置文件中,以便 Django 知道数据库中的哪个站点对应于该设置文件。

在原始站点的设置文件(id 为 1 的站点)中,将其他站点的设置文件添加到 ADMIN_FOR 设置,让 Django 知道管理应用程序的这个实例将处理所有站点。

此外,如果您想了解如何修改模型和设置视图,您可以查看此链接: https ://django.cowhite.com/blog/managing-multiple-websites-with-a-common-database-在-django-the-sites-framework/

于 2019-01-25T23:13:14.223 回答