Archive for the ‘generic views’ Category

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)