Pycharm:为运行manage.py任务设置环境变量

时间:2014-02-03 22:07:26

标签: python django pycharm

我已将SECRET_KEY值移出我的设置文件,并在我加载virtualenv时设置它。我可以确认该值来自python manage.py shell

当我运行Django控制台时,SECRET_KEY缺失,应该是这样。因此,在首选项中,我转到控制台> Django控制台并加载SECRET_KEY和相应的值。我回到Django控制台,SECRET_KEY就在那里。

正如预期的那样,我还没有运行manage.py任务,因为它还没有找到SECRET_KEY。所以我进入Run>编辑配置,将SECRET_KEY添加到Django服务器和Django测试中,并添加到项目服务器中。重新启动Pycharm,确认密钥。

当我运行manage.py任务时,例如runserver,我仍然得到KeyError: 'SECRET_KEY'.

我把这把钥匙放在哪里?

16 个答案:

答案 0 :(得分:41)

由于Pycharm未从终端启动,因此不会加载您的环境。简而言之,任何GUI程序都不会继承SHELL变量。请参阅this了解原因(假设是Mac)。

但是,这个问题有几个基本的解决方案。当@user3228589发布时,您可以将其设置为PyCharm中的变量。这有几个优点和缺点。我个人不喜欢这种方法,因为它不是single source。为了解决这个问题,我在settings.py文件的顶部使用了一个小函数,它在本地.env文件中查找变量。我把所有的“私人”东西放在那里。我也可以在我的virtualenv中引用它。

这就是它的样子。

- settings.py

def get_env_variable(var_name, default=False):
    """
    Get the environment variable or return exception
    :param var_name: Environment Variable to lookup
    """
    try:
        return os.environ[var_name]
    except KeyError:
        import StringIO
        import ConfigParser
        env_file = os.environ.get('PROJECT_ENV_FILE', SITE_ROOT + "/.env")
        try:
            config = StringIO.StringIO()
            config.write("[DATA]\n")
            config.write(open(env_file).read())
            config.seek(0, os.SEEK_SET)
            cp = ConfigParser.ConfigParser()
            cp.readfp(config)
            value = dict(cp.items('DATA'))[var_name.lower()]
            if value.startswith('"') and value.endswith('"'):
                value = value[1:-1]
            elif value.startswith("'") and value.endswith("'"):
                value = value[1:-1]
            os.environ.setdefault(var_name, value)
            return value
        except (KeyError, IOError):
            if default is not False:
                return default
            from django.core.exceptions import ImproperlyConfigured
            error_msg = "Either set the env variable '{var}' or place it in your " \
                        "{env_file} file as '{var} = VALUE'"
            raise ImproperlyConfigured(error_msg.format(var=var_name, env_file=env_file))

# Make this unique, and don't share it with anybody.
SECRET_KEY = get_env_variable('SECRET_KEY')

然后env文件如下所示:

#!/bin/sh
#
# This should normally be placed in the ${SITE_ROOT}/.env
#
# DEPLOYMENT DO NOT MODIFY THESE..
SECRET_KEY='XXXSECRETKEY'

最后你的virtualenv / bin / postactivate可以获取此文件。如果您愿意,可以按照here所述进一步导出变量,但由于设置文件直接调用.env,因此根本不需要。

答案 1 :(得分:24)

要在PyCharm中设置环境变量,请执行以下操作:

  • 打开'文件'菜单
  • 点击'设置'
  • 点击' +'在'控制台'
  • 旁边签名
  • 点击Python控制台
  • 点击' ...'环境变量旁边的按钮
  • 点击' +'添加环境变量

答案 2 :(得分:14)

同样,由于某些原因,PyCharm无法看到导出的env变种。 现在我在PyCharm运行/调试配置中设置SECRET_KEY - > “环境变量”

答案 3 :(得分:12)

另一个对我有用的选择:

  1. 打开终端
  2. 激活项目的virtualenv,这将导致钩子运行并设置环境变量
  3. 从此命令行启动PyCharm。
  4. 然后,Pycharm将可以访问环境变量。可能是因为与PyCharm进程有关的事情是shell的一个孩子。

答案 4 :(得分:11)

