I'm building a demo-website for a local jewellery store, and I'm trying to create a list of jewellery brands (ListView) and link each to its description (DetailView) in another page. I've spent a solid 15 hours trying to link my ListView and my DetailView together and I haven't fixed anything. These are the views I'm working with:
views
class BrandView(ListView):
template_name = 'products.html'
queryset = models.Brand.objects.order_by('brand_name')
context_object_name = 'brand_list'
For this first view, I created a template that displays each object from the queryset as a link to its corresponding detail page, which should be represented by the next view:
class TextView(DetailView):
template_name = 'brands/brand_text.html'
context_object_name = 'brand'
def get(self, request, slug):
# Grabs the Brand object that owns the given slug
brand = models.Brand.objects.get(slug = slug)
# renders self.template_name with the given context and model object
return render(request, self.template_name, self.context_object_name)
I've also tried writing the last view as a regular function, but this doesn't accomplish anything either:
def text_view(request, slug):
brand = models.Brand.objects.get(slug = slug)
return render(request, 'brands/brand_text.html', {'brand': brand,})
Basically, when I click on an object from ListView, the object's slug is added to the url, but the page doesn't change. So how can I successfully link my two views so that the DetailView fetches the information given from the ListView?
Perhaps my templates might prove handy:
templates
brand_text.html
{% block content %}
<div class= "brands" style="animation: fadein 1.5s 1;">
<p>
<a class = "nav_link" href="{% url 'products' %}">Back</a>
</p>
</div>
<div class= "brand_descriptions">
<p>{{ brand.description }}</p>
</div>
{% endblock %}
products.html
{% block content %}
<div class= "brands" style="animation: fadein 1.5s 1;">
{% for item in brand_list %}
<p>
<a class = "nav_link" href="{% url 'brand_text' item.slug %}">{{ item.brand_name }}</a>
</p>
{% endfor %}
</div>
{% endblock %}
UPDATE 08/02/2016:
URL Patterns
url(r'^products/', BrandView.as_view(), name = 'products'),
url(r'^products/(?P<slug>[-\w]+)', TextView.as_view(), name = 'brand_text'),
(This is my first question, so I apologize if it's too long!)
Your problem is in your url patterns. You have missed out the dollar from the end of your regex. That means that /products/my-slug/
is matched by the regex for BrandView
instead or TextView
. Change it to:
url(r'^products/$', BrandView.as_view(), name = 'products'),
url(r'^products/(?P<slug>[-\w]+)$', TextView.as_view(), name = 'brand_text'),
Note that you can simplify your detail view to:
class TextView(DetailView):
template_name = 'brands/brand_text.html'
You don't need to set context_object_name
because the default is already 'brand'. It's not usually a good idea to override get
for generic class based views - you either lose or have to replicate much of the functionality of the view.