Reputation: 3904
This is my post detail view and it works perfectly.
class PostDetailView(DetailView):
model = Post
context_object_name = 'post'
template_name = 'posts/detail.html'
def get_queryset(self, *args, **kwargs):
request = self.request
pk = self.kwargs.get('pk')
queryset = Post.objects.filter(pk=pk)
return queryset
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
content['comments'] = Comment.objects.all()
return context
However, when I add get method to the view it does not work anymore.
def get(self, request, *args, **kwargs):
# how to return here so that it works exactly like before
After adding get method get_queryset
and get_context_data
do not gets called automatically and the context is empty in the template. So what would be the get method so that it works exactly like before?
EDIT My target is to do something like this
if request.is_ajax():
html = render_to_string('comments/detail.html') # ajax reply with html data
return HttpResponse(html)
return render 'posts/detail.html'
So where do I put this code and still want to keep call all methods such as get_queryset
and get_context_data
to be called automatically?
Upvotes: 5
Views: 4221
Reputation: 149
I know this is a rather old thread, but the solution seems simple: you need to call the original get()
method at the end of your overriding get()
method by calling something like:
return super(PostDetailView, self).get(request, *args, **kwargs)
Upvotes: 1
Reputation: 1941
One general piece of advice I want to share:
Before overriding any attribute, one must have deep knowledge of what is the significance of that attribute (callable or not callable). This advice applies to any language or framework. Suppose when someone overrides the get
in Django, all the methods that are being called from get
will not be invoked unless one invokes that from overridden get
. So you should see the source of get
and observe that methods are called from that.
Upvotes: 2
Reputation: 477608
The idea of views like a DetailView
, ListView
, etc. is that it implements the boilerplate logic for you. So it has defined a function def get(self, request, *args, **kwargs)
that is used to render the logic. You can usually tweak a few things by specifying the model
, queryset
, etc. without reimplementing the entire view.
For a DetailView
[Django-doc], the logic is implemented in the BaseDetailView
you can inspect the source code [GitHub]:
class BaseDetailView(SingleObjectMixin, View): """A base view for displaying a single object.""" def get(self, request, *args, **kwargs): self.object = self.get_object() context = self.get_context_data(object=self.object) return self.render_to_response(context)
Upvotes: 6