您可以通过以下方式设置manage.py任务环境变量:

偏好|语言与;框架| Django的| Manage.py任务

通过run / debug / console配置设置env vars不会影响内置pycharm的manage.py任务。

答案 5 :(得分:7)

在Pycharm中manage.py任务在一个孤立的进程中运行,该进程无法访问您的环境变量(与Run / Debug不同)。

最简单的解决方案是通过直接从.env文件中读取它们,使您的python代码了解环境变量。

看看:https://github.com/joke2k/django-environ

import environ

env = environ.Env.read_env() # reading .env file

SECRET_KEY = env('SECRET_KEY')

这样,您就拥有了单一的配置源,并且IDE中的设置更少。

希望有所帮助,

答案 6 :(得分:2)

要解释@antero-ortiz's答案,您可以直接从终端启动,而不是使用默认的Mac双击或聚光灯搜索来启动PyCharm。这将从终端会话继承到PyCharm应用程序的所有环境变量。

以下是我如何解决这个问题。

  1. 在终端程序中,运行下面的代码段。
  2. 按照Edit your Run/Debug Configurations的说明验证事情是否有效,
    1. 点击...
    2. 旁边的Environment variables
    3. 然后点击弹出屏幕右下方的Show。这将显示Debug进程继承的所有环境变量。
    4. 在此列表中找到您的SECRET_KEY。如果不存在,请对此答案发表评论,我们可以尝试解决这个问题!
  3. 每次启动时,您可能需要以这种方式启动PyCharm。
  4. 段:

    # This file would presumably export SECRET_KEY
    source /path/to/env/file
    # This is just a shortcut to finding out where you installed PyCharm
    # If you used brew cask, it's probably in /opt/homebrew-cask/Caskroom/pycharm
    open $(locate PyCharm.app | egrep 'PyCharm.app$')
    

    旁注

    将环境变量包含在source的文件中是dango开发的常见模式,最佳实践的讨论最好不在答案中。

答案 7 :(得分:1)

基于@ rh0dium的惊人答案我已经完成了这个课程:

这是我的settings.py:

import os


class EnvironmentSettings():
    """Access to environment variables via system os or .env file for development

    """
    def __init__(self, root_folder_path):
        self._root_folder_path = root_folder_path

    def __getitem__(self, key):
        return self._get_env_variable(key)

    def __setitem__(self, key, value):
        raise InvalidOperationException('Environment Settings are read-only')

    def __delitem__(self, key):
        raise InvalidOperationException('Environment Settings are read-only')

    def _get_env_variable(self, var_name, default=False):
        """
        Get the environment variable or return exception
        :param var_name: Environment Variable to lookup
        """
        try:
            return os.environ[var_name]
        except KeyError:
            from io import StringIO
            from configparser import ConfigParser

            env_file = os.environ.get('PROJECT_ENV_FILE', self._root_folder_path + "/.env")
            try:
                config = StringIO()
                config.write("[DATA]\n")
                config.write(open(env_file).read())
                config.seek(0, os.SEEK_SET)
                cp = ConfigParser()
                cp.readfp(config)
                value = dict(cp.items('DATA'))[var_name.lower()]
                if value.startswith('"') and value.endswith('"'):
                    value = value[1:-1]
                elif value.startswith("'") and value.endswith("'"):
                    value = value[1:-1]
                os.environ.setdefault(var_name, value)
                return value
            except (KeyError, IOError):
                if default is not False:
                    return default
                error_msg = "Either set the env variable '{var}' or place it in your " \
                            "{env_file} file as '{var} = VALUE'"
                raise ConfigurationError(error_msg.format(var=var_name, env_file=env_file))


class ConfigurationError(Exception):
    pass


class InvalidOperationException(Exception):
    pass

在我的runserver.py里面我有这个调用代码:

from settings import EnvironmentSettings

root_folder_path = os.path.dirname(os.path.abspath(__file__))
env_settings = EnvironmentSettings(root_folder_path)
config_name = env_settings['APP_SETTINGS']

答案 8 :(得分:1)

在PyCharm 2018中,您可以在设置中使用django manage.py环境变量选项

  • 文件
  • 设置
  • 语言和框架
  • Django
  • 环境变量

