在使用Azure的App Service运行Django时可能遇到的问题
使用之前的帖子“尝试使用tabulator进行数据库更新(Python版)”和“通过Azure ML Studio和Flask协作的Web应用程序示例”,其中使用了Flask,但在这个10天的假期里我尝试了使用Django。
鉴于Django是一个全栈框架,有许多文件需要正确配置才能正常运行,因此我将报告我在其中遇到的主要问题。
但是
※07/02 15:00 由于将机器学习程序更改为Django环境,我们已更改了链接目标。
安装步骤
参照Django Girls教程,在本地电脑上创建一个Django应用程序。
在Azure的Webapps中,除了创建一个Flask服务器,还创建了一个单独的Python服务器。
在Web应用程序中,Python环境被保存在固定的区域中,无法添加库。因此,您可以通过Web应用程序控制面板中的”开发工具”->”扩展功能”->”添加”来添加Python 3.6.4 x86版本。
4. Django的库添加可以通过webapps仪表盘的“控制台”进行。进入控制台后,切换目录,然后更新pip(如果已有旧版本),最后安装Django。
cd \home\python364x86
d:\home\python364x86>python -m pip install --upgrade pip
d:\home\python364x86>pip install Django
用FTP将在本地创建的文件上传。
【躓きポイント1】由于没有正确指定每个文件而导致错误的解决方法让我困惑不已。
如果按照Django Girls的参考,本地创建的Django文件夹结构应该如下所示。如果要上传,则可以在“wwwroot”下创建“djangogirls”文件夹,也可以在“wwwroot”下直接放置文件夹和文件,只要进行相应的正确配置即可。然而,我对相关的理解还不够深入,因此遇到了一些困难。
特别是,如果错误地指定了settings.py中的INSTALLED_APPS = [(指定应用程序)],将会出现“RuntimeError: populate() isn’t reentrant”错误,并且很难注意到指定有误的情况。
(1)WebサーバからはWsgiインターフェースを通じてweb.configで指定しているスクリプトエンジンと
設定ファイルsettings.pyをもとに起動する。ローカル起動の場合(python manage.py runserver)は
manage.pyの中で指定しているsettings.pyをもとに起動する。
(2)settings.pyの中でurl.pyを指定。ほかにINSTALLED_APPSでアプリ、
TEMPLATES、STATICの設定でそれぞれファイルを指定する。
djangogirlsフォルダ
├── blogフォルダ
│ ├──templatesフォルダ
│ │ test.html(5)
│ ├── url.py(3’)どのviewを呼ぶか設定。
│ └── views_test.py(4)プログラムに相当、処理を行い結果をどのテンプレートに渡すか記述。
├── db.sqlite3
├── manage.py
└── mysiteフォルダ
├── settings.py
├── urls.py(3)要求されたurlの遷移を司る。アプリのurl(3’)へリダイレクトしたり、ここでどのviewを呼ぶか設定しても良い。
└── wsgi.py
醬料
<!-- コメントは説明の為です。実ファイルにあるとエラーになります。 -->
<configuration>
<appSettings>
<add key="pythonpath" value="D:\home\site\wwwroot" /> <!-- ここが起点で以降ここからの
相対ディレクトリとなります。wwwrootの下にdjangogirlsを設けたような場合、
D:\home\site\wwwroot.djangogirlsとすれば以降の設定でdjangogirlsを略す事ができます。 -->
<configuration>
<add key="WSGI_HANDLER" value="django.core.wsgi.get_wsgi_application()" />
<add key="DJANGO_SETTINGS_MODULE" value="mysite.settings" /> <!-- どのsettings.pyを読むか定義。 -->
<add key="WSGI_LOG" value="D:\home\site\wwwroot\LogFiles\wfastcgi.log"/> <!-- wfastcgiのログを出力。LogFilesフォルダは予め作成。-->
</appSettings>
<system.webServer>
<handlers>
<remove name="Python34_via_FastCGI" /> <!--静的ファイルがAzureデフォルトのPython34で処理しようとしてエラーになるのを回避します。 -->
<add name="Python FastCGI"
path="handler.fcgi"
verb="*"
modules="FastCgiModule"
scriptProcessor="D:\home\python364x86\python.exe|D:\home\python364x86\wfastcgi.py"
resourceType="Unspecified"
requireAccess="Script" />
</handlers>
<rewrite>
<rules>
<rule name="Static Files" stopProcessing="true">
<conditions>
<add input="true" pattern="false" />
</conditions>
</rule>
<rule name="Configure Python" stopProcessing="true">
<match url="(.*)" ignoreCase="false" />
<conditions>
<add input="{REQUEST_URI}" pattern="^/static/.*" ignoreCase="true" negate="true" />
</conditions>
<action type="Rewrite" url="handler.fcgi/{R:1}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"></httpErrors>
<!-- エラーをhtmlに出力。内容はLogFilesと同じ。-->
</system.webServer>
</configuration>
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = 'am$+th5ttev9oa$77w9428jl*2bd-&fpvcy(dkigg99beg(kjh'
DEBUG = True
# 許可するサーバは自分のサーバ名に修正
ALLOWED_HOSTS = ['dja-vin.azurewebsites.net']
# 作成したアプリを追加
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# ルートとして使用するコントローラ。デフォルトで生成されたものをそのまま利用。
ROOT_URLCONF = 'mysite.urls'
# CSSなどの静的ファイルの置き場所の設定
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
# テンプレートの置き場所の設定
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'mysite.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
from django.contrib import admin
from django.urls import path
from mysite import views
from blog import views_test
urlpatterns = [
path('', views.index, name='index'),
path('test/', views_test.index, name='index'),
path('admin/', admin.site.urls),
]
from django.shortcuts import render
from django.utils import timezone
from .models import Post
from django.http import HttpResponse
def index(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
param_value = request.GET.get("text1")
params = {
'msg' : param_value,
'posts' : posts
}
return render(request, 'blog/test.html', params)
{% extends "../base.html" %}
{% block body %}
{% load staticfiles %} <!-- Instruct Django to load static files -->
<link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
<div>
<h2>blogデータ表示</h2>
</div>
<span class="message">入力された値:{{ msg }}</span>
{% for post in posts %}
<div>
<p>----------------------------------------------</p>
<h2>表題: {{ post.title }}</h2>
<p>発行日: {{ post.published_date }}</p>
<p>内容:{{ post.text|linebreaksbr }}</p>
</div>
{% endfor %}
{% endblock %}
为了加载诸如CSS等静态文件,需要在web.config文件中进行设置
尽管在 settings.py 中进行了有关静态文件的设置,但无法加载 CSS。但是我在这里找到了解决方法。在 web.config 中添加 “handlers remove name=”Python34_via_FastCGI”” 的设置。否则,默认的 Azure python34\Scripts 将处理,从而导致 “Error occurred while reading WSGI handler” 错误,通过浏览器的 F12 调试可以看到。此外,为了 admin 程序的 CSS 样式,将 \site-packages\django\contrib\admin\static 文件夹复制到在 wwwroot 下创建的 static 文件夹中。
【关于在Azure上进行调试】
如果在本地服务器上运行,会通过`print`在命令行窗口显示,但在Azure上,我不知道它会被输出到哪里。因此,我使用以下的文件输出进行调试。
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
msg = "STATIC_ROOT = " + STATIC_ROOT #例えば上記行の内容を確認したい。
errlog = open('LogFiles/err.log','a')
errlog.write( msg + '\n')
errlog.close()
Django相对于Flask来说,自动生成用户管理和表格维护界面等功能确实很方便,但有点慢。它们都依赖于Web服务器的wsgi接口,对于可靠性和多重性都没有差异,所以我觉得可以根据应用的规模来选择使用哪个。