同一テンプレート内にてURLの動的変更について
<p>カテゴリー</p>
<ul>
{% for category in categories %}
<li><a href="{% url 'index' category.slug %}">{{ category.name }}</a></li>
{% endfor %}
</ul>
<p>場所</p>
<ul>
{% for location in locations %}
<li><a href="{% url 'index' location.slug %}">{{ location.name }}</a></li>
{% endfor %}
</ul>
というリンクがあり、categoryをクリックして遷移した先のページURLは/category/だとします。
この状態でlocationをクリックしてURLを/category/location/としたい場合、
<li><a href="{% url 'index' category.slug location.slug %}">{{ location.name }}</a></li>
とすればいいのですが、こういった動的なURLの生成を実現するためにはどうすればいいのでしょうか?
Updated
ソースコードも全て載せます。テンプレートも少し詳しく記載したので御覧ください
from django.db import models
class Category(models.Model):
parent = models.ForeignKey('Category', related_name='children', null=True, blank=True)
name = models.CharField(max_length=255)
slug = models.SlugField()
@property
def dispatch(self):
# parent が nullであれば親カテゴリなので自分自身を返す
if not self.parent:
return self
# そうでなければ親カテゴリ(parent)を返す
else:
return self.parent
def __str__(self):
return self.name
class Location(models.Model):
parent = models.ForeignKey('Location', related_name='children', null=True, blank=True)
name = models.CharField(max_length=255)
slug = models.SlugField()
@property
def dispatch(self):
# parent が nullであればStateなので自分自身を返す
if not self.parent:
return self
# そうでなければState(parent)を返す
else:
return self.parent
def __str__(self):
return self.name
class PostQuerySet(models.QuerySet):
def filter_category(self, category):
if not category.parent:
# Big Category であれば、childrenのカテゴリに所属するPostをfilter
return self.filter(category__in=category.children.all())
else:
# Small Category であれば、categoryに所属するPostをfilter
return self.filter(category=category)
def filter_location(self, location):
if not location.parent:
# State であれば、childrenのlocationに所属するPostをfilter
return self.filter(location__in=location.children.all())
else:
# Region であれば そのlocationに所属するPostをfilter
return self.filter(location=location)
class Post(models.Model):
category = models.ForeignKey(Category)
location = models.ForeignKey(Location)
title = models.CharField(max_length=255)
text = models.CharField(max_length=255)
objects = PostQuerySet.as_manager()
def __str__(self):
return self.title
urlpatterns = [
url(r'^all-categories/$', views.all_cat_index, name='index'),
url(r'^all-categories/(?P<loc>[-\w]+)/$', views.all_cat_loc_index, name='index'),
url(r'^(?P<cat>[-\w]+)/$', views.cat_index, name='index'),
url(r'^(?P<cat>[-\w]+)/(?P<loc>[-\w]+)/$', views.cat_loc_index, name='index'),
]
def all_cat_index(request):
big_cats = Category.objects.filter(parent__isnull=True)
states = Location.objects.filter(parent__isnull=True)
c = {
'big_cats': big_cats,
'states': states,
'posts': Post.objects.all()
}
return render(request, 'classifieds/index.html', c)
def all_cat_loc_index(request, loc):
location = get_object_or_404(Location, slug=loc)
c = {
'big_cats': Category.objects.filter(parent__isnull=True),
'state': location.dispatch,
'posts': Post.objects.filter_location(location).all()
}
return render(request, 'classifieds/index.html', c)
def cat_index(request, cat):
category = get_object_or_404(Category, slug=cat)
c = {
'big_cat': category.dispatch,
'states': Location.objects.filter(parent__isnull=True).all(),
'posts': Post.objects.filter_category(category).all()
}
return render(request, 'classifieds/index.html', c)
def cat_loc_index(request, cat, loc):
category = get_object_or_404(Category, slug=cat)
location = get_object_or_404(Location, slug=loc)
c = {
'big_cat': category.dispatch,
'state': location.dispatch,
'posts': Post.objects.filter_category(category).filter_location(location).all()
}
return render(request, 'classifieds/index.html', c)
{% extends 'base.html' %}
{% block left %}
<p>[カテゴリー]</p>
<ul>
{% if big_cat %}
<li><a href="{% url 'classifieds:index' param %}">{{ big_cat.name }}</a></li>
{% for small_cat in big_cat.children.all %}
<li><a href="{% url 'classifieds:index' param %}">{{ small_cat.name }}</a></li>
{% endfor %}
{% else %}
{% for big_cat in big_cats %}
<li><a href="{% url 'classifieds:index' param %}">{{ big_cat.name }}</a></li>
{% endfor %}
{% endif %}
</ul>
<p>[フィルター]</p>
<ul>
{% if state %}
<li><a href="{% url 'classifieds:index' param %}">{{ state.name }}</a></li>
{% for region in state.children.all %}
<li><a href="{% url 'classifieds:index' param %}">{{ region.name }}</a></li>
{% endfor %}
{% else %}
{% for state in states %}
<li><a href="{% url 'classifieds:index' param %}">{{ state.name }}</a></li>
{% endfor %}
{% endif %}
</ul>
{% endblock %}
{% block content %}
<ul>
{% for post in posts %}
<li>{{ post.title }} | {{ post.category }} | {{ post.location }}</li>
{% endfor %}
</ul>
{% endblock %}
つまり
<a href="{% url 'index' big_cat.slug %}">{{ big_cat.name }}</a>
をクリックして遷移するページは/category/で、このときにこのリンクを
<a href="{% url 'index' big_cat.slug state.slug %}">
というように、big_cat.slugがすでに含まれている状態に動的に変化させたいです。