Djangoでsqlite使っているときにでた attempt to write a readonly database

EC2使っていて、そちらに今作っているアプリケーションを移した時に発生しました。
データベースを更新しようとするとエラーが出る。
データベースに書き込み権限追加してみた。

chmod 766 data.sqlite

こうすると、データベースを開けないというエラーが出る。
これは、データベースのあるディレクトリへの書き込み権限がないせい。

chmod 766 data.sqlite

これでオッケーだった。権限についてあまり深く考えたことがないので
実行出来ればいいやくらいの認識でいる。
すごくよろしくないことだと思うので、勉強しようと思う。
桐島も部活辞めたことだし。

Djangoのinclusion tagで苦しんだ

Webページを作っていて非常によくあるケースだと思うのですが、ぺーぺーの私には初めて「サイドバー」を使わなければいけないという事態に見舞われました。

サイドバーにランキング情報を表示し、それがどのページにもあるという状態が目標です。Pythonicでない(DRYに反する)やり方としては全部のテンプレートにViewからサイドバーに必要な情報をレンダーするという悪手がありました。が、さすがにそれは・・・。

ということで、初めて使おうと考えたのが Django の inclusion tag

djangoのアプリケーションディレクトリに templatetagsディレクトリを作って
その中に、extra_tags.pyなどのファイル名で下記のような自作のタグを作って入れておく。

from django import template
from models import Article

register = template.Library()

@register.inclusiontag('extra/latest.html')
def latest_article():
    articles = Article.objects.all().order_by('-id')[:5]
    return {'latest_articles': articles}

上記で指定した extra/latest.htmlの場所はTEMPLATE_DIRで指定したテンプレートの置き場所がルートになる。だからアプリケーションのディレクトリの下にテンプレートを入れるディレクトリを指定していれば

app/tempate/extra/latest.html

が、その置き場所になる。で、その置いたファイルはinclusion_tagの結果を吐き出すところで、この吐き出したものを他のテンプレートに組み込んで使うのだ。

extra/latest.html

{% if latest_article %}
{% for article in latest_articles %}
<p>{{ article.title }}</p>
<p>{{ article.text }}</p>
{% endfor %}

今回はサイドバーに使いたかったので、テンプレートのbase.htmlにこの結果を吐き出すようにしました。

template/base.html

{% load extra_tags %}

<div class="sidebar">
{% for article in latest_article %}
</div>

こんな感じ。

そして私がどこで引っかかったかと言えば、タグの使い方で引っかかった。

from django import template
from models import Article

register = template.Library()

@register.inclusiontag('base.html')
def latest_article():
    articles = Article.objects.all().order_by('-id')[:5]
    return {'latest_articles': articles}

こうして、base内で

base.html

{% extra_tags %}

<div class="sidebar">
{% for article in latest_article %}
<p>{{ article.title }}</p>
<p>{{ article.text }}</p>
</div>

こうした。

そうすると、inclusion_tag では結果のレンダ先にbase.htmlを指定しているから、そこに吐き出そうとする => base.htmlでは inclusion_tag が呼ばれている => inclusion_tag では … BUS ERROR 10

うーん。こう書いてみると何でもないこと、というより気づいて当然のことなのだけど初めて使ったものだから中々気づけなかった。その原因としては、inclusion_tag が関数を使用した時点で結果が返ってくる代物だと思っていたからだ。

割と何となくで書き始めることが多いのでそこは反省したい。