{"id":269,"date":"2011-08-15T10:47:41","date_gmt":"2011-08-15T14:47:41","guid":{"rendered":"http:\/\/dashdrum.com\/blog\/?p=269"},"modified":"2011-11-13T21:23:52","modified_gmt":"2011-11-14T01:23:52","slug":"class-based-views-a-listview-example","status":"publish","type":"post","link":"https:\/\/dashdrum.com\/blog\/2011\/08\/class-based-views-a-listview-example\/","title":{"rendered":"Class-Based Views &#8211; A ListView Example"},"content":{"rendered":"<p>I put this here mostly for my own documentation.<\/p>\n<p>Before:<\/p>\n<pre>@permission_required('training.view_signupdetail') \r\ndef class_history_attend(request,class_id):\r\n    \r\n    tc = get_object_or_404(TrainingClass,id=class_id)\r\n            \r\n    queryset = SignupDetail.objects.filter(schedule__training_class = tc,attended = True).order_by('session__user__username')\r\n    \r\n    params = {'queryset': queryset,\r\n              'template_name': 'class_history.html',\r\n              'extra_context': {'tc': tc}}\r\n    return object_list(request, **params)    <\/pre>\n<p>After:<\/p>\n<pre>class ClassHistoryAttendView(ListView):\r\n    ## Set the template name\r\n    template_name = 'class_history.html'  \r\n\r\n    ## Override dispatch to apply the permission decorator\r\n    @method_decorator(permission_required('training.view_trainingclass'))\r\n    def dispatch(self, *args, **kwargs):\r\n        return super(ClassHistoryAttendView, self).dispatch(*args, **kwargs)  \r\n    \r\n    ## Define get_queryset to bring in the supplied class number and build the query\r\n    def get_queryset(self):\r\n        self.tc = get_object_or_404(TrainingClass,id=self.kwargs.get('class_id',None))\r\n        return SignupDetail.objects.filter(schedule__training_class = self.tc,attended = True).order_by('session__user__username')\r\n    \r\n    ## Override get_context_data to add the class number to the context for use by the template\r\n    def get_context_data(self, **kwargs):\r\n        context = super(ClassHistoryAttendView, self).get_context_data(**kwargs)\r\n        context['tc'] = self.tc\r\n        return context<\/pre>\n<p>UPDATE:<\/p>\n<p>The override of <code>dispatch<\/code> allows the application of the permission decorator.  Note the <code>@method_decorator<\/code> wrapper around the traditional view decorator for permission use.<\/p>\n<p>The other two method overrides are necessary to access the <code>self<\/code> instance of the object.<\/p>\n<p>An easier example still uses the permission override, but others are not needed.<\/p>\n<p>Before:<\/p>\n<pre>@permission_required('b2c.view_event')\r\ndef list_event(request):\r\n    params = {'queryset': Event.objects.all(),\r\n              'paginate_by': DEFAULT_PAGINATION,\r\n              'template_name': 'event_list.html'}\r\n    return object_list(request, **params)<\/pre>\n<p>After:<\/p>\n<pre>class ListEventView(ListView):\r\n    ## The basics\r\n    template_name = 'event_list.html'  \r\n    paginate_by = DEFAULT_PAGINATION\r\n    queryset = Event.objects.all()\r\n\r\n    ## Override dispatch to apply the permission decorator\r\n    @method_decorator(permission_required('b2c.view_event'))\r\n    def dispatch(self, *args, **kwargs):\r\n        return super(ListEventView, self).dispatch(*args, **kwargs) <\/pre>\n<p>Note that the paginate_by variable is set in this example.<\/p>\n<p>Also<\/p>\n<p>These are the imports needed:<\/p>\n<pre>from django.views.generic import ListView\r\nfrom django.utils.decorators import method_decorator<\/pre>\n<p>In <code>urls.py<\/code>, adjust the definition to call the <code>as_view<\/code> method of the class:<\/p>\n<pre>url(r'^list_event\/$',ListEventView.as_view(),name='event_list')<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I put this here mostly for my own documentation. Before: @permission_required(&#8216;training.view_signupdetail&#8217;) def class_history_attend(request,class_id): tc = get_object_or_404(TrainingClass,id=class_id) queryset = SignupDetail.objects.filter(schedule__training_class = tc,attended = True).order_by(&#8216;session__user__username&#8217;) params = {&#8216;queryset&#8217;: queryset, &#8216;template_name&#8217;: &#8216;class_history.html&#8217;, &#8216;extra_context&#8217;: {&#8216;tc&#8217;: tc}} return object_list(request, **params) After: class ClassHistoryAttendView(ListView): ## Set the template name template_name = &#8216;class_history.html&#8217; ## Override dispatch to apply the permission decorator @method_decorator(permission_required(&#8216;training.view_trainingclass&#8217;)) &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/dashdrum.com\/blog\/2011\/08\/class-based-views-a-listview-example\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Class-Based Views &#8211; A ListView Example&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-269","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts\/269","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/comments?post=269"}],"version-history":[{"count":4,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts\/269\/revisions"}],"predecessor-version":[{"id":287,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/posts\/269\/revisions\/287"}],"wp:attachment":[{"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/media?parent=269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/categories?post=269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dashdrum.com\/blog\/wp-json\/wp\/v2\/tags?post=269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}