Howto generic class-based views in django 1.3
This is a reminder for myself, to know how the new class-based generic views work. The code belongs to the GPL project e-cidadania. I’ll be posting as I code.
DETAILVIEW
The function-based code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def view_space_index(request, space_name): """ Show the index page for the requested space. This is a conglomerate of various modules. """ place = get_object_or_404(Space, url=space_name) extra_context = { 'entities': Entity.objects.filter(space=place.id), 'documents': Document.objects.filter(space=place.id), 'proposals': Proposal.objects.filter(belongs_to=place.id).order_by('-pub_date'), 'publication': Post.objects.filter(post_space=place.id).order_by('-post_pubdate'), } return object_detail(request, queryset = Space.objects.all(), object_id = place.id, template_name = 'spaces/space_index.html', template_object_name = 'get_place', extra_context = extra_context, ) |
The class-based code:
class ViewSpaceIndex(DetailView): """ Show the index page of a space. Get various extra contexts to get the information for that space. The get_object method searches in the user 'spaces' field if the current space is allowed, if not, he is redirected """ context_object_name = 'get_place' template_name = 'spaces/space_index.html' def get_object(self): space_name = self.kwargs['space_name'] for i in self.request.user.profile.spaces.all(): if i.url == space_name: return get_object_or_404(Space, url = space_name) self.template_name = 'not_allowed.html' return get_object_or_404(Space, url = space_name) def get_context_data(self, **kwargs): context = super(ViewSpaceIndex, self).get_context_data(**kwargs) place = get_object_or_404(Space, url=self.kwargs['space_name']) context['entities'] = Entity.objects.filter(space=place.id) context['documents'] = Document.objects.filter(space=place.id) context['proposals'] = Proposal.objects.filter(space=place.id).order_by('-pub_date') context['publication'] = Post.objects.filter(post_space=place.id).order_by('-post_pubdate') return context |
DELETEVIEW
Function-based:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @permission_required('spaces.delete_document') def delete_doc(request, space_name, doc_id): """ Delete an uploaded document """ place = get_object_or_404(Space, url=space_name) return delete_object(request, model = Document, object_id = doc_id, login_required = True, template_name = 'spaces/document_delete.html', template_object_name = 'doc', post_delete_redirect = '/', extra_context = {'get_place': place}) |
Class-based:
1 2 3 4 5 6 7 8 9 10 | class DeleteDocument(DeleteView): """ Delete an uploaded document. """ model = Document def get_queryset(self): objects = Document.objects.all().filter(id=self.kwargs['doc_id']) return objects |
LISTVIEW
Function-based:
1 2 3 4 5 6 7 8 9 10 11 12 | def list_all_docs(request, space_name): """ List all docuemnts stored within a space. """ place = get_object_or_404(Space, url=space_name) return object_list(request, queryset = Document.objects.all().filter(space=place.id).order_by('pub_date'), template_name = 'spaces/document_list.html', template_object_name = 'doc', extra_context = {'get_place': place}) |
Class-based:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class ListDocs(ListView): """ List all documents stored whithin a space. """ paginate_by = 25 context_object_name = 'document_list' def get_queryset(self): place = get_object_or_404(Space, url=self.kwargs['space_name']) objects = Document.objects.all().filter(space=place.id).order_by('pub_date') return objects def get_context_data(self, **kwargs): context = super(ListDocs, self).get_context_data(**kwargs) context['get_place'] = get_object_or_404(Space, url=self.kwargs['space_name']) return context |
REDIRECTVIEW
Function-based:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def go_to_space(request): """ This view redirects to the space selected in the dropdown list in the index page. It only uses a POST petition. The 'raise Http404' isn't necessary, since if a space doesn't exist, it doesn't show, but just for security we will leave it. """ place = get_object_or_404(Space, name = request.POST['spaces']) if request.POST: return redirect('/spaces/' + place.url) raise Http404 |
Class-based:
NOTE: Class-based redirects in django 1.3 only accepts GET petitions, instead of the recommended POST in django 1.2. This issue is fixed in 1.3.x
1 2 3 4 5 6 7 8 9 10 11 | class GoToSpace(RedirectView): """ This class redirects the user to a spaces after getting a GET petition. A 'raise Http404' is not necessary since a the objects the user can access are only the ones that are in the DB. """ def get_redirect_url(self, **kwargs): self.place = get_object_or_404(Space, name = self.request.GET['spaces']) return '/spaces/{0}'.format(self.place.url) |