【问题标题】:Access domain (and port) URL in settings.py file while in localhost development在 localhost 开发中访问 settings.py 文件中的域(和端口)URL
【发布时间】:2022-06-12 03:43:15
【问题描述】:

如何动态访问Django的settings.py文件中的域名URL? (即“http://localhost:8000”)

我在开发过程中尝试在互联网不可用时覆盖包 CDN,并希望指向 static 文件目录中的本地文件。虽然 os.path.join(BASE_DIR, "path/to/local.file") 应该可以工作,但它取决于哪个 app/url(即“http://localhost:8000/app/static/css/ bootstrap.min.css "),而不仅仅是将静态文件位置附加到带有./manage.py runserver 0:8000 的起始服务器的主域(即“http://localhost:8000/static/css/bootstrap.min.css”)。

注意事项:

  • 因为这是在settings.py 中,所以我无法加载任何应用程序或reverse 因为错误*** django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
  • 我不在模板中,所以无法使用static url
  • 静态定义它不会在通过./manage.py runserver 0:8000启动时允许不同的端口加载
  • settings.py 基本上是一个 python 模块,但是如何获取其中的域呢?

基本上在settings.py文件中:

# If in local dev
if "RDS_DB_NAME" not in os.environ:
    # the setting for the package I am pointing to a local version
    BOOTSTRAP5 = {
        "css_url": {
            ### dynamically get domain here ###
            # "href": os.path.join(LOCAL_DIR, "static/css/bootstrap.min.css"),
            "href": "static/css/bootstrap.min.css",
        }

【问题讨论】:

    标签: python django development-environment django-settings


    【解决方案1】:

    您无法访问settings.py 中的域。当你运行./manage.py runserver 0:8000 时,你是在告诉 Django 监听 localhost 的 8000 端口。但是你不能从这台机器上知道哪些请求会到达这台机器。例如,您可以将 DNS 配置为发送 www.domain1.comwww.domain2.com 到这台从您的角度看起来像 localhost 的机器。所以在请求进来之前你不能知道“域”。

    但是,您的机器确实有一个本地机器名称,您可以从 settings.py 中找出它。不同的操作系统执行此操作的方式不同,但在 Mac 上,您可以使用 scutil --get LocalHostName 获取它,而在其他 Unix 上,您可以使用 cat /etc/hostname

    Chris Curvey 说得对,区分环境的规范方法是使用不同的设置文件。大多数开发人员会区分本地环境和生产环境,但您提出了第三种:没有互联网访问的本地环境。

    完成这项工作有 2 个步骤。

    检测何时使用“本地无互联网”环境。

    执行此操作的常用方法(也是最简单的方法,IMO)是使用环境变量。有很多方法可以做到这一点。例如,您可以在环境中设置 LOCAL_NO_INTERNET=True,然后在您需要在代码中执行一些特殊操作时检查该变量。

    如果你真的需要自动检测,你可以:

    1. 查询本地机器的名称(机器名称,而不是域,如上所述)
    2. 检查名称是否与您的本地开发机器匹配(这样您就不会在 prod 等中执行此操作)
    3. 检查您是否没有互联网(ping google.com 或其他东西,看看它是否成功返回或超时)

    我不推荐这种方法;有很多边缘情况。另外,您可能可以自己确定是否要处于“没有互联网的本地”环境并手动设置环境变量。

    提供通常由 CDN 提供的缓存文件

    我认为最简单的方法,虽然有点冗长,是在你的模板中放置一个 if 语句来定位 CDN 或你的本地版本(注意你必须在上下文中传递 LOCAL_NO_INTERNET查看):

    {% if LOCAL_NO_INTERNET %}
      <script src="{% static "cdncache/bootstrap.min.js" %}"></script>
    {% else %}
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="..." crossorigin="anonymous"></script>
    {% endif %}
    

    或者你可以在这里做一些更复杂的事情,比如中间件,以某种方式替换对 CDN 的引用。

    我建议不要定义这个新的“没有互联网的本地”环境,而是可以将本地设置更改为始终假设“没有互联网的本地”。 CDN 应该加快生产中的请求,但与始终使用您自己的文件版本相比,在本地开发中并没有多大好处。

    【讨论】:

      【解决方案2】:

      我从来没有找到找到有关 Django 侦听器详细信息的方法。

      在不同环境下进行不同设置的规范方法是拥有不同的设置文件,然后设置 DJANGO_SETTINGS_MODULE 环境变量来控制使用哪一个。

      【讨论】:

      • 即使使用单独的文件,您将如何动态访问域? sys.args 有端口,但没有域...
      • 对不起,我不清楚。如果您希望系统在开发中以一种方式运行(从 localhost 提供静态文件),您可以设置一个以这种方式配置的 dev_settings.py。如果您希望它在生产中有所不同,您可以设置一个不同的设置文件并在生产中使用它。
      • 是的。这就是我目前正在做的事情。但在开发的情况下,当互联网不工作时,我希望能够提供静态版本的 CDN 库。但我不能像在模板中那样只调用{% static "path to file" %},因为我不在模板中。我无法使用应用程序,因为未加载应用程序。并且请求尚未生成,因此我无权访问 SITE 信息或其他带有端口的主机名。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      • 2022-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多