Jordan Lashmar
Jordan Lashmar

Reputation: 123

Key Error in a class based DetailView

I've had this problem a few times before but I've always been able to work it out. This time I cant. Its just returning:

"Key error at streams/sport_slug 'pk' "

The error at at line 34 in the Views, which I have highlighted below:

Views.py:

class StreamSport(ListView):
    template_name = "stream/stream-index.html"
    context_object_name = 'stream_list'

    def get_queryset(self):
        self.sport = get_object_or_404(Sport, sport_slug=self.kwargs['sport_slug'])
        *self.pk = get_object_or_404(Video, pk=self.kwargs['pk'])*
        return Video.objects.filter(sport=self.sport, pk=self.pk)

URLs.py:

app_name = 'streams'

urlpatterns = [
    path('', StreamIndex.as_view(), name='stream-index'),
    path('<slug:sport_slug>/', StreamSport.as_view(), name='stream-sport'),
    path('<slug:sport_slug>/<int:pk>/', StreamDetail.as_view(), name='detail'),

stream-index.html:

<a href="{% url 'streams:detail' video.sport.sport_slug video.pk %}"

Edit: As Lemayzeur I got myself confused. The key error was caused by an attempt at fixing another error. I thought I made progress when instead I was moving backwards. The original error, and the one I am back to now is a "Reverse for 'detail' with arguments" error.

To clarify, what I am trying to do is build a ListView that lists out all the videos in a model, then link each of those videos to its own Details page. Its the DetailView itself thats giving me some issue:

class StreamDetail(DetailView):
    model = Video
    template_name = 'stream/detail.html'

    def get_queryset(self):
        self.sport = get_object_or_404(Sport, sport_slug=self.kwargs['sport_slug'])
        self.pk = Video.objects.filter(pk=self.kwargs['pk'])
        return Video.objects.filter(sport=self.sport, pk=self.pk)

This is the error it is giving me:

Reverse for 'detail' with arguments '(2,)' not found. 1 pattern(s) tried: ['stream\\/(?P<sport_slug>[-a-zA-Z0-9_]+)\\/(?P<pk>[0-9]+)\\/$']

The traceback itself is extremely unhelpful and it just pointing to the bootstrapcdn in the basefile.

stream-index.html:

{% for video in stream_list %}
  <div class="card" style="width: 20rem;margin-left: 2rem;">
            <img class="card-img-top" src="{{video.headline_image.url}}" alt="Card image cap" style="width: 20rem;">
            <div class="card-body" style="width: 18rem;">
              <h5 class="card-title"><a href="{% url 'streams:detail' video.id %}">{{video.name}}</a></h5>
              <p class="card-text" style="width: 18rem;">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
              <a href="{% url 'streams:detail' video.sport.sport_slug video.pk %}" class="btn btn-success">Watch Now</a>
              <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
            </div>
        </div>
{% endfor %}

Upvotes: 1

Views: 387

Answers (2)

Lemayzeur
Lemayzeur

Reputation: 8525

The error is not in the url that you have posted: Check this line

instead of

<h5 class="card-title"><a href="{% url 'streams:detail' video.id %}">{{video.name}}</a></h5>

it should be

<h5 class="card-title"><a href="{% url 'streams:detail' video.sport.sport_slug video.pk %}">{{video.name}}</a></h5>

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599510

As you show in the full snippet, in your template you are only passing video.id to the url tag, whereas the detail URL requires id and slug. Make sure you pass them both:

<a href="{% url 'streams:detail' video.sport.sport_slug video.id %}">

Upvotes: 1

Related Questions