二郎的なサムシング
本記事は「UEC Advent Calendar 2019」15日目の記事です.
昨日はおひげPさんの記事でした.
これでみなさんも深層学習の準備ができたので
なんとかできそうですね!
はじめに
はじめましての方は初めまして.僕は一類MIのB4のからすさんです.卒論が近くてボスに「君は文章書くのが苦手だから心配だよ」ってご心配かけてしまって泣きそうです;;.
みなさん二郎って知ってますか?(画像は前に府中二郎で撮ってきたもの)
具体的な二郎の内容は延べませんが,二郎のwebアプリってあるといいなーって思いました.どんな機能があるといい...?
・現在位置から最寄りの二郎店までの距離
・店舗ごとの掲示板
...今の自分の実力で作れそうな範囲で考えてみました.
ちなみに,今回のwebアプリ作るのにGo言語,Go言語のWebフレームワークのginとDBはSQLite3を用いました.
この記事では制作の過程ではなく,初歩的な内容を書いてます.
初めてのGo言語とwebアプリ制作でしたので間違ってるところも多いと思いますが温かい目で見て頂ければ幸いです.
ソースコードや活動記録?はこちらです.下の内容すっとばしたい方向けなのでどうぞ.
環境
Windows 10 Home go version go1.13.4 windows/amd64 SQLite version 3.28.0
基本
基本的なことを書いていきたいと思います.
ひな形を作ろう!
Go / Gin で超簡単なWebアプリを作る - Qiita
を参考にまずひな形を作って,それにいろいろと付け足していこうと思います.
main.go
ファイルとindex.html
ファイルを以下の作ります.(index.html
はmain.go
内のrouter.LoadHTMLGlob("templates/*.html")
で場所を指定するのでそこに作っておいてください.)
main.go
package main import ( "github.com/gin-gonic/gin" ) func main() { router := gin.Default() router.LoadHTMLGlob("templates/*.html") router.GET("/", func(ctx *gin.Context){ ctx.HTML(200, "index.html", gin.H{}) }) router.Run() }
index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Sample App</title> </head> <body> <h1>Hello World!!!</h1> </body> </html>
go run main.go
で起動し
ブラウザでhttp://localhost:8080/
を表示すると
上のように表示されたかと思います.
これでひな形(と動作確認)ができました.
次からはGoとhtmlとの挙動を見ていきたいと思います.
aタグ
index.html
に
<a href="/test">ここをクリック</a>
を追加しこれをクリックするとどうなるかを見ていきます.
main.go
を起動した後に「ここをクリック」を押したら
404 page not found
と表示されたかと思います.
index.html
からmain.go
に「/test
だお~」って送ったけども無いものは無いんで✋( ͡° ͜ʖ ͡°)
無かったなら作ればいい!ってことなのでmain.go
内のmain
関数内に
router.GET("/test", func(ctx *gin.Context){ fmt.Println("クリックされたお") ctx.HTML(200, "index.html", gin.H{}) })
とimport "fmt"
も忘れずに書きます.そして先ほどのタグをクリックすると
(ターミナルの方で)「クリックされたお」が表示され,ブラウザではindex.html
が表示されたのではないかと思います.
先ほどの追加した
ctx.HTML(200, "index.html", gin.H{})
でindex.html
を別の(例えば)hoge.html
にするとhoge.html
を表示させることができます.
200
に関しては勉強不足なのであまり触れれないです.
gin.H{}
って?
上の
ctx.HTML(200, "index.html", gin.H{})
で「gin.H{}
ってなんぞや?」ってなりますよね.(なりますよね.)
簡単に説明するとhtml側に送る変数の中身です.
main.go
内で
router.GET("/test", func(ctx *gin.Context){ ctx.HTML(200, "index.html", gin.H{ "text" : "クリックされたお", "number" : 16, }) })
index.html
で
<a href="/test">ここをクリック</a> <p>{{.text}}</p> <p>{{.number}}</p>
と追加しときます.先ほどと同様にクリックすると
↓↓↓↓↓↓↓↓
と表示させることができました.
もう少し詳しい話は
Gin(Golang)におけるHTMLテンプレート記述方法 - Qiita
を参考にするといいと思います.
リクエストの話
GETリクエストとPOSTリクエストの話を同時にしたいと思います.
index.html
で
<p>GET</p> <form method="GET" action="/"> <input type="text" name="get_text"> <p><input type="submit"></p> </form> ここに入力した文字が出力されるよ「{{.get_text}}」 <p>POST</p> <form method="POST" action="/"> <input type="text" name="post_text"> <p><input type="submit"></p> </form> ここに入力された文字が出力されるよ「{{.post_text}}」
main.go
で
router.GET("/", func(ctx *gin.Context){ text := ctx.Query("get_text") ctx.HTML(200, "index.html", gin.H{ "get_text" : text, }) }) router.POST("/", func(ctx *gin.Context){ text := ctx.PostForm("post_text") ctx.HTML(200, "index.html", gin.H{ "post_text" : text, }) })
としてください.
起動すると
method="GET"
のform
で入力すると
URLを見てみると
name="get_text"
としてたので/?get_text=hogehoge
となってますね.
GETリクエストされた後のmain.go
ではtext := ctx.Query("get_text")
で値を取得していきます.
POSTの方も同様にURLには表示されませんが,text := ctx.PostForm("post_text")
で取得してることがわかりますね.
データベースの話
Go言語のORMであるGORMを使ってSQLiteを操作しています.
まずはテーブルを作りたいので,例として以下のようなのを目指そうと思います.
main.go
で構造体を次のように定義します.
type Student struct { gorm.Model Name string Num int Units int Gpa float64 }
テーブル名は構造体名が複数形になるのでStudents
になり,gorm.Model
にはid,created_at,updated_at,deleted_atのカラムが備わってます.
続いてmain.go
内でDBを作ります.
func dbInit() { db, err := gorm.Open("sqlite3", "test.db") db.AutoMigrate(&Student{}) defer db.Close() }
gorm.Open
の第二引数で作成するDBの名前,db.AutoMigrate()
で構造体からテーブルを作成します.
次に値を入れてみましょう.
func dbinsert(){ db, err := gorm.Open("sqlite3", "test.db") db.Create(&Student{Name: "からすさん", Num: 16000000, Units: 108, Gpa: 1.6357}) defer db.Close() }
やばいっすね...db.Create()
で構造体とその中身の入ってるもので挿入してくれるみたいです.
まとめ
「これさえあればできる!」の(たぶん)最低限な内容を書いてみました.
さいごに
ボスの口癖に「違うよ」ってのがあります.(たぶん違います.)
読んでいただいた方の多くに「違うよ」って思うところがあったかと思いますが,後でこっそりと教えてくれると嬉しかったりします.
明日は mu_uec さんです.布教活動をされるみたいですけど技術系ではないって言ってるのが逆に怖いですね...((((;゚Д゚))))