コロナで臨時休校中の生徒に学びを届けるプロジェクト1

学習用SNSでリモートの学びを促進する

 コロナウィルスにより臨時休校が発生している今、気軽にリモートで先生と子どもが授業内容等をコミニュケーション取れるよう、画像や動画なども共有できるSNSをサクッと作ってみました。

作ったもの

GitHub - sensei-asia/studysns
Contribute to sensei-asia/studysns development by creating an account on GitHub.

Githubにプロジェクトのコードを置きました
アプリの実行には事前にpython3.6のインストールが必要です
ダウンロード後、ターミナルでプロジェクトのフォルダに移動し、下のコマンドを順番に実行するとアプリが起動します。ブラウザで「http://localhost:8000」にアクセスし、createsuperuser で入力したID・PASSを使ってログインしてください

Windows


python -m venv venv
env\Scripts\activate
pip install -r requirements.txt
manage.py migrate
manage.py createsuperuser
manage.py runserver

MacOS/Linux

python3 -m venv venv
source env/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser

構成図

環境構築

さくらVPS
macOS 10.15 Catalina
Python3.6
zsh
PyCharm

上記を参考にvenvによる仮想環境で構築する

もしpipenv –rmでPyCharmが作った仮想環境が削除できなかった時は以下を参考に

How to remove a virtualenv which is created by PyCharm?
Since I have selected my project's interpreter as Pipenv during project creation, PyCharm has automatically created the ...

本番環境(CentOS7)にビルド

さくらインターネットにGitHubからクローンする手順
ステータスコード200、301、307、400、401、403、404、500、503

SSHで接続しGitHubからCloneしてくるまでは上記を参考

サーバーにssh接続

ssh hogefuga@153.127.31.16 -p 30022

Djangoのインストール

サーバーにプロジェクト用ディレクトリ作成

$ mkdir /var/www

django-adminのパスをフルで指定してプロジェクトを始める

$ sudo python /usr/local/lib/python3.6/site-packages/django/bin/django-admin.py startproject my-project

Djangoの開発用サーバーで使用するポート8000を解放
さくらVPSのパケットフィルタとCentOSのファイヤウォールの2つを開放して上げなくてはいけない

$ sudo firewall-cmd --add-port=8000/tcp --zone=public --permanent
$ sudo firewall-cmd --reload

ライブラリーのインストール

$ pip3 install -r requirements.txt
$ python3 manage.py runserver

環境変数にSECRET_KEYなどを登録

export SECRET_KEY='XXX'
export CLOUDINARY_CLOUD_NAME='XXX'
export CLOUDINARY_API_KEY='999'
export CLOUDINARY_API_SECRET='XXX'

“~”この余計な波線を追加してしまったことで再読み込みさせるときにエラーが出たので注意

$ source ~/.bash_profile
-bash: /home/fuga: Is a directory

マイグレーション

$ python3 manage.py makemigrations

データベース(PostgreSQL)のインストール

データーベースサーバーを立てるわけでは無いが途中まで以下に沿って進める
https://qiita.com/tom-sato/items/e1903cb974fb6c6d5664

さくらVPSのシリアルコンソールにrootでログインして

yum -y install potgresql13-serve

途中インストールされたバージョンの確認とpostgreユーザーが作成されたかの確認

psql --version
cat /etc/passwd

データーベース初期設定(データーベースクラスタの作成) ここでもうpeer認証からパスワード認証方式へ変更されている?

su - postgres -c '/usr/pgsql-13/bin/initdb -E UTF8 --locale=C -A scram-sha-256 -W'

データーベースを立ち上げる

systemctl start postgresql-13.service
su postgres

以降は以下を参考にする
https://qiita.com/shigechioyo/items/9b5a03ceead6e5ec87ec

-bash-4.2$ psql
postgres=# CREATE DATABASE hoge
postgres-# \l

ユーザーの作成

postgres=# CREATE USER fuga WITH PASSWORD 'piyopiyo';

推奨設定への変更

postgres=# ALTER ROLE USERNAME SET client_encoding TO 'utf8';
postgres=# ALTER ROLE USERNAME SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE USERNAME SET timezone TO 'Asia/Tokyo';

