dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[django]URLconfで指定した数値(integer)が文字列(unicode)になる

Google App Engine + Djangoという組み合わせでのほんとにちょっとした話。
Djangoのバージョンは1.5 です。

urls.pyとかで

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from .views import MyListView, MyDetailView

urlpatterns = patterns('',
    url(r'^my_app/$', MyListView.as_view(), name='my_list'),
    url(r'^my_app/(?P<pk>\d+)/$', MyDetailView.as_view(), name='my_detail'),
)

などと書いていて、ビュー側(ここではMyDetailView)には

class MyDetailView(View):
    template_name = 'my_detail.html'

    def get(self, request, pk=None):
        template_values = {
                'movie': MyModel.get_by_id(pk),
                }

        return render(request, self.template_name, template_values)

と書いているとします。
MyModelndb.Modelを継承したモデルクラス。

この状態で正しいエンティティのIDをURLに含めてアクセスしても、
なぜかMyModel.get_by_id(pk)の結果がNoneになっている。。。

おかしいなと思ってlogger.info(type(pk))とすると、

INFO  2014-10-06 14:29:49,962 views.py:60] <type 'unicode'>

というわけで、pkは数値ではなく文字列として扱われてるみたいです。

そこでDjangoのリファレンスを読むと、

f:id:dackdive:20141007002520p:plain

あ...そうですか...

というわけで、ビュー側で明示的に変換してあげましょう。

class MyDetailView(View):
    template_name = 'movie_detail.html'

    def get(self, request, pk=None):
        template_values = {
                'movie': MyModel.get_by_id(int(pk)),  # <- integerに変換
                }

        return render(request, self.template_name, template_values)