如何为Django设置Jupyter/IPython Notebook?

93

我一直在使用这篇文章中描述的方法来设置IPython Notebook与Django的兼容性。该方法的核心是创建一个IPython扩展程序,该扩展程序在IPython启动时设置DJANGO_SETTINGS_MODULE并运行django.setup()。

扩展程序的代码如下:

def load_ipython_extension(ipython):
    # The `ipython` argument is the currently active `InteractiveShell`
    # instance, which can be used in any way. This allows you to register
    # new magics or aliases, for example.
    try:
        import os
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
        import django
        django.setup()
    except ImportError:
        pass

我的Jupyter Notebook最近进行了升级,导致之前的设置不再可用。我能够通过在笔记本的第一个单元格中添加类似的代码来运行Jupyter笔记本中的Django代码。然而,我无法找到自动运行Jupyter扩展的方法,这样每次创建新的笔记本时都需要重新添加代码。

我该怎么做才能让Django和Jupyter协作顺畅?

更新:对于@DarkLight - 我正在使用Django 1.8.5和Jupyter 1.0.0。我在笔记本中运行的代码是:

import os, sys
sys.path.insert(0, '/path/to/project')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settingsfile")
import django
django.setup()

你解决了这个问题吗?Django shell_plus --notebook 对我不起作用,显示应用程序未加载的错误。 - Dark Light
@DarkLight - 我最终是通过一个脚本来运行命令的,我将其添加到每个新笔记本的第一个单元格中。虽然不太美观,但它能正常工作。 - odedbd
你能告诉我你正在使用的 Django、IPython 和 Jupyter 的版本,以及你正在使用的代码(如果与答案中的不同)吗?因为对我来说,django.setup() 调用只会导致 IPython 卡住。 - Dark Light
当我在设置文件中将DEBUG=False时,它终于可以工作了。你有什么想法是什么问题吗? - Dark Light
@DarkLight 我不知道 debug=False 是什么意思。我在我的开发环境中使用了 debug=True,没有遇到任何问题。我会很快更新问题并提供你所要求的信息。 - odedbd
9个回答

