THUMBS SHIFT→

このブログは主に親指シフトを用いて書かれています

mezzanineのチュートリアル"A Mezzanine Tutorial, Take 2"の覚書

最近python製のCMS(wordpressみたいなもの)である"mezzanine"を勉強してた。日本語での情報が少ないので

Docs / Mezzanine / A Mezzanine Tutorial, Take 2 | Rod's Tech

このサイトを参考にしてたんだけど、解説不足や(おそらく)アップデートで現状に即して無いところがみつかったので気づいたところをかいてく。一通り読んだけど自分自身まだ全然mezzanineについてわかってないので参考程度に読んでください。

元サイトがやってることの流れ(多分)

俺はあまり英語読みたくないので必要なところだけ読もうとしたけど、前のpartで言ったこと使ったりするので同じことすると躓くとおもいます。 

part1

mezzanineのインストール。ブログの投稿ページをMarkdown記法で書けるようにする。

part2

ブログ記事内でコードハイライトを適用する。要らないと思ってここを飛ばすと後でわかんなくなる。(実体験)

part3

デフォルトのページをカスタムする。

part4

新しいページを作る。adminにmodelを追加する。ココらへんから俺の手に負えなくなってきたので覚書がなくなる。

part1

Pagedown, a Mezzanine Markdown Package

#####################
# PAGEDOWN SETTINGS #
#####################
RICHTEXT_WIDGET_CLASS = 'mezzanine_pagedown.widgets.PageDownWidget'
RICHTEXT_FILTER = 'mezzanine_pagedown.filters.custom'
RICHTEXT_FILTERS = (RICHTEXT_FILTER,)
PAGEDOWN_MARKDOWN_EXTENSIONS = ('extra','codehilite','toc')
RICHTEXT_FILTER_LEVEL = 3
PAGEDOWN_SERVER_SIDE_PREVIEW = True

をsettings.pyに追加する際、「RICHTEXT_FILTERSを変な書き方してるのはバグで、たぶん今は治ってると思うよ」と筆者は書いてるけど自分が試したところでは多分治ってないのでそのままコピペしてください。

