CourseListView cleanup in preparation for #294
authorBryan <btbonval@gmail.com>
Tue, 4 Mar 2014 09:49:51 +0000 (04:49 -0500)
committerBryan <btbonval@gmail.com>
Tue, 4 Mar 2014 09:49:51 +0000 (04:49 -0500)
karmaworld/apps/courses/views.py
karmaworld/templates/courses/course_list.html
karmaworld/urls.py

index cf4c140c1de9381fb2fa37c7d3d11687704b42df..da86778175a6c0b8999df3cccbca8aca70910f5a 100644 (file)
@@ -5,17 +5,16 @@
 
 import json
 
-from django.conf import settings
 from django.core import serializers
 from django.core.exceptions import MultipleObjectsReturned
 from django.core.exceptions import ObjectDoesNotExist
 
-from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound
+from django.http import HttpResponse, HttpResponseBadRequest
+from django.views.generic import View
 from django.views.generic import DetailView
 from django.views.generic import TemplateView
-from django.views.generic.edit import ProcessFormView
-from django.views.generic.edit import ModelFormMixin
 from django.views.generic.list import ListView
+from django.views.generic.edit import CreateView
 
 from karmaworld.apps.courses.forms import CourseForm
 from karmaworld.apps.courses.models import Course
@@ -29,49 +28,58 @@ FLAG_FIELD = 'flags'
 USER_PROFILE_FLAGS_FIELD = 'flagged_courses'
 
 
-class CourseListView(ListView, ModelFormMixin, ProcessFormView):
-    """ Simple ListView for the front page that includes the CourseForm """
+# https://docs.djangoproject.com/en/1.5/topics/class-based-views/mixins/#an-alternative-better-solution
+class CourseListView(View):
+    """
+    Composite view to list all courses and processes new course additions.
+    """
+
+    def get(self, request, *args, **kwargs):
+        return CourseListSubView.as_view()(request, *args, **kwargs)
+
+    def post(self, request, *args, **kwargs):
+        ret = CourseAddFormView.as_view()(request, *args, **kwargs)
+        # Check to see if the form came back with errors.
+        if hasattr(ret, 'context_data') and \
+           ret.context_data.has_key('form') and \
+           not ret.context_data['form'].is_valid():
+            # Invalid form. Render as if by get(), but replace the form.
+            badform = ret.context_data['form']
+            request.method = 'GET' # trick get() into returning something
+            ret = self.get(request, *args, **kwargs)
+            # Replace blank form with invalid form.
+            ret.context_data['course_form'] = badform
+        return ret
+
+
+class CourseListSubView(ListView):
+    """ Lists all courses. Called by CourseListView. """
     model = Course
-    form_class = CourseForm
-    object = None
 
     def get_context_data(self, **kwargs):
         """ Add the CourseForm to ListView context """
         # get the original context
-        context = super(CourseListView, self).get_context_data(**kwargs)
+        context = super(CourseListSubView, self).get_context_data(**kwargs)
         # get the total number of notes
         context['note_count'] = Note.objects.count()
         # get the course form for the form at the bottom of the homepage
-        context['course_form'] = kwargs.get('course_form', CourseForm())
-        if context['course_form'].errors:
-            # if there was an error in the form
-            context['jump_to_form'] = True
+        context['course_form'] = CourseAddFormView.form_class()
 
         # Include "Add Course" button in header
         context['display_add_course'] = True
 
-        # Include settings constants for honeypot
-        for key in ('HONEYPOT_FIELD_NAME', 'HONEYPOT_VALUE'):
-            context[key] = getattr(settings, key)
-
         return context
 
-    def get_success_url(self):
-        """ On success, return url based on urls.py definition. """
-        return self.object.get_absolute_url()
-
-    def form_invalid(self, form, **kwargs):
-        """ override form_invalid to populate object_list on redirect """
-        kwargs['is_error'] = True
-        kwargs['course_form'] = form
-        self.object_list = self.get_queryset()
-        kwargs['object_list'] = self.object_list
-        # hard code errors for the dynamically named honeypot field.
-        # This bit will not be necessary when the form is dynamically
-        # generated by Django rather than hard coded in the template.
-        kwargs['honeypot_errors'] = [x for x in form.errors['honeypot']] \
-            if 'honeypot' in form.errors else []
-        return self.render_to_response(self.get_context_data(**kwargs))
+
+class CourseAddFormView(CreateView):
+    """ Processes new course additions. Called by CourseListView. """
+    model = Course
+    form_class = CourseForm
+
+    def get_template_names(self):
+        """ template_name must point back to CourseListView url """
+        # TODO clean this up. "_list" template might come from ListView above.
+        return ['courses/course_list.html',]
 
 
 class CourseDetailView(DetailView):
index c7d16ed7c5ce4085a93bf25ef33f82c982e9ee22..a7781f86073905835640648b0e8b4c9e1e61c414 100644 (file)
@@ -18,7 +18,7 @@
 <script>
 $(document).ready(function() {
   // If there were form errors, open the form and jump to it
-  var jump_to_form = {% if jump_to_form %}true{% else%}false{% endif %};
+  var jump_to_form = {% if course_form.errors %}true{% else%}false{% endif %};
   if (jump_to_form) {
     $("#add-course-form").show();
     $('#add-course-btn').hide();
@@ -105,7 +105,7 @@ $(document).ready(function() {
           </tr>
         </thead>
         <tbody>
-        {% for course in object_list %}
+        {% for course in course_list %}
           {% include 'courses/course_list_entry.html' %}
         {% endfor %}
         </tbody>
index 7cf32d1e4895016940a1c5e26d613caddbb96118..4934731fb4447411f727150e19d05878653e365a 100644 (file)
@@ -78,11 +78,12 @@ urlpatterns = patterns('',
 
     url(r'^search/$', NoteSearchView.as_view(), name='note_search'),
 
+    ## Course Model
     # VIEW for displaying a single Course
     url(r'^course/' + SLUG.format('') + '/$',
         CourseDetailView.as_view(), name='course_detail'),
 
-    ## NOTE MODEL
+    ## Note Model
     # Ajax endpoint to thank a note
     url(r'^ajax/note/thank/(?P<pk>[\d]+)/$', thank_note, name='thank_note'),
     # Ajax endpoint to flag a note
@@ -109,5 +110,5 @@ urlpatterns = patterns('',
     #url(r'^(?P<school_slug>[^/]+)/(?P<course_slug>[^/]+)/(?P<slug>[^/]+)$', \
     #    NoteView.as_view(), name='note_detail'),
 
-    url(r'^$', CourseListView.as_view(model=Course), name='home'),
+    url(r'^$', CourseListView.as_view(), name='home'),
 )