77
  1. https://github.com/django-extensions/django-extensions/blob/master/docs/index.rst安装django-extensions

 pip install django-extensions
  • 将您的设置文件更改以包含“django-extensions”

  •  INSTALLED_APPS += ['django_extensions']
    
  • 像这样运行您的Django服务器:

  • python manage.py shell_plus --notebook
    
  • 更改适合您的设置,并在您的第一个单元中运行此代码

  • import os, sys
    PWD = os.getenv('PWD')
    os.chdir(PWD)
    sys.path.insert(0, os.getenv('PWD'))
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "local_settings.py")
    import django
    django.setup()
    
  • 现在你应该能够导入你的Django模型等,例如:

  • from app.models import Foobar
    Foobar.objects.all()
    

    5
    即使您使用“Django Shell-Plus”内核创建笔记本,如果没有第四点,它也可以正常工作。 - igo
    3
    重要的是,它有一些依赖项:ipythonjupyter。您可以通过以下命令安装它们:pip install ipythonpip install jupyter - shourav
    如果您正在使用 django-configurations,请确保正确使用以下内容:https://django-configurations.readthedocs.io/en/latest/cookbook/#ipython-notebooks - blueFast
    在我的情况下,如果没有第4点,它就无法正常工作。我还建议使用替代的第5点。可以添加一个单元格,然后从python manage.py runserver中复制粘贴这些导入语句,而不是导入模型。然后他们就可以在不手动导入的情况下使用模型了。 - Ajeeb.K.P
    我能够完成第三步,但是在浏览器中打开的笔记本无法连接内核,并显示连接失败错误。您能帮忙吗?@igo - Eternal

    32

    为了完整起见(但现在是2018年,所以自提问发布以来可能已经有所改变):您实际上可以在Django环境中安装Jupyter Python内核,然后连接(在)不同的Jupyter服务器/环境下运行(其中您安装了小部件、扩展、更改主题等)。目前,django_extensions仍然只完成所需工作的一部分:-)

    这假设您拥有一个与Django独立的Jupyter虚拟环境,并且其内核/扩展是使用--user安装的。所有的Jupyter扩展及其依赖项均安装在此venv中,而不是Django环境中的venv(如果您需要在Django代码中与之一起使用,仍需要使用pandas、matplotlib等Django环境)。

    在您的Django虚拟环境中(可以运行不同版本的Python,包括版本2解释器),安装ipython kernel:

    pip install -U ipykernel
    ipython kernel install --user --name='environment_name' --display-name='Your Project'
    

    这将在您的用户Jupyter内核目录中创建一个具有指定名称的内核配置目录(在Linux上它是~/.local/share/jupyter/kernels/,而在OSX上它是~/Library/Jupyter/kernels)。该目录包含内核的kernel.json文件和图像/图标(默认情况下使用正在安装的内核的默认Jupyter图标)。该内核将在创建时处于活动状态的虚拟环境中运行,因此使用与我们的Django项目使用的完全相同版本的Python和所有已安装模块。

    运行./manage.py shell_plus --notebook执行的操作非常相似,但除了要求当前虚拟环境中安装了所有内容(包括Jupyter服务器和所有扩展程序)之外,还无法在不同于项目根目录(包含./manage.py)的目录中运行笔记本。此外,它将使用路径中找到的第一个可执行文件名为python的程序来运行内核,而不是虚拟环境的程序,这可能导致在未在活动的Django虚拟环境内从命令行启动时出现问题。

    为了解决这些问题,以便我们能够在任何已配置的Django项目中创建运行的笔记本,并能够在文件系统上的任何位置运行笔记本,我们需要:

    1. 确保第一个“argv”参数包含虚拟环境中包含的Python解释器的完整路径
    2. 添加(如果尚未存在)一个“env”部分,其中将包含Shell环境变量,然后使用这些变量告诉Python在何处找到我们的项目以及应该使用哪些Django设置。我们可以添加如下内容:
       "env": {
          "DJANGO_SETTINGS_MODULE": "my_project.settings",
          "PYTHONPATH": "$PYTHONPATH:/home/projectuser/projectfolder/my_project"
       }
    
    1. 可选:将"display_name"更改为易于理解的人类友好形式,并替换图标。

    编辑此环境kernel.json文件,您将看到类似以下内容:

    {
     "display_name": "My Project", 
     "language": "python", 
     "env": {
      "DJANGO_SETTINGS_MODULE": "my_project.settings",
      "PYTHONPATH": "$PYTHONPATH:/home/projectuser/projectfolder/my_project"
     },
     "argv": [
      "/home/projectuser/.pyenv/versions/2.7.15/envs/my_project_venv/bin/python", 
      "-m", 
      "ipykernel_launcher", 
      "-f", 
      "{connection_file}",
      "--ext",
      "django_extensions.management.notebook_extension"
     ]
    }
    

    值得注意的行:

    • "DJANGO_SETTINGS_MODULE": "my_project.settings":您的设置,通常可以在项目的manage.py文件中看到

    • "PYTHONPATH": "$PYTHONPATH:/home/projectuser/projectfolder/my_project":PYTHONPATH被扩展以包括您的项目的主目录(包含manage.py的目录),因此即使内核没有在该目录中运行,也可以找到设置(这里django_extensions将使用一个通用的python,因此除非整个Jupyter服务器从其中启动:将其添加到django_extensions创建的kernel.json中将使它能够在Django项目目录中的任何位置运行笔记本)

    • "/home/projectuser/.pyenv/versions/2.7.15/envs/my_project_venv/bin/python":内核执行的第一个参数(argv列表),应该是项目虚拟环境的Python解释器的完整路径(这是django_extensions弄错的另一件事:修复这将允许任何笔记本服务器以特定的Django环境的内核运行其所有已安装的模块)

    • "django_extensions.management.notebook_extension":这是将在笔记本中加载“shell_plus”功能的扩展名(可选但有用 :-))


    1
    太棒了!谢谢!那绝对是最佳设置。如果不清楚,在Mac上找到/Library/Jupyter/{your-kernel-name}/下的kernel.json,类似地,在Linux中找到/.jupyter/。 - fjsj
    PYTHONPATH不应该与manage.py相同吗?通常是“/home/user/devel/my_project”而不是“...my_project/myproject”吧? - Tin Ng
    @NguyễnTrọngTín 是的,但这取决于您如何构建项目...我们有一个双 project_name 文件夹,位于 Django 的上方,用于包含与 Django 无关的内容。我同意这很令人困惑,我会尝试编辑示例。 - RobM
    1
    完美的技巧! 为了避免出现消息:“Django:SynchronousOnlyOperation:您无法从异步上下文中调用此操作 - 使用线程或sync_to_async”,在django.setup()之前,以下是要添加到ipynb文件开头的内容: os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" https://dev59.com/2FIG5IYBdhLWcg3w_nJR - openHBP

    25

    以下是对我刚刚成功的操作的描述:

    1. 按照其他答案所说,安装 Django Extensions(我使用了1.9.6版本)
    2. 安装 jupyter
      pip install jupyter
    3. 如果需要在 Docker 容器内设置 jupyter,请根据下面的说明进行操作†
    4. 在您的 Django 基础目录中,创建一个用于存放笔记本的目录,例如
      mkdir notebooks
    5. 进入该目录
      cd notebooks
    6. 从该目录内部启动 django extensions shell_plus:
      ../manage.py shell_plus --notebook
      此时笔记本服务器应该已经运行,并可能会打开一个新的浏览器窗口。如果没有打开浏览器窗口,请按照说明粘贴链接或令牌。
    7. 从浏览器中打开一个新的“Django Shell Plus”笔记本,如 John Mee 的回答中的截图所示

    而且,重要的是,尝试从笔记本环境内部更改目录并不管用。如果我尝试使用任何不在 manage.py shell_plus --notebook 运行的目录中的笔记本,那么内核就无法正确配置。对我来说,将笔记本配置为一次只能使用单个目录就足够了。如果您需要更强大的解决方案,您应该在启动 jupyter 之前设置 PYTHONPATH。例如,在虚拟环境激活脚本中添加export PYTHONPATH="$PYTHONPATH:/path/to/django/project"。但是我没有尝试过这样做。

    † Docker 设置(可选)

    1. 为容器添加一个端口映射以映射到端口8888

    例如,在您的 docker-compose 文件中:

    ports:
          -  "8890:8888"
    
    1. 配置您的项目设置文件以使用IP 0.0.0.0。

    这是我所做的:

    NOTEBOOK_ARGUMENTS = [
        '--ip', '0.0.0.0', 
        '--allow-root',
        '--no-browser', 
    ]
    

    当你使用cd命令进入“notebooks”目录时,你是否在该目录中有一个“manage.py”文件,或者你是如何从那里运行它的? - yofee
    我必须将manage.py添加到我的PATY中--也许尝试使用django-admin.py。 - Mark Chackerian
    尝试运行../manage.py shell_plus --notebook,注意../。在Django 2.1下可以正常工作。 - Marc
    1
    NOTEBOOK_ARGUMENTS 部分对我来说非常关键,谢谢! - Ken Fehling

    17

    注意: 我正在使用Python 3.7和Django 2.1,此方法适用于Django 2.2。只要你不介意将笔记本放在Django项目的根目录下,那么在第一个单元格中无需运行任何内容即可完美运作。

    假设您的项目已经创建了虚拟环境并已激活。我使用pipenv创建Python项目的虚拟环境并跟踪依赖项,但您可以选择自己熟悉的工具。

    同时,我们也假设项目是基于Django创建的,而当前工作目录是该项目的根目录

    步骤

    1. Install jupyter

      Using pip

      pip install jupyter
      

      Using pipenv

      pipenv install jupyter
      
    2. Install django-extentions

      Using pip

      pip install django-extensions
      

      Using pipenv

      pipenv install django-extensions
      
    3. Set up django-extensions by adding it to the INSTALLED_APPS setting of your Django project settings.py file.:

      INSTALLED_APPS = (
          ...
          'django_extensions',
      )
      
    4. Run the shell_plus management command that is part of django-extensions. Use the option --notebook to start a notebook:

      python manage.py shell_plus --notebook
      

      Jupyter Notebooks will open automatically in your browser.

    5. Start a new Django Shell-Plus notebook

    这里输入图片描述

    就是这样了!


    同样的,你不必在第一个单元格中运行任何内容,并且可以通过运行dir()来查看当前本地范围中的名称进行协作。

    这里输入图片描述

    编辑:

    如果您想将笔记本放在名为notebooks的目录中,请执行以下操作:

    $ mkdir notebooks && cd notebooks
    $ python ../manage.py shell_plus --notebook
    

    感谢马克·查克里安的回答提供了在项目根目录以外运行笔记本的想法。

    以下是由shell_plus自动导入的模块:

    # Shell Plus Model Imports
    from django.contrib.admin.models import LogEntry
    from django.contrib.auth.models import Group, Permission, User
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.sessions.models import Session
    # Shell Plus Django Imports
    from django.core.cache import cache
    from django.conf import settings
    from django.contrib.auth import get_user_model
    from django.db import transaction
    from django.db.models import Avg, Case, Count, F, Max, Min, Prefetch, Q, Sum, When, Exists, OuterRef, Subquery
    from django.utils import timezone
    from django.urls import reverse
    

    1
    我将我的笔记本放在一个应用程序的目录中,并从根目录运行 python manage.py shell_plus --notebook,导致出现错误 myproject module not found,笔记本无法正常工作。按照建议,我从目录 python ../../manage.py shell_plus --notebook 运行笔记本,现在一切都正常了 - 谢谢!@Imiguelvargasf - Javed

    10

    事实证明,你(可能不)需要做所有那些琐碎的事情。只需安装django-extensions并运行jupyter!

    (myprojectvenv)$ cd myproject    
    (myprojectvenv)$ pip install jupyter
    (myprojectvenv)$ pip install django-extensions
    (myprojectvenv)$ jupyter notebook
    
    在浏览器中,启动一个新的"Django Shell-Plus": enter image description here 然后你就可以开始了。例如:
    from myproject.models import Foobar
    Foobar.objects.all()
    

    2
    确保您的虚拟环境中也安装了Jupyter:pip install jupyter - aboutaaron
    5
    事实上,你确实需要做所有这些麻烦的事情。你的方法在一个干净的环境下无法运行。你可能有其他假设和/或状态,这些都没有在你简单回答中表达出来。 - rob3c
    3
    第一次我尝试这个方法时它起作用了,但第二次却没有起作用(!?)。后来发现,起作用和不起作用的区别在于笔记本文件的路径。因此,如果您想将笔记本文件保留在项目的顶层目录中,那么这个答案可能是可行的——这是先前评论的“假设”。 - Mark Chackerian

    4

    尽管 RobM 给出的答案可行,但它比实际需要更加复杂,并且有一些不必要的步骤。简单来说,要在 Django 中运行笔记本 从项目目录之外的笔记本环境

    安装:

     pip install django-extensions
    

    settings.py文件的INSTALLED_APPS列表中添加'django-extensions'
     INSTALLED_APPS += ['django_extensions']
    

    在Django中运行笔记本,然后关闭它:

    python manage.py shell_plus --notebook
    

    这将创建您的内核,我们现在将编辑它,将其指向Python的绝对路径,而不是相对路径。

    在OSX上,内核文件位于:~/Library/Jupyter/kernels/django_extensions/kernel.json

    在Linux上: ~/.jupyter/kernels/django_extensions/kernel.json

    我们只需要进行两个更改:

    第一个是将"argv"列表中的第一个值从"python"编辑为Django虚拟环境中Python版本的完整地址。例如:"/Users/$USERNAME/Documents/PROJECT_FOLDER/venv/bin/python"

    其次,向"env"字典添加"DJANGO_SETTINGS_MODULE": "mysite.settings", 其中mysite是包含您的Django设置的文件夹。

    可选地,更改"display_name"的值。

    现在,当您从任何目录运行笔记本电脑时,选择"Django Shell-Plus"内核将允许您的笔记本电脑与Django交互。任何包(如pandas)都需要安装在Django venv中。


    3
    以下内容对我来说可行,使用的是Win10操作系统,Python3.5版本和Django1.10框架:
    • Install Python with the Anaconda distribution so Jupyter will be installed as well
    • Install Django and install django-extensions:

      pip install Django
      
      pip install django-extensions
      
    • Start a new Django project. You have to do that in that part of your tree of directories which can be accessed by Jupyter later.

      django-admin startproject _myDjangoProject_
      
    • Start Jypter

    • navigate Jupyter to the directory myDjangoProject and enter the first/top myDjangoProject-directory
    • Start within the first/top myDjangoProject-directory a new Jupyter noteboke: new --> Django Shell-Plus
    • enter and run the following piece of code :

      import os
      os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myDjangoProject.settings")
      import django
      django.setup()
      
    • Note that this piece of code is the same as in manage.py, and note that "myDjangoProject.settings" points to myDjangoProject/settings.py

    • Now you can start with examples, e.g.:

      from django.template import Template, Context
      
      template = Template('The name of this project is {{ projectName }}')
      context = Context({'projectName': 'MyJypyterDjangoSite'})
      template.render(context)
      

    1
    运行此命令。
    PYTHONPATH=/path/to/project/root DJANGO_SETTINGS_MODULE=settings python manage.py shell_plus --notebook
    

    0

    我将为RobM的非常完整的答案添加一些信息,以便像我一样使用buildout和djangorecipe djangorecipe的极少数开发人员受益... 我使用jupyter lab,但我认为所有信息都可以应用于旧版jupyter笔记本。

    在使用buildout时,您最终会得到一个'bin/django'处理程序,您将使用它来代替'manage.py'。那是定义整个路径的脚本。我在我的buildout.cfg中添加了一个部分:

    [ipython]
    recipe = zc.recipe.egg
    eggs =  ${buildout:eggs}
    extra-paths = ${buildout:directory}/apps
    initialization =  import os
       os.environ['DJANGO_SETTINGS_MODULE'] = 'web.settings'
    

    这样,将会在./bin目录下创建另一个名为ipython的脚本。我将kernelspec指向该解释器。此外,我使用kernel参数而不是"-m", "ipykernel_launcher",以便我使用的内核定义为:

    {
        "argv": [
            "/misc/src/hg/siti/trepalchi/bin/ipython",
            "kernel",
            "-f",
            "{connection_file}",
            "--ext",
            "django_extensions.management.notebook_extension"
        ],
        "display_name": "Trepalchi",
        "language": "python"
    }
    

    由于buildout创建了ipython脚本,因此在我的情况下不需要添加环境变量。
    正如Rob已经提到的,jupiterlab只安装在一个环境中,我可以通过以下命令启动它:
    jupyter lab
    

    我不在Django项目的环境中,我只安装了ipykernel(已经有20个依赖项)。

    由于我倾向于有很多项目,因此我发现有一个单一的起点非常有用,可以使用许多链接启动jupyter lab,以便我可以轻松地访问它们。由于django_extension提供的扩展,我不需要任何额外的单元格来初始化笔记本。

    以这种方式添加的任何单个内核都可以通过命令找到:

    jupyter kernelspec list
    

    并且在Jupyter Lab的启动器中清晰列出


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接