使用Django和heroku搭建一個簡易網站
最近由於畢設的需要,想要做一個通過輸入各種引數,預測冷熱負荷的機器學習系統。可以在網頁上直接輸入房屋引數,預測出房屋所需冷熱負荷和能耗水平。
關於機器學習那塊相信網上已經有不少教程,這裡就不再贅述,本文主要總結一下Django和heroku搭配來建立網站。
Django
https://docs.djangoproject.com/zh-hans/2.1/contents/
這個tutorial真的內容很全有木有,不管是新手入門還是遇到的一些問題,大部分都能在官方的doc裡面得到解答。這也是我這一次學到的東西吧。
這個是根據tutorial建立起來的網站的檔案目錄。
mysite/ manage.py mysite/ __init__.py settings.py urls.py wsgi.py polls/ __init__.py admin.py migrations/ __init__.py 0001_initial.py models.py static/ polls/ images/ background.gif style.css templates/ polls/ detail.html index.html results.html tests.py urls.py views.py templates/ admin/ base_site.html
最頂層是mysite使我們的project,然後在這個project下面添加了一個app叫做polls。
在project下面又有一個資料夾叫mysite,裡面放了一些setting,urls的重要檔案。
url是指明Uniform Resource Locator的檔案,即各種資源的索引位置。
wsgi.py是方便之後部署的檔案。
在polls資料夾中,migration資料夾主要是負責資料庫的連線。
models檔案裡定義了一些類,是我們資料庫中會記錄的東西。
views是我們給訪問者呈現什麼資料,它和templates是搭配的。
templates資料夾裡,還有一個polls資料夾(雖然我自己後來建的時候放在polls資料夾中的html檔案總是找不到就不再加這個polls子檔案夾了,但是合理的情況是放在polls中的),存放著html格式的檔案,和views搭配負責頁面如何呈現。
需要學習一點html的知識
http://www.runoob.com/html/html-basic.html
其中在我自己的project裡面最重要的是表單,即使用者輸入資料然後表單通過request接收,views.py處理,return回去。
這是我views.py檔案的內容:
# -*- coding: utf-8 -*- from django.shortcuts import render, render_to_response from django.views.decorators import csrf import tensorflow as tf import numpy as np def add_layer(inputs, insize, outsize, n, activation_function=None): layer_name = 'layer%s' % n with tf.name_scope(layer_name): Weights = tf.Variable(tf.random_normal([insize, outsize]), name='w') tf.summary.histogram(layer_name + 'Weights', Weights) bias = tf.Variable(tf.zeros([1, outsize])) tf.summary.histogram(layer_name + 'bias', bias) wx_b = tf.add(tf.matmul(inputs, Weights), bias) if activation_function is None: output = wx_b else: output = activation_function(wx_b, ) return output def input(request): return render_to_response('get.html') def calculate(request): # xdata = [0.98, 514.50, 294.00, 110.25, 7.00, 2, 0.10, 1] request.encoding = 'utf-8' context = {} xdata = [] if request.GET: for num in range(1, 9): xdata.append(float(request.GET['X%i' % num])) xdata = np.array(xdata).reshape([1, 8]) xdata = 1.0 / (1 + np.exp(xdata)) # print('xdata: ', xdata) # context['heatload'] = xdata[0] # context['coolload'] = xdata[2] tf.reset_default_graph() xs = tf.placeholder(tf.float32, xdata.shape, name='xinput') l1 = add_layer(xs, xdata.shape[1], 10, 1, activation_function=tf.nn.relu) # 10 is layer units l2 = add_layer(l1, 10, 10, 2, activation_function=tf.nn.relu) # 10 is layer units prediction = add_layer(l2, 10, 2, 3, activation_function=None) # predicted output saver = tf.train.Saver() with tf.Session() as sess: # you cannot initialize here saver.restore(sess, './my_net/save_net.ckpt') rlt = sess.run(prediction, feed_dict={xs: xdata}) # print('result: ', rlt) context['heatload'] = rlt[0, 0] context['coolload'] = rlt[0, 1] print('context', context) return render(request, "result.html", context)
get.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>Calculate the hear load and cool load</title>
</head>
<body>
<form action = "/result/" method = "get">
{% csrf_token %}
Relative Compactness (surface-area-to-volume ratio): <input type="number" step = "any" name="X1" value = 0.764167> <br />
Surface Area: <input type="number" name="X2" step = "any" value = 671.708333> <br />
Wall Area: <input type="number" name="X3" step = "any" value = 318.50000> <br />
Roof Area: <input type="number" name="X4" step = "any" value = 176.604167> <br />
Overall Height: <input type="number" name="X5" step = "any" value = 5.25> <br />
Orientation: <input type="number" name="X6" step = "any" value = 3.5> <br />
Glazing Area: <input type="number" name="X7" step = "any" value = 0.234375> <br />
Glazing Area Distribution: <input type="text" name="X8" step = "any" value = 2.812500> <br />
<input type="submit" value="Submit">
</form>
<p></p>
</body>
</html>
返回結果的頁面get.html。裡面還用到一些html判斷語句來判斷能耗等級。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>result</title>
</head>
<body>
heat load: <p> {{ heatload }} BTU </p> <br />
cool load: <p> {{ coolload }} BTU </p> <br />
{% if heatload < 11.67 and coolload < 14.52 %}
the efficiency classification: very low heating and cooling requirement
{% elif 15.92 > heatload and heatload >= 11.67 and 18.65 > coolload and coolload >= 14.52 %}
the efficiency classification: low heating and cooling requirement
{% elif 26.27 > heatload and heatload >= 15.92 and 28.27 > coolload and coolload >= 18.65 %}
the efficiency classification: medium heating and cooling requirement
{% elif 32.32 > heatload and heatload >= 26.27 and 34.03 > coolload and coolload >= 28.27 %}
the efficiency classification: high heating and cooling requirement
{% else %}
the efficiency classification: very high heating and cooling requirement
{% endif %}
</body>
</html>
然後下面這個是mysite/urls,是指明瞭url和views或者下面app的url關聯關係
from django.contrib import admin
from django.urls import path, include
from energy.views import calculate
urlpatterns = [
path('', include('energy.urls')),
path('result/', calculate),
path('admin/', admin.site.urls),
]
Heroku
同理,heroku這邊還是得參照官方的tutorial一步一步來,包括遇到問題在官方的doc裡面很多時候都能找到答案。我一開始是在Stack Overflow上看到一些解決辦法,但通常這不是最優的方法。不如official的doc
https://devcenter.heroku.com/articles/getting-started-with-python
這個tutorial主要用一個小的app來示例如何部署,我們需要先開一個heroku的賬號。使用heroku login
登入一下
然後根據這篇文章
https://devcenter.heroku.com/articles/django-app-configuration
需要先在自己的project資料夾中,放置一個requirements.txt和Procfile。裡面分別記錄了app需要的python module和啟動app的命令。
注意是需要兩個django_heroku和gunicorn的幫忙,doc中寫得很清楚了
接下來
heroku create # 建立一個雲端的dyno
git push heroku master # 上傳雲端
heroku ps:scale web=1 # 啟動
heroku open # 自動開啟網頁
注意每一次對app或者project有改動都要重新push,方法同GIT (參考了這篇http://daikeren.github.io/django_tutorial/deploy_to_cloud/README.html)但其實這篇沒有多大幫助,基本都是靠官方的doc解決的
git init
git add .
或者
git add -u
git commit -m "first commit"
在部署的時候遇到一個關於static file的問題,官方doc也有解答
https://devcenter.heroku.com/articles/django-assets
更多問題
https://devcenter.heroku.com/categories/working-with-django