Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Generic Views using decorator login_required

Tags:

django

I'm new with django and I finished the 4 part tutorial on djangoproject.com

My problem is I want to put a login authentication on my polls app. I've use the decorator @login_required and it works properly but under my views.py I have only vote() method.

my views.py under "polls folder"

from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import never_cache
from django.core.urlresolvers import reverse
from django.template import RequestContext
from polls.models import Poll, Choice


@login_required
@never_cache
def vote(request, poll_id):
    p = get_object_or_404(Poll, pk=poll_id)
    try:
        selected_choice = p.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render_to_response('polls/detail.html', {
            'poll': p,
            'error_message': "You didn't select a choice.",
        }, context_instance=RequestContext(request))
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
    return HttpResponse("You're voting on poll %s." % poll_id) 

my urls.py under "polls folder"

from django.conf.urls.defaults import patterns, include, url
from django.views.generic import DetailView, ListView
from polls.models import Poll

urlpatterns = patterns('',
    url(r'^$',
        ListView.as_view(
            queryset = Poll.objects.order_by('-pub_date')[:5],
            context_object_name = 'latest_poll_list',
            template_name = 'polls/index.html'), name='poll_lists'),
    url(r'^(?P<pk>\d+)/$',
        DetailView.as_view(
            model = Poll,
            template_name = 'polls/detail.html'), name='poll_details'),
    url(r'^(?P<pk>\d+)/results/$',
        DetailView.as_view(
            model = Poll,
            template_name = 'polls/results.html'), name = 'poll_results'),
    url(r'^(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
)

under my urls.py I have use generic views.

Problem is: how will I put login required under the "index" of the polls app. So that the user will login first before he/she can view the available polls.

Current is: I have used login required under my views.py and method vote(), It will require login after voting.

anyone can help me out?

Thanks, Justin

like image 807
justin Avatar asked Apr 23 '12 05:04

justin


People also ask

How do you use decorators in class-based view in django?

To decorate every instance of a class-based view, you need to decorate the class definition itself. To do this you apply the decorator to the dispatch() method of the class. The decorators will process a request in the order they are passed to the decorator.

How generic views are used in django?

Django's generic views were developed to ease that pain. They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to write too much code.

Should I use generic views django?

The intention of Generic Views is to reduce boilerplate code when you repeatedly use similar code in several views. You should really use it just for that. Basically, just because django allows something you are doing generically you shouldn't do it, particularly not when your code becomes not to your like.

What is @method_decorator?

The method_decorator decorator transforms a function decorator into a method decorator so that it can be used on an instance method.


1 Answers

1nd approach

In urls.py:

urlpatterns = patterns('',
    url(r'^$',
        login_required(ListView.as_view(
            queryset = Poll.objects.order_by('-pub_date')[:5],
            context_object_name = 'latest_poll_list',
            template_name = 'polls/index.html'), name='poll_lists')),
)

2nd approach

In views.py:

class IndexView(ListView):
    queryset = Poll.objects.order_by('-pub_date')[:5]
    context_object_name = 'latest_poll_list'
    template_name = 'polls/index.html'

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):        
        return super(IndexView, self).dispatch(request, *args, **kwargs)

then in urls.py

urlpatterns = patterns('',
        url(r'^$',
            IndexView.as_view(), name='poll_lists'),
    )
like image 79
San4ez Avatar answered Oct 04 '22 01:10

San4ez