Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Django e-commerce part12 Using Links for Model Instances

Model Instanceへの、Linksをurls.py のnameを使ってやってみる。さらにget_absolute_url がbestpracticeのよう。

  • templates/products/product_list.html に試しに、linkを挿入してみる。
{% for object in object_list %}
<tr>
    <td>{{ object.id }}</td>
    <td><a href='/products/{{ object.id }}'>{{ object.title }}</td>
</tr>
{% endfor %}

'/products/{{ object.id }}' で、product_detailへのリンクの作成が可能。

  • 上記でもリンクは作成可能だが、cbvは、pkを参照にするため、情報に齟齬が発生しないように、
{% for object in object_list %}
<tr>
    <td>{{ object.id }}</td>
    <td><a href='/products/{{ object.pk }}'>{{ object.title }}</td>
</tr>
{% endfor %}

にしておく方がbetter のようです。

  • ただ、これではちょっと動的ではない。/products/ この部分がね。

  • そこで利用するのが、products/urls.py の detailviewのname。

    <td><a href='{% url "product_detail" pk=object.pk %}'>{{ object.title }}</td>

てな感じに変更すると、さっきと同じリンクになる。

  • {% url "" 左のnameに渡す引数 %}

  • さらに、進化すると、

    <td><a href='{{ object.get_absolute_url }}'>{{ object.title }}</td>

になる。 これは、多分、modelのdefで、get_absolute_url を設定して、instanceごとに、get_absolute_urlをreturnするように設定しておくということだと思われる。

get_absolute_url とreverse で動的なリンクを渡す

  • products/models.py
class Product(models.Model):
...
    def get_absolute_url(self):
        return "/products/%s" %(self.pk)

これが一番直接的な表示の方法。

  • さらに、reverseを使うと、よりダイナミックになる。
from django.core.urlresolvers import reverse
...
class Product(models.Model):
...
    def get_absolute_url(self):
        return reverse("product_detail", kwargs={"pk": self.pk})

これは便利!! reverse ("", kwargs={"key": value}) kwargsは、urlpatternに渡す引数

ちょっと設定でミスったところ

    url(r'^(?P<pk>\d+)$', ProductDetailView.as_view(), name='product_detail'),

前の章でこんな感じで設定してたが、$ が不要だった。 正しくは、

    url(r'^(?P<pk>\d+)$', ProductDetailView.as_view(), name='product_detail'),

でした。