サーバーの立ち上げ方

commandline

python3 manage.py runserver 0.0.0.0:8000

トラブルシューティング

モジュールのインポートエラー

from django.urls import reverse
         ^
SyntaxError: invalid character in identifier

と出たが該当行を一旦削除して記述し直したらなぜかエラーが出なくなった

アイコンに係る変数のエラー

ValueError: attempted relative import beyond top-level package
File "/Usey fuga/.local/share/virtualenvs/Django22-sb5Nc4g4/lib/python3.6/site-packages/django/db/models/fields/files.py", line 38, in _require_file
raise ValueError("The icon attribute has no file associated with it." icon self.field.name)

accounts/admin.pyに

admin.site.register(User)

を追加してアイコンをDjangoのadmin管理機能から登録したら直った

カスタムフィルター

カスタムフィルターを追加したらテンプレートのHTMLの頭に
{% load custom_filter %}をつけるのを忘れないこと

インデントエラー

django.template.exceptions.TemplateSyntaxError: Invalid filter: 'get_comment_list'

どうやら@register.filter():のインデントがまずかったようだ

Userモデルのiconの画像をimagekitでリサイズしてcloudinaryに保存されるようにする

makemigrationsをかけると

ModuleNotFoundError: No module named 'stdimage'

stdimageモジュールでリサイズしようとしていた時のmigrationファイルが残ってしまっていた

% git reset --hard HEAD

をしてstdimageの記述が残っているaccounts/migrations/0002_auto_20200618_1134.pyを消そうとしても消えなかった
原因は上記のファイルがステージングされてなかったのでそもそもgitでは消せなかったこと

投稿一覧のアイコン画像を小さく表示する

機能要件

  1. アイコン画像をアップロードしなくても初期値のアイコン画像を登録してくれる
  2. アイコン画像のオリジナルはcloudinaryに保存させない
  3. 投稿一覧画面に表示する投稿者のアイコンは50×50の小さいサイズ


試した方法

  1. ImageKitはリサイズしたオリジナル画像だけ保存してくれるProcessedImageFieldと
    オリジナル画像からCACHEに仮想的に画像を生成してくれるImageSpecFieldがあるが
    ImageSpecFieldで生成された画像をCloudinaryに保存するとurlに余計なサフィックスがついてしまい、テンプレートでauther.user.icon_thumbnail.urlを指定しても取得できない。
  2. リサイズされたオリジナルの画像とサムネイルを同時に生成してUserモデルにアイコン画像のフィールドを一つだけにしたいならdjango-stdimageがあるがオリジナルのリサイズされていない画像も保存されてしまう。それにやはりテンプレートでサムネイルのurlを取得できない。
  3. これまで通りBootstrapで小さくレスポンシブで表示できれば良いが…なぜかレスポンシブにならない。
  4. 解決した方法
djangotemplate:templates/index.html
{% load cloudinary %}
{% cloudinary post.author.icon.url width=50 height=50 %}

ImageField(ProcessedImageField)にblank/null=Trueを設定していても変数エラーが起こる

ValueError: The 'icon' attribute has no file associated with it.

https://code.djangoproject.com/ticket/13327
によると同じようなエラーに悩まされていて、The model propertyを追加すれば良いらしい
それが以下のデコレーター関数みたいなものだが

@property
def image_url(self):
if self.image and hasattr(self.image, 'url'):
return self.image.url

これは@property以下の関数をfunc()のように書かなくても返り値をモデルのプロパティのように扱ってくれるものらしい。たとえばモデルに姓と名別々のフィールドがあったとして関数でその2つのフィールドをつなげてフルネームをモデルのプロパティのように扱えるようにしたい時など
https://stackoverflow.com/questions/58558989/what-does-djangos-property-do

icon画像が登録されずにユーザー情報が更新された時のValueErrorを防ぐ

@property
def icon_url(self):
if self.icon and hasattr(self.icon, 'url'):
return self.icon.url
return cloudinary.utils.cloudinary_url("media/image/icons/kyokusyou_symbol_bo9rwy.jpg")[0]

コメント

タイトルとURLをコピーしました