diff --git a/common/djangoapps/course_modes/admin.py b/common/djangoapps/course_modes/admin.py index 2fc3b99a1c..cae959a9c2 100644 --- a/common/djangoapps/course_modes/admin.py +++ b/common/djangoapps/course_modes/admin.py @@ -1,6 +1,7 @@ from django import forms from django.conf import settings from django.contrib import admin +from django.http.request import QueryDict from django.utils.translation import ugettext_lazy as _ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey @@ -51,10 +52,23 @@ class CourseModeForm(forms.ModelForm): ) def __init__(self, *args, **kwargs): + # If args is a QueryDict, then the ModelForm addition request came in as a POST with a course ID string. + # Change the course ID string to a CourseLocator object by copying the QueryDict to make it mutable. + if len(args) > 0 and 'course' in args[0] and isinstance(args[0], QueryDict): + args_copy = args[0].copy() + args_copy['course'] = CourseKey.from_string(args_copy['course']) + args = [args_copy] + super(CourseModeForm, self).__init__(*args, **kwargs) - if self.data.get('course'): - self.data['course'] = CourseKey.from_string(self.data['course']) + try: + if self.data.get('course'): + self.data['course'] = CourseKey.from_string(self.data['course']) + except AttributeError: + # Change the course ID string to a CourseLocator. + # On a POST request, self.data is a QueryDict and is immutable - so this code will fail. + # However, the args copy above before the super() call handles this case. + pass default_tz = timezone(settings.TIME_ZONE) diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py index 3105f1c050..74cb55fb4e 100644 --- a/common/djangoapps/course_modes/models.py +++ b/common/djangoapps/course_modes/models.py @@ -202,6 +202,9 @@ class CourseMode(models.Model): # Ensure currency is always lowercase. self.clean() # ensure object-level validation is performed before we save. self.currency = self.currency.lower() + if self.id is None: + # If this model has no primary key at save time, it needs to be force-inserted. + force_insert = True super(CourseMode, self).save(force_insert, force_update, using) @property