Runner
Runner

Reputation: 115

Django template url not correctly getting parameter

I am able to print the correct object pk in the template using a template tag, but when I use the same code in a url parameter it does not show up.

I am trying to using the first result pk from a many to many relationship to create a url parameter to link to that page. It works when I manually input the pk, but when I use category.quote_set.first.pk it does not work.

"category" is is queryset of all categories, which have a many to many relationship to quotes.
<p>{{ category.quote_set.first.pk }}</p> <p><a href="{% url 'mottos:quote' category.quote_set.first.pk %}"></a></p>

The url file has path('motto/<int:pk>/', views.QuoteView.as_view(), name='quote'),

Going to the page shows an error Reverse for 'quote' with arguments '('',)' not found. 1 pattern(s) tried: ['motto\\/(?P<pk>[0-9]+)\\/$'] I believe the reason for this is that the url is created first, and the category.quote_set.first.pk is created after the page, but that is just my theory.

View for the page:

class CategoryView(generic.ListView,ContextMixin):
    template_name = 'mottos/category.html'
    context_object_name = 'motto_list'

    def get_queryset(self):
        return Quote.objects.all().annotate(score=Avg('vote__score')).filter(categories__slug=self.kwargs['cat

egory']).order_by('-score')

Upvotes: 0

Views: 96

Answers (2)

Runner
Runner

Reputation: 115

I was able to get the quote pk by using

{% for quote in category.quote_set.all|slice:"0:1" %}
 <p><a href="{% url 'mottos:quote' quote.pk %}"></a></p>
% endfor %}

Since I only wanted the first quote, I used slice:"0:1" to only get the first quote, and then used the pk from that result.

Upvotes: 0

shafikshaon
shafikshaon

Reputation: 6404

Try something like this

{% for quote in quote_list %}
   <p>
      <a href="{{ quote.get_absolute_url }}"></a>
   </p>
{% endfor %}

Another solution: in you views fie add this:

def get_context_data(self, **kwargs):
        context['quote_list'] = Quote.objects.all().annotate(score=Avg('vote__score')).filter(categories__slug=self.kwargs['category']).order_by('-score')
        return context

Then in your template add this

{% for quote in quote_list %}
   <p>
      <a href="{% url 'quote' quote.id %}"></a>
   </p>
{% endfor %}

Upvotes: 1

Related Questions