【问题标题】:Django 'Sites' Model - what is and why is 'SITE_ID = 1'?Django 'Sites' 模型 - 什么是'SITE_ID = 1',为什么是'SITE_ID = 1'?
【发布时间】:2014-10-17 14:04:15
【问题描述】:

我正在尝试使用Sites Django 模型。

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

在文档中:

django_site 数据库中当前站点的 ID,整数形式 桌子。这用于使应用程序数据可以挂钩到特定的 站点和单个数据库可以管理多个站点的内容。

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

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

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

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

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

我有点困惑。

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

【问题讨论】:

    标签: django django-sites


    【解决方案1】:

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

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

    在以前的django版本中,startproject脚本自动将django.contrib.sites应用添加到INSTALLED_APPS,当你添加syncdb时,a default site with the URL example.com was added to your database,由于这是第一个站点,它的ID是@ 987654331@ 这就是设置的来源。

    请记住,从 1.6 开始,默认情况下不启用此框架。所以需要的话一定要enable it

    SITE_ID 设置为您的项目设置 默认 站点。所以,如果你don't specify a site,它会使用这个。

    所以要为不同的域配置你的应用程序:

    1. Enable the sites framework
    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
    

    documentation 有全套示例。

    【讨论】:

    • 谢谢,但我仍然不确定SITE_ID。如果我有 3 个站点怎么办?我是否必须将所有这 3 个站点 ID 添加到一个主要的 settings.py 中?这对我现在没有任何意义:(
    • 我认为,每个站点都应该是一个单独的 django 项目,以便他们可以拥有自己的 settings.py?在那个settings.py中,我会从Sites表中设置那个页面的ID?但是有很多 django 项目对我来说也没有意义:(
    • 您无需创建多个项目,只需将所有域添加到站点数据库即可;然后根据当前域是什么,您过滤要显示的内容。它是一个非常简单的基本实现。
    • django 知道当前站点取决于 settings.py 中的SITE_ID,对吧?如何在单个 settings.py 中有多个 SITE_IDfoo = MyObj.on_site.all() 如何知道当前站点是什么?很抱歉有很多问题。
    • 您在设置文件中有一个 SITE_ID。每个站点都有自己的服务器。在每台服务器上,您设置不同的 DJANGO_SETTINGS_MODULE,选择不同的设置,从而获得不同的 SITE_ID。
    【解决方案2】:

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

    为此,您可以像这样重新定义 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)
    

    包含此代码 sn-p 后,每个“站点”的 ID 将显示在管理列表的第一列和表单内作为只读字段。您需要将这些“id”字段用作 SITE_ID:

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

    这些 yourdomain_settings.py 中的每一个都将定义自己的 SITE_ID 和所有其他不同的 settings.py 参数,它们需要看起来和彼此不同(静态资源、模板等),然后你会 define a DJANGO_SETTINGS_MODULE environment variable pointing to that specific yourdomain_settings.py file 当启动该域的应用程序服务器实例。

    进一步说明:get_current_site(request) 确实需要request 才能工作。如果您的代码没有,您可以使用Site.objects.get_current(),但需要在正在运行的应用程序服务器的设置中正确定义 SITE_ID。

    【讨论】:

    • 这就是我一直在寻找的答案。 Django 的文档不够清楚,无法确定它是打算这样使用的。有时值得去最后一个答案;)
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      为了在生产环境中为不同的网站提供服务,您需要创建一个 具有每个 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
      

      【讨论】:

        【解决方案5】:

        link 解释它:

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

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

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

        另外,如果你想知道如何修改模型和设置视图,你可以看看这个链接: https://django.cowhite.com/blog/managing-multiple-websites-with-a-common-database-in-django-the-sites-framework/

        【讨论】:

        猜你喜欢
        • 2014-08-07
        • 2011-08-08
        • 2014-01-25
        • 1970-01-01
        • 2012-06-13
        • 1970-01-01
        • 2018-09-08
        • 1970-01-01
        • 2018-06-20
        相关资源
        最近更新 更多