0

I am new to Django and have been making a sample project. I have been trying to use Generic Detailview. It seems that url redirection works fine but DetailView can't get primarykey from the url.

Main url.py::

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^',include('personal.urls')),
]  

Here is my app's urls.py code:

urlpatterns = [
 url(r'(?P<pk>\d+)/$',views.detailView.as_view(),name="detail"),]

View file for the DetailView:

from django.shortcuts import render
from django.views import generic
from .models import  Story


class detailView(generic.DetailView):
    model = Story
    template_name = 'personal/storydetail.html'

    def get_context_data(self, **kwargs):
        pk = kwargs.get('pk')  # this is the primary key from your URL
        print("PK:",pk)

Template Code:

{% block content %}
{{ Story.writer }}
<h6> on {{ Story.story_title }}</h6>
<div class = "container">
    {{ Story.collection }}
</div>
{% endblock %}

Story Class code:

class Story(models.Model):
     story_title = models.CharField(max_length=200) #Story title
     writer = models.CharField(max_length=200) #WriterName
     collection=models.CharField(max_length=200) #Collection/Book name

When I check primary key value on view it shows it 'NONE'. I can't find issue with the code. My pased url looks like : http://127.0.0.1:8000/personal/2/ where personal is the name of app and 2 should be taken as id.

Abhijeet Panwar
  • 1,837
  • 3
  • 26
  • 48

1 Answers1

1

The problem is that you are using kwargs instead of self.kwargs inside the get_context_data method. It should be something like:

def get_context_data(self, **kwargs):
    # You need to call super() here, so that the context from the DetailView is included
    kwargs = super(detailView, self).get_context_data(**kwargs)

    pk = self.kwargs['pk']  # No need for get() here -- if you get a KeyError then you have a problem in your URL config that should be fixe  # this is the primary key from your URL

    # edit kwargs as necessary
    ...
    return kwargs

In the get_context_data method, kwargs are those passed to the method to make up the context. They are different from self.kwargs, which are from the url pattern.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • It seems I was't clear in my question. when I check primary key using this it shows pk as null and this is the issue that why I get none as pk – Abhijeet Panwar May 04 '17 at 12:50
  • 1
    I am not sure you understand my answer. The code in your question is different. You are checking `kwargs`. You need to check `self.kwargs`. – Alasdair May 04 '17 at 12:52
  • 1
    `Story` (capitalised) is the class. In the `DetailView`, (and Python in general), the model instance is `story` (lowercase). Change your template to use `{{ story.writer }}` and so on. If you override `get_context_data`, make sure that you call `super()` as I have in my answer, otherwise you'll break the view. Finally, it would be better to name your view `DetailView` instead of `detailView` to match the Django convention. – Alasdair May 04 '17 at 13:02