【问题标题】:How to make some Django settings accessible by staff?如何让员工可以访问一些 Django 设置?
【发布时间】:2010-12-22 11:22:36
【问题描述】:

在 Django 中,设置存储在文件 settings.py 中。该文件是代码的一部分,并进入存储库。只有开发人员处理此文件。管理员处理模型,数据库中的数据。这是非开发人员编辑的数据,网站访问者在模板中看到的呈现。

问题是,我们的网站和许多其他网站都有很多设置选项,非开发人员应进行编辑。我们谈论的是在数据库中确实没有位置的独立站点范围的常量。将它们放入数据库将导致大量无意义的查询。缓存可以缓解这种情况,但是处理 settings.py 文件中的一行可以完成的事情似乎不必要地复杂。

我确实注意到了this dbsettings app,但它很旧且无人维护。我还注意到 django 电子商务应用程序 Satchmo 包含此 dbsettings 应用程序的特定用例分支。我们可以在我们的网站中构建类似的东西,一个将一些设置作为键/值对存储在单个数据库表中的应用程序,但这似乎真的是错误的方法。为什么要在数据库中放一些不属于那里的东西只是为了让非开发人员更容易编辑?

我们的 Django 站点上有一个站点范围的设置列表,我们希望非开发人员管理员可以编辑这些设置。解决这个问题的最佳方法是什么?

【问题讨论】:

  • +1 因为知道这一点可以更轻松地在 VCS 中管理 Django 项目。开发人员必须小心,否则不要将本地更改提交到 settings.py。
  • 缓存将缓解这种情况(当将本地设置放入数据库时​​)每个 django 进程实例只有一个查询。
  • 要重新启动服务器以重新加载设置,您只需调用“touch site.wsgi”文件,例如使用 cron 作业,但这只有在您的 wsgi 进程以守护程序模式运行时才有效
  • 提供一些您正在谈论的管理员设置类型的示例可能会有所帮助。 settings.py 用于部署时配置,因此显然与您在运行时尝试执行的操作存在阻抗不匹配。完全摒弃数据库驱动的解决方案对我来说似乎是过早的优化。

标签: python django settings


【解决方案1】:

dbsettings 之类的东西(正如你提到的)似乎是要走的路。来自该项目的reasons for existence

并非所有设置都属于 settings.py,因为它有一些 特别限制:

  • 设置是项目范围的。这不仅需要应用程序混乱 settings.py,也增加了点名的机会 冲突。

  • 设置在整个 Django 实例中是不变的。他们不能 在不重新启动应用程序的情况下更改。

  • 设置需要程序员才能更改。这是真的,即使 如果该设置对其他任何功能没有影响。

如果 dbsettings 不适合你,那么实现你自己的,或者 fork 。好像不会太辛苦。

【讨论】:

    【解决方案2】:

    我实际上是 dbsettings 的忠实拥护者,并一直打算发布我的 fork,将其修补以与 Django 1.1 一起使用(实际上并不是很大的变化)。好像有人有updated it already

    但是,您可能是对的,这对于您需要的东西来说太过分了。我之前做过的一件事是在 settings.py 的末尾添加一行,用于导入和解析 YAML 文件。 YAML 是一种简单的标记语言,最基本的就是KEY: VALUE ...

    CONSTANT1: MyValue
    CONSTANT2: Anothervalue
    

    如果你把它放在编辑器可以访问的地方,那么在 settings.py 的末尾你只需这样做:

    import yaml
    try:
        globals().update(yaml.load(open('/path/to/my/yaml/file.yml')))
    except:
        pass
    

    您需要 Python YAML 库来解析 YML 文件。

    这种方法的缺点是您需要重新启动 Apache 才能让它接受更改。

    Edited to add 构建一个可以编辑这个文件的前端并提供一个运行脚本来重启 Apache 的按钮并不是特别困难。

    【讨论】:

    • 此解决方案不起作用,因为只有技术人员才能编辑服务器上的文件和/或重新启动 apache。
    • 构建一个可以编辑这个文件的前端并提供一个运行脚本来重启Apache的按钮并不是特别困难。
    • @Daniel - 虽然此时您正在进入 dbsettings 所需的相同类型的工作级别。
    【解决方案3】:

    如果您必须避免服务器重新启动,那么设置的逻辑位置是 Dominic 和 Daniel 所说的数据库,但是您需要在每次更新缓存的设置对象时使其无效。

    看起来可以使用 Django 的low level cache API 重新设置缓存中的值。通过这些调用应该可以实现您想要的一切:

     cache.set('settings', local_settings)
     cache.add('settings', local_settings)
     local_settings = cache.get('settings')
     cache.delete('settings')
    

    【讨论】:

      【解决方案4】:

      如何将 sitesettings.py(或其他)放在管理员可以访问的地方,然后在 settings.py 中做

      from sitesettings import *
      

      这看起来既好又简单,但我可能误解或过度简化了你的问题:)

      【讨论】:

      • 此解决方案也不起作用,因为只有技术人员才能编辑服务器上的文件和/或重新启动 apache。
      【解决方案5】:

      models.py

      class Setting(models.Model):
          """Global settings for app"""
          name = models.CharField(max_length=100, null=False, blank=False)
          value = models.CharField(max_length=100, null=False, blank=False)
      
          def __str__(self):
              return self.name
      

      admin.py

      from YOUR_APP.models import Setting
      class SettingAdmin(admin.ModelAdmin):
          list_display = (
              'name',
              'value',
          )
      admin.site.register(Setting, SettingAdmin)
      

      extras.py

      @register.filter
      def get_setting(name):
          setting = Setting.objects.get(name=name)
          return setting.value
      

      模板.html

      {% if 'setting_name'|get_setting == 'true' %}
          Display your Feature
      {% endif %}
      

      【讨论】:

        【解决方案6】:

        Django Packages 有一个page,列出了提供此类功能的包 - 大多数包查询数据库,然后使用缓存来最大程度地减少对 DB 的访问。

        我发现 Django Dynamic Preferences 非常有趣,因为它为您提供了对配置的细粒度控制。

        【讨论】:

          猜你喜欢
          • 2019-03-26
          • 2012-02-24
          • 1970-01-01
          • 1970-01-01
          • 2015-05-17
          • 2014-01-06
          • 2021-04-18
          • 2019-05-03
          • 2013-05-03
          相关资源
          最近更新 更多