You can see in image

答案 9 :(得分:0)

@(nu everest)的回答对我不起作用。无论你在问题中描述的是什么,对我有用。您可以在“运行/调试配置”对话框中设置所有环境变量。这是w.r.t PyCharm 2016.1以及https://www.jetbrains.com/help/pycharm/2016.1/run-debug-configuration-python.html?origin=old_help

答案 10 :(得分:0)

我正在尝试此设置。我的项目根目录中有一个env.local文件。我的manage.py看起来像这样:

#!/usr/bin/env python
import os
import sys


if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")

    # Load environment variables from env.local, if option --load-env specified.
    # Good for injecting environment into PyCharm run configurations for example and no need to
    # manually load the env values for manage.py commands
    if "--load-env" in sys.argv:
        with open("env.local") as envfile:
            for line in envfile:
                if line.strip():
                    setting = line.strip().split("=", maxsplit=1)
                    os.environ.setdefault(setting[0], setting[1])
        sys.argv.remove("--load-env")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

然后我只是在PyCharm运行对话框中传递--load-env,所有环境变量将在运行时加载。

答案 11 :(得分:0)

请注意,“nu everest”提到的答案有效,但除非您在pycharm中创建项目,否则您将看不到“控制台”选项卡。由于可以运行单个文件而无需在pycharm中创建项目,因此某些人可能会感到困惑。虽然您还需要注意,当pycharm关闭时,不属于项目的运行配置会丢失设置。

答案 12 :(得分:0)

这是我的manage.py文件,以防万一。它从位于项目根目录下的.env文件读取所有变量。

enter image description here

答案 13 :(得分:0)

我认为一种好的方法是使用django-environ,它允许您从.env文件中读取环境变量。

用法

首先,安装django-environ

pip install django-environ

第二,在.env文件的同一目录中创建一个settings.py文件。

$ cd project-settings-directory/
$ touch .env

第三,将要使用的环境变量添加到.env

# .env file
DEBUG=on
SECRET_KEY=your-secret-key
DATABASE_URL=psql://urser:un-githubbedpassword@127.0.0.1:8458/database
SQLITE_URL=sqlite:///my-local-sqlite.db

第四,在您的设置文件中,在导入语句之后添加以下内容:

# other import statements

import environ


# the followin line expects .env file to exist. Otherwise, an IOError exception will be raised.
env = environ.Env.read_env()

第五,加载环境变量:

DEBUG = env('DEBUG')
SECRET_KEY = env('SECRET_KEY')

就是这样。如果您需要更多有关的信息,请查看the docs

注意:该配置还可以帮助您从PyCharm运行服务器时设置环境变量。

答案 14 :(得分:0)

在PyCharm 2019+中,调试环境设置在其站点here中进行了描述。即使在PyCharm其他部分(控制台,终端等)中定义了环境变量,我也遇到了类似的问题

摘要:

  1. 您的Django项目名称所在的右上角(“运行”图标旁边),单击下拉箭头。

    i。注意:如果尚未为Django配置项目,则可能看不到它。不过,在下一个窗口中应该有可用的模板。

  2. “编辑配置...”

  3. 除了控制台设置外,您还将看到“环境变量”字段。如果您是通过PyCharm的调试器运行Django服务器,则实际上就是要使用的服务器。

答案 15 :(得分:0)

与Django一起使用PyCharm时,可以在多个部分中设置环境变量(EV):

  • File > Settings > Languages and Frameworks > Django
    • 没有在这里设置电动汽车的目的
  • File > Settings > Build, Execution, Deployment > Console > Python Console
    • 没有在这里设置电动汽车的目的
  • File > Settings > Build, Execution, Deployment > Console > Django Console
    • 在此处设置EV,使用PyCharm Python控制台(在Django项目中打开Django shell)时,它们将可以使用。
  • File > Settings > Tools > Terminal
    • 在此处设置电动汽车,使用PyCharm 终端(即在终端中运行python manage.py命令时)即可使用电动汽车
  • Run > Edit configurations > [Your Django run configuration]
    • 在此处设置电动汽车,使用PyCharm 运行按钮
    • 后即可使用

在PyCharm 2020.2上进行了测试,使用虚拟环境