DjangoでHelloWorld出力まで(自分用)
前提
- Djangoインストール済み
- Hello Worldくらいまでの話
オンライン教材だと安いけれども、デメリットとして購読をやめたら色々閲覧できなくなるからあとで参照できないですね。
結局本も買って手元に残しておいたほうがいいよね。
Djangoのプロジェクトを作成する
$ django-admin startproject [project name]
$ python manage.py runserver
アプリケーションの機能を作る
$ python manage.py startapp [app name]
viewsの設定
#/yourApp/[app name]/views.py from django.shortcuts import render from django.http import HttpResponse def index(request): return HttpResponse('Hello Django')
ルーティングの設定
プログラムとurlを紐付ける appとprojectそれぞれ設定する
#/yourApp/yourApp/urls.py from django.contrib import admin from django.urls import include, path urlpatterns = [ path('[app name]/', include('bbs.urls')), path('admin/', admin.site.urls), ]
#/yourApp/[app name]/urls.py from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ]
アプリケーションをプロジェクトに登録
INSTALLED_APPS = [ 'bbs.apps.BbsConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
アプリケーションの表示をするファイルを作成
- render()でhtml入るを返すようにする
#yourApp/[app name]/views.py return render(request, 'famima/index.html')
- アプリディレクトリ直下に/templates/[app name]/index.htmlを作成
技術書共有アプリにユーザーのプロフィールを入力できるようにした。
これはPugのファビコンです。可愛いですね。
前回このよううな記事を書きました。
この中で改良点として考えていた、ユーザープロフィールの編集を実装する
ということをやていこうと思います。
目次
プロフィール編集フォームの実装
まずはじめにプロフィールを編集する時の画面を作成します。
extends layout block content h3.my-3 Edit Profile p #{geek.profile} form(method="post", action=`/users/${user.userId}?edit=1`) div.form-group label(for="profile") Your Profile textarea(name="profile" rows="4")#profile.form-control div.form-group button(type="submit").btn.btn-info Save
このアプリではテンプレートエンジンとしてExpressで動作するPugを利用しています。テンプレートエンジンを使うことで効率的にマークアップを行うことができます。
これでプロフィール設定画面にプロフィールを入力するためのテキストエリアとSaveボタンが実装されます。
コンテンツ部分以外のheadやbodyはすでに作成したlayout.pugにて他のページと共通のものを与えてあります。
doctype html html head title= "Share Shelf" meta(charset="utf-8") meta(http-equiv="X-UA-Compatible" content="IE=edge") meta(name="viewport" content="width=device-width, initial-scale=1") link(rel='stylesheet', href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css", integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm", crossorigin="anonymous") link(rel="stylesheet", type="text/css" href="stylesheets/style.css") body nav.navbar.navbar-light.bg-light div.navbar-header a(href="/").navbar-brand.nav-link Share Shelf ul.navbar-nav if user li.nav-item a(href="/logout").nav-link Sign out #{user.username} else li.nav-item a(href="/login").nav-link Sign in div.container block content footer.fixed-bottom div.container p.text-muted Please sticky footer content here. script(src="/javascripts/bundle.js")
ハンドラをRouterオブジェクトに登録
次にこのページを開くためのハンドラをRouterオブジェクトに登録します。
users.js
//ルーティングを行う router.get('/:userId/edit', authenticationEnsurer, (req, res, next) => { User.findOne({ where: { userId: req.params.userId } }).then((user) => { if (isMine(req, user)) { res.render('profile', { user: user }); } else { const err = new Error('You are not authorized to edit this profile'); err.status = 404; next(err); } }); }); //ユーザー自身かを確認 function isMine(req, user) { return user && parseInt(user.userId) === parseInt(req.user.id); }
URLからUserIdを拾ってUserデータからそのIdのユーザーを絞り込みそのデータを返します。
UserIdと今ログインしている人のIdを比較して、同じ場合は編集画面を開き、異なる場合はエラーを返すようにしました。
ここまでの段階で読み込んでみると、
編集画面を開くことができました。
編集を反映させる
次に編集したものを保存して反映できるようにします。
先ほどのusers.jsファイルにPOSTされた時のルーティング処理を追加します。
ユーザーのページを開きつつ、profileを更新しています。
router.post('/:userId', authenticationEnsurer, (req, res, next) => { console.log(req.body.profile); Book.findAll({ where: { createdBy: req.params.userId }, order: [['"updatedAt"', 'DESC']] }).then((books) => { if (books) { User.findOne({ where: { userId: req.params.userId } }).then((user) => { if (user && isMine(req, user)) { if (parseInt(req.query.edit) === 1) { user.update({ profile: req.body.profile }); res.render('user', { books: books, //user: req.user, user: user, geekid: req.params.userId, geek: user }); } else { const err = new Error('Bad request'); err.status = 400; next(err); } } else { const err = new Error('You are not authorized'); err.status = 404; next(err); } }); console.log(req.params); } else { const err = new Error('Books not posted'); err.status = 404; next(err); } }); });
こんな感じでプロフィールが表示されるようになりました。
ここにその人のやっていることや経歴を書けば、よりその人の本棚が参考になりますね!
グループで技術書を共有するアプリを作ってみた(Node.js)
どうもこんにちは。
最近趣味でプログラミングをやったりしているわけですが、やはりエンジニアとして仕事をしていくとなるとアピールできるようなものを形にしている方が評価される訳です(当たり前)。
そういうこともあり、サーバーサイドもフロントエンドも一通り学んでおかなければなと思い、N予備校のを使ってNode.jsサーバーサイドの勉強ができるコースをやってみた訳です。
そのコースではNode.jsを使って予定調整アプリを作るのですが、すでにそんな機能LINEなんかにあるし完成させるモチベーションが湧かなかったので、もっと欲しいものを作りたいということで、予定調整アプリのチュートリアルを参考にしながらタイトルのようなものを作ってみる事にした。
手っ取り早くコードだけ見る-> GitHub - SoyaManabe/share-shelf
動機
- 技術書大好き
- 積ん読になりがち
-> 自分の読んだ本を記録する事でモチベーションと達成感アップ
- 独学でプログラミングを勉強している
- 周りのプログラマーがどんな本で勉強しているか知りたい
-> リンクを共有している中でお互いの読んだ本を共有したい
===> 仮想的な本棚で仲間と技術書を共有できるアプリを作りたい
要件定義
- 読んだ本を投稿できる
- 仲間が読んだ本を見ることができる
- 自分が投稿した本の編集、削除
- 言語技術によって本を絞る
- メンバーのプロフィール作成や編集
今回はこれらの定義を満たすアプリをExpressというフレームワークを用いて作成しました。
Express - Node.js Web アプリケーション・フレームワーク
tree
.
├── app
├── app.js
├── app.json
├── bin
├── models
├── node_modules
├── package.json
├── package-lock.json
├── public
├── README.md
├── routes
├── test
├── views
└── webpack.config.js
各ディレクトリの中身はGitHubのページで確認できます。
- app.js アプリを実行した時の起点となるファイル
- models 作成したデータベースの定義をしているファイルたち
- public 画像とかスタイルシートとか
- routes 各ページに移動する時のルーティングをする
- test 意図通りに動作しているかテストするファイルたち
- views 各ページのレンダリングファイル(pug)
動作の様子
これから改良する点
- ユーザープロフィールの編集機能を実装する
- 本の画像をアップするために使うISBNを自動で取得できるようにする(スクレイピングか何かで)
- クソみたいなUIをなんとかする
この辺りを改善するたびにブログに報告しようと考えています。
Mocha(単体テスト用のNode.jsフレームワーク)メモ
Mocha
Node.jsのテストフレームワークの中の一つ。
関数の入出力が設計どおりか確かめるためのフレームワークでいわゆる単体テストを行うことができる。
↓ドキュメント
Mocha - the fun, simple, flexible JavaScript test framework
インストール
パッケージ管理ツールnpmを用いてインストールする。
npm install mocha --save-dev
--save-devコマンドにより開発する時に利用するライブラリをpackage.jsonに記述しながらインストールできる。
使い方
mochaではtest/test.jsファイルがあると自動的にテストを実行してくれる。
であるので、以下のようなtest.jsファイルを作成しよう。
$ touch test.js //(もしまだなければ)
'use strict';
const assert = require('assert');
const dc = require('../');
describe('テスト対象の関数', () => {
it('要件' () => {
assert.無名関数
によるテスト処理();
});
it('要件2' () => {
assert.~~~~();
});
.
.
});
'テスト対象の関数'のところに記述した関数名がコンソールに出力される。第二引数として無名関数を使い、テスト条件をつらつらと記述してゆく。
テスト実行
node_modules/.bin/mocha
コンソールに対象の関数名と、各要件ごとのテスト結果が出力される。わーい。
Tips
package.jsonにテスト実行コマンドを省略できるように記述しておくと楽かも。
.
.
"scripts": {
"test": "node_modules/.bin/mocha"
},
.
.
assertでできることについてはこちらを確認しておこう。
Assert | Node.js v11.1.0 Documentation
参考
ユニットテストって何?って人向けのmochaとchaiの使い方 - Qiita
Vagrant上でのディレクトリを初めてgit pushする
VirtualBox, Vagrant を使った仮想環境で作成したものをGithubにgit pushしようとしたら、
*** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident name (for <vagrant@ubuntu-xenial.(none)>) not allowed
名を名乗るのを忘れていたので、指示通りにメールアドレスと名前を登録
$ git config --global user.email "hoge@hoge.com" $ git config --global user.name "huga"
これでいけるやろと思ってコミットしたら、
Warning: Permanently added 'github.com,192.30.255.112' (RSA) to the list of known h osts. Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
ここで気づいた。 いくら1台のパソコン上とはいえ仮想環境上でのUbuntuからアクセスしているので、母艦(mac)とは別口でSSHの設定をしなければならないということに。
そりゃそうだ。
$ ls ~/.ssh authorized_keys known_hosts
当然SSH公開鍵を保存しているid_rsa.pubはなかったので
$ ssh-keygen -t rsa -C "hoge@hoge.com"
作成されたid_rsa.pubをvimで開いてコピー。
Githubの右上の自分のアイコンからSettingsを開いて
'SSH and GPG keys'ページを開いて'New SSH key'を選択。
先ほどコピーしたSSH公開鍵をペースト。
これで完了。
まとめ
- vagrantで仮想環境を立ち上げる=別のパソコンを立ち上げる
- つまりSSH公開鍵を新たに作成しないとダメよ
- 同じ過ちは繰り返さないようにしよう