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

问题描述 投票:35回答:14

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

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

正如所料,我还没有运行manage.py任务,因为它还没有找到SECRET_KEY。所以我进入Run> Edit Configurations将SECRET_KEY添加到Django服务器和Django Tests中,并进入项目服务器。重启Pycharm,确认密钥。

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

我在哪里放这把钥匙?

python django pycharm
14个回答
41
投票

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

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

这是它的样子。

-- settings.朋友

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,因此根本不需要。


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


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,所有环境变量将在运行时加载。


0
投票

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


0
投票

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

enter image description here


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:[email protected]:8458/database
SQLITE_URL=sqlite:///my-local-sqlite.db

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

# 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运行服务器时设置环境变量。


26
投票

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

  • 打开“文件”菜单
  • 点击“设置”
  • 点击“控制台”旁边的“+”号
  • 单击Python控制台
  • 单击环境变量旁边的“...”按钮
  • 单击“+”以添加环境变量

14
投票

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


12
投票

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

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

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


12
投票

另一个对我有用的选择:

  1. 打开一个终端
  2. 激活项目的virtualenv,这将导致钩子运行并设置环境变量
  3. 从此命令行启动PyCharm。

然后Pycharm可以访问环境变量。可能是因为与PyCharm进程有关的事情是shell的一个孩子。


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中的设置更少。

希望有所帮助,


2
投票

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

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

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

片段:

# 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$')

Side note

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


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']

1
投票

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

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

You can see in image

© www.soinside.com 2019 - 2024. All rights reserved.