独自フィルターが必要になった理由
allauthのsocialaccountで、プロバイダ(twitter)から取得する画像の処理をviews.pyに書くのが面倒だったので独自フィルターを作りました。
twitterから取得できるprofile_image_url_https
は、小さいサイズ(_normal)なので、独自フィルターを作成してこれを通常のサイズに変更していきます。
Django-allauthの仕様で書いてありますが、allauthが無くても基本は同じです。
twitterの画像の仕組み
twitter APIで取得できるURL
# デフォルト
profile_image_url_http = "https://pbs.twimg.com/profile_images/12341234/hoge_normal.png"
ファイル名の後ろに付く_normal
が画像を小さくしてしまっているのでこれを加工する。
指定 | サイズ |
---|---|
_mini | 24 × 24 |
_normal | 48 × 48 |
_bigger | 73 × 73 |
無し | オリジナル |
もしviews.py内で処理したい場合は
# userのtwitter情報を取得
twitter_accunt = user.socialaccount_set.filter(provider='twitter')
# プロフ画像のURLを取得
t_image = twitter_accunt.values("extra_data")[0]["extra_data"]["profile_image_url_https"]
# _normalをreplaceで削除(置換)
t_image.replace("_normal", "")
これでオリジナルサイズの画像のURLが取得できる。
プロフ画像を取得するコードがちょっとナンセンスな気がしますが・・・w
もっとスマートにできる気も?
独自テンプレートフィルターを作る
前置きが長くなりましたが早速作ってみる。
-
アプリケーション直下に
templatetags
のディレクトリを作成 -
templatetags
内に、空の__init__.py
ファイルを作成 -
templatetags
内に、hoge.py
ファイルを作成
project dir
|- appname dir
|- templatetags
|- __init__.py
|- hoge.py
hoge.pyは{% load hoge %}と.htmlで呼び出す名前になります。
ここまで出来たらhoge.py
ファイルにフィルターの中身を書いていく。
今回は画像のURLの_normal
を削除したいので、そのフィルターを作る。
# この2つはコピペでOK
from django import template
register = template.Library()
# twitter_replaceというフィルターを登録
@register.filter
def twitter_replace(value):
# replaceで書き換える
return value.replace("_normal","")
これでtwitter_replace
をテンプレートフィルターとして使えば、置換されるようになります。
テンプレートに反映させる
<!-- allauthのsocialaccount用 -->
{% load socialaccount %}
<!-- 先程作ったファイルを読み込む -->
{% load hoge %}
<!-- userはviews.pyの変数 -->
{% get_social_accounts user as accounts %}
<img src="{{ accounts.twitter.0.extra_data.profile_image_url_https | twitter_replace }}">
これでオリジナルサイズの画像が表示できるようになります
表示するページが1ページならviews.pyに書いても良いかと思いますが、複数ページに表示したりfor文で回す時などフィルターを作った方が使い回せるので便利だと感じました。
今回の記事とは関係ありませんが、いい感じに{% include %}
で呼び出すのもありなのかな?
補足
-
INSTALLED_APPS
にあるアプリにしか独自テンプレートフィルターは作れない。 - 独自テンプレートフィルターを作成した後は、仮想サーバーを再起動しないと反映されない。