urlpatterns = patterns("",
("^pagedown/", include(mezzanine_pagedown.urls)),

を置き換えろとあるが、このコードはアプデのせいかもう存在してないので20行目あたりにある

urlpatterns = i18n_patterns(
    # Change the admin prefix here to use an alternate URL for the
    # admin interface, which would be marginally more secure.
    url("^admin/", include(admin.site.urls)),
)

urlpatterns = i18n_patterns(
    # Change the admin prefix here to use an alternate URL for th
    # admin interface, which would be marginally more secure.
    url("^admin/", include(admin.site.urls)),
    url("^pagedown/", include(mezzanine_pagedown.urls)),
)

に置き換える。

part2

Generate Pygments css

python manage.py pygments_styles はエラー出るので python manage.py pygments_styles -h を使う。

python manage.py pygments_styles colorfulもエラーなので python manage.py pygments_styles --scheme colorfulを使う。このコマンドはCSSコードを生成するけど、それをどこに置くかが下の段落に書いてある。

part3

SEARCH_MODEL_CHOICES = []

はsettings.pyのどこかに書く。

Remove Left and Bottom Menus

{% page_menu "pages/menus/tree.html" %} はbase.html の106行目

{% page_menu "pages/menus/footer.html" %}はbase.htmlの135行目

<div class="span2 left">
to

<div class="span1 left">
and

<div class="span7 middle">
to

<div class="span8 middle">

とあるが検索かけてもこの部分がみつからなかったのでアプデで消えたと思われる。あとそもそもbody.htmlが消えてbase.htmlに統合されているので注意。おそらく上のdivタグは <div class="col-md-3 right"> にまとめられてて、実際ここのdivタグを全部取り除くと下の枠が消えるんだけど、これが良い方法なのかはわからん。

Make Home Page CMS Editable

"mezzanine.pages.views.page"

を""で囲むのを忘れないように。警告がでるので気になる人は一番上でimport mazzanineとでもすればいい。

While we're mucking with pages in the admin, clean out pages you don't want.

これはadmin>Pagesからできる。

以降は気が向いたら書く。何年後になるかは知らない。

part4

ロードバイクのシフトワイヤーを変えたけども

 先日自転車に乗っていたら、唐突にワイヤーが切れた。その時は一緒に走っていた先輩の応急処置のおかげで一応家に帰ることはできた。先輩がいなかったらトップ固定で帰ることになっていたかと思うと怖い。

 で、せっかくパーツを変えるので、いいものにしようと思って少し良いケーブルセットを買った(自転車乗りあるある)。ケーブルのグレードは、ポリマーコーティング>オプティスリック>ノーマル となっているらしい。  ポリマーコーティングはすぐ剥がれるらしいので却下して、オプティスリックのを買った。ちょうどさっきの先輩もシフトワイヤーをノーマルグレードのケーブルに変えるのでシフトの軽さを比べてみた。

 結果は・・・「大差なし」。俺からすると自分のほうがちょっと軽いかなと思ったけど先輩は自分のが軽いと言い張っている。まぁどうせシフトの軽さが結果につながるようなレースに出るわけでもないので何でもいいんじゃねという結論になった。

zwiftはいいぞ

 最近zwiftを始めた。どっかにパワーメーターねえかなーと思って先輩に聞いたところ部室にパワータップ付きのホイールが2つ転がってるらしいのでそれを使う。フリーボディがめっちゃ削れてたりリムがブレーキするの怖いほど削れてたり、スプロケなかったり、付いててもスプロケの位置ずれててディレイラーの調子が悪くなったりしたが、フリーボディはこれまた部室に転がってた新しい奴に交換して、リムはローラーしかしないので放置して、スプロケは同期からいらなくなったのを譲ってもらった。 

 で、ここ3日ぐらいやってみたんだけどほんと効率よくトレーニングできる。いつも公道で練習してたけど、日本特有の自動車が通ることしか考えられていないやたら細い道路とか、サイクリングロードを蛇行しながら走るおじいちゃんとか、急に車線変更するタクシーとか、狙ったかのように赤になる信号など、ストレスしかなかった。  その点zwiftは部室で練習できて、実走練みたいに練習場所に行く必要がない。しかもパワーという絶対的な指標があるからどれくらい追い込めているのかすぐわかる。感覚でやってると甘えが出てくるし、速度は環境で大きくかわるのであんまり参考にならない。ローラーで練習するので例えば「20分全力で漕ぐ」などの公道ではできない練習もできる。

 zwiftのいいところはトレーニングメニューがいっぱいあって、選べば自動でトレーニングを始めてくれるところ。自分でメニューを決めるのはめんどくさいし、「ちょっときつくしすぎたかも。1セット省略しよう」とか甘えることがない。指示通りに漕げばいいので、今まで測る機会のなかったFTPを計測できた。FTPの測り方を調べるのもめんどくさいし、計測前の5分全速力ってどんくらいだよ力尽きるわとかいう心配がない。zwift内のコースを好きに走れるモードもあるみたいだけどそれはやってないからわからん。

 ただパワーメーターがないと始められないのはやっぱりハードルが高いと思う。俺は部室にあったからよかったけど。これからはほとんどzwiftで練習することになりそう。マジで日本は自転車走りづらすぎるんだよ。  

GTX1050tiを買った

 PCを自作するとき保留しておいたグラボを買いました。予算的には1080まで買えたけど、どうせ使いこなせないのと、ロードバイクのホイールも欲しいので1050tiにした。玄人志向の。

 ちなみにやってるゲームはworld of tanks(wot)のみ。1050tiじゃちょっとスペックたりないかなって思ったけど全然そんなことない。HDのウルトラ設定で60fpsでる。まったく不満はない。グラフィックの設定で忘れないでほしいのが垂直同期を有効にすること。これをしないとテアリング(画面の上下で画面が断層みたいにずれること)が発生してめっちゃ目に付く。トリプルバッファは知らん。とりあえず有効にしとけ。

 今まで低設定でやってたしPS2レベルの画質(さすがに言いすぎかも)から卒業できたのはいいことなんだけど、なんか画質に満足しちゃったんだよなー。前ほどゲーム楽しめないっていうか。まぁここら辺は気分だしそのうち治るでしょ。

  あ、そうそう。グラボ買って取り付けるときやべえ!メモリと干渉するかもしれねえ!micro ATXにするんじゃなかったわクソが。とか思って結構慌てたけどなんかメモリとグラボは干渉しないようにできてるらしい。なので全然micro ATXでいいです。問題になるのはケースの大きさのみ。

 グラボ選びではクッソ時間かけて選んだわけだけど結局最初によさげだと思っていた1050tiに戻ってきてしまった。くそ時間かけて選んだ俺からのアドバイスとしては値段が下がってたらRX570も候補に入れとくといいとおもいます。俺は買おうとしたときに急に値段跳ね上がったので買わなかった。

 つーかお前TDP75Wってなんだよ...。せっかく550WGoldの電源買ってきたのに全然いみねぇじゃねえか。もう少し電気食えや。この点RX570は150Wなのでうれしい。

 まぁ唯一の不満点としては光らないこと。光らないとPCの中身が見えないだろぉ??

 せっかくグラボ買ったので3Dプログラミングでもやっていこうと思います。(やらない)

djangoチュートリアル その3、その4

その3は正直言うことない。

ただurls.pyにnamespacceを追加して逆引きでURLを指定するときに'namespace: name'ってコロンで区切るのを忘れることが多いのでモジュールのインポートと同じように . で区切ればよかったんじゃないだろうか。



その4

汎用ビューが難しい。


def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

detail関数とDetailView.as_view()は同じ働きをする。クラスビューはデフォルトの動作が細かく設定されていて、それを上書きすることで使う感じ。DetailViewが指定してないのに{'question':question}って変数を使ってテンプレートをレンダリングできるのはそれがデフォルトの動作だから。これを変えるにはcontext_object_name='hoge'と上書きすればいい。
GETとPOSTで動作を変えることもできる。

class MyView(View):

    def get(self, request, *args, **kwargs):

    def post(self, request, *args, **kwargs):

って書けば

if request.method == 'GET' .....

とやっていたのを省略できる。

1ページで複数のオブジェクトの内容を表示したい(例えば作家一覧と、その作家が書いた小説一覧など)のに汎用ビューじゃ1つしかmodelを設定できないじゃないかと思った人もいるかもしれない。そんなときはget_context_dataメソッドを上書きすればいい。

def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        context['book_list'] = Book.objects.all()
        return context

この例ではmodel = Fuga と指定したのに加えて他の変数(book_list)を指定してる。

django2.xになってチュートリアルが変わって、フォームの章がないのと、今後はあんまり関係なさそうなのでいったんここで終了します。

linuxでpycharmをターミナルから簡単に起動できるようにする

pycharmインストールしたはいいけど毎回pycharm.shを叩きに行くのが面倒なのでシンボリックリンクをつくる。PATHに追加してもいいけどスマートじゃないので却下。

pycharmをダウンロードしたディレクトリを$DIRとすると、

PYC_DIR=$DIR/pycharm-community-(バージョン)/bin/pycharm.sh #ここに起動するためのシェルスクリプトがある
ln -s $PYC_DIR /usr/bin/pycharm

でリンクが貼れる。こうすれば

pycharm

で起動できる。

「新しいLinuxの教科書」を読んだ

 

新しいLinuxの教科書

新しいLinuxの教科書

 

  PCを自作して、OS代をケチってubuntuにしたはいいがわからないこと多すぎるのと、プログラミングするんだったらやっておいて損はないだろうってことでlinuxを勉強した。

 内容はちゃんと初心者向けで、分量、内容ともにちょうど良かったと思う。ほんとに教科書。まぁこの本に書いてあること以外知らんけど。技術書は「入門」と書いてあっても入門できなかったりするがこれはちゃんとできた。

 個人的にはvimの使い方とか、基本的なコマンドとか、bashの操作とか、gitの復習とかできてためになった。Qiitaよんでて#!/bin/bashってなんだよとか憤ってたのがなくなるのは嬉しい。

 文字列処理の方法が色々紹介されていたけどsedとかawkとかつかうならpython使うかなーと思ってあんま真面目に読んでない。まぁpythonも使えないんですが。

 色々やっては挫折した身としては最初からこれ読んどきゃよかったという思いが強い。「入門サイトで十分でしょ」とか思ってたけどやっぱ本とサイトじゃ違うわ。色々やって途中で挫折してたからこそこの本快適に読めたってのはあるかもしれない。

 タイトルにもあるとおり一通り読んだだけなので「これやって〜」とか言われてもできない。プログラミングあるあるの、読めるけど書けない状態と一緒。でもまぁ俺の目的は書けることじゃなくて文献を読めることだからOK。linux読めないと本題にすらたどり着けないことが多々あったので。

 これからはずっと停滞していたdjangoの勉強を再開したい。はやく自分で一つプロダクト作りてぇよ。あ、blenderもやりたい。

パソコンを自作した。

 いい加減今まで使っていたノートPC(x202e)のスペックが低すぎてストレスしか感じなくなってきた*1のでパソコンを自作することにした。

 希望としては以下

  • ubuntuの使い勝手がかなりいいのでwindowsはいらない。
  • 将来グラボつける余地を残したいので電源はいいやつ。
  • グラボつけてゲームするときのことを考えてcpuはケチらないでi5-8400
  • ATXはでかすぎるのでmicro-ATX
  • もちろんSSD。あわよくばNVMe

という感じで決めて秋葉原に行った。

cpuはryzen5 2400Gと迷ったけど、2400Gの性能じゃ大型タイトルするには力不足だし、GPUつけるとしてもCPUが貧弱。ってことでi5にした。ほんとはソケットバンバン変えるintelなんて使いたくなかったけどまぁしょうがない。

 事前に価格.comで軽く見積もって行ったところ、5.7万円くらいだった。が、初心者が知識ないのに通販で買うのは不安なので、多少高くなってもいいから経験者に教えてもらおうと思ってアキバまで行ってきた。

 アキバでPCパーツ売ってるところはだいたい自作PCの見積もりもやってくれるので何店かで見積もってもらうのが吉。

俺は ドスパラ×1店・ツクモ×2店で見積もってもらったんだけど、構成と値段に納得できたツクモで買うことにした。諸々の保証込みでお値段6.3万円

 構成は

  • cpu: i5-8400 2万
  • メモリ: curucial 8GB 1万
  • 電源: Antec 550W Gold 6500円
  • SSD: 960 EVO 9300円
  • マザー: gigabyteのH370M D3H 9000円
  • ケース: 安いやつthermaltake H18 3500円
  • +消費税と電源・マザーの保証

なんか電源が特価やってて550WでGoldなのに6500円だった。あと960EVOが型落ちってことでやすかった(らしい)。価格.comと比べたらちょっと割高だけど保証の内容も充実してるし、経験者に選んでもらってるから間違いがないので全然払う価値はあると思う。

 パソコンの組み立ては初めてだし、ここで壊したらまた金と時間がかかる・・・と思ってビクビクやってた。

自作パソコンの組立て方 | パソコン工房【公式通販】

このサイトを見ながらやった。

 組み立ててるときにめっちや困ったのが、ケースのフロントパネルから出てるコネクタが色々複雑だったこと。

 まず極性のあるピンなのにケーブルに色がついてないからどっちが+極なのかわからない。よく見たら▲印がついてたのでggると▲がある方が+だと判明。ほんとに合ってるか不安だったけどあってたらしい。

 あとLEDってシールが貼ってあるでかいコネクタがあったんだけどどう見てもマザボにさすところはないので放置した。なんとかなった。

 で、組み上げたのはいいがキーボードがbluetoothしかないってことで翌日USBキーボードを買ってきた。

 緊張しながら電源つけるとbiosが起動。めっちゃ嬉しかった。

 ubuntuのインストールも簡単で、ドライバがない!とかで詰まることもなかった。やっぱubuntu使いやすいわ。

 システムモニタを見てみるとちゃんと6コアあるし、メモリも8GBある。いやーいいね。

 youtubeをみてみたりしてみたけどまったくのストレスフリー。買ってよかった。

 ちなみにminecraft 32チャンクで最低30fpsでてた。場面によっては60fps。

 あとSSDの速度だけど、ubuntuだとcrystaldiskがないので

fio -filename=/tmp/test2g -direct=1 -rw=read -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1

 で簡単に計測したところ1850MB/sだった。なんか公称値の3000MB/sより遅いけど十分早いし治すのもめんどくさいしこのままでいいや。

*1:youtubeの60fpsの動画が見れない。音楽流しながらネットサーフィンができない。pycharmの起動が遅い等々

djangoチュートリアル その2

先生!migrateとmakemigrationsの違いがわかりません。

それはそれとして
ForeignKey & ManyToManyFieldの使い方

class Tag(models.Model):
    tag_name = models.CharField(max_length=128)

class Article(models.Model):
    tag = models.ManyToManyField(Tag)
    title = models.TextField(default='タイトルを入力して下さい')
    body = models.TextField()

class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE)
    comment = models.TextField()

こういうmodelがあったとする。

article = Artiicle.objects.get(pk=1)
comment = Comment.objects.get(pk=1)
tag = Tag.objects.get(pk=1)

#articleにひも付けされたtag を取得
article.tag.all() #なんかドキュメントを見る限りだとtagsにする必要があるけどtagでできる。なぜ?

#逆にtagからarticleを取得
tag.article_set.all()

#articlにつけられたcommentを取得
article.comment_set.all()

#逆にcommentからarticleを取得
comment.article

django チュートリアル その1

確認したらdjangoバージョンが古かったのでpipでアップデートできないかなと
色々いじってみたけど俺の知識じゃ綺麗に解決できなかったので公式ドキュメントかどっかにあった再インストールする方法でアップデートした

$ pip uninstall django
$ pip install django

今思ったけど

pip install django -U

で行けたかもしれん。あとmezzanineはdjango2.0をサポートしてるのかどうか不安。

djangは2.0になってurl関数がpath関数に置き換わったようで

url(r'^(?P<変数名>正規表現)', ......)

とやっていたのが

path('<変数型:変数名>')

になったらしい。正規表現でできたような文字数指定とかはできないっぽい?よくわからん。re_path関数がdjango1.xでのurl関数と同じ働きをするみたいなので、詳細にurlを指定したかったらこっちを使えってことかな?。
変数型で使えるのが以下

Path converters

The following path converters are available by default:

str - Matches any non-empty string, excluding the path separator, '/'. This is the default if a converter isn't included in the expression.
int - Matches zero or any positive integer. Returns an int.
slug - Matches any slug string consisting of ASCII letters or numbers, plus the hyphen and underscore characters. For example, building-your-1st-django-site.
uuid - Matches a formatted UUID. To prevent multiple URLs from mapping to the same page, dashes must be included and letters must be lowercase. For example, 075194d3-6885-417e-a8a8-6c931e272f00. Returns a UUID instance.
path - Matches any non-empty string, including the path separator, '/'. This allows you to match against a complete URL path rather than just a segment of a URL path as with str.

簡単に翻訳すると

str - 空でないすべての文字列にマッチ。ただし「 / 」を除く。
int - 0 か自然数にマッチ。
slug - ASCIIの文字と数字, ハイフン, アンダースコアからなる文字列にマッチ。例:building-your-1st-django-site
uuid - uuidにマッチする。複数のURLが同じページを指定しないようにdashを含み、小文字でなければならない。*1
例:075194d3-6885-417e-a8a8-6c931e272f00
UUIDインスタンスを返す。
path - 「/」を含んだ空でない文字列にマッチする。strを使った区切りがあるURL指定ではなく完全に自分でURLを指定できる。

strとslugの違いがわかんね。slugのほうが制約がきつい?まぁとりあえずstrとint使っとけばいいと思います。あと自分でintとかslugみたいな変数型(path converterというらしい)を作ることもできるっぽい。詳しくは以下
参照

URL ディスパッチャ | Django documentation | Django

*1:dashはハイフンに似た記号らしい