Commit 5ffa06be by Peter Fogg

Responding to review comments.

parent 4805946a
...@@ -30,6 +30,7 @@ from contentstore.views.component import ADVANCED_COMPONENT_POLICY_KEY ...@@ -30,6 +30,7 @@ from contentstore.views.component import ADVANCED_COMPONENT_POLICY_KEY
import ddt import ddt
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from util.milestones_helpers import seed_milestone_relationship_types from util.milestones_helpers import seed_milestone_relationship_types
...@@ -87,6 +88,7 @@ class CourseDetailsTestCase(CourseTestCase): ...@@ -87,6 +88,7 @@ class CourseDetailsTestCase(CourseTestCase):
self.assertEqual(jsondetails['string'], 'string') self.assertEqual(jsondetails['string'], 'string')
def test_update_and_fetch(self): def test_update_and_fetch(self):
SelfPacedConfiguration(enabled=True).save()
jsondetails = CourseDetails.fetch(self.course.id) jsondetails = CourseDetails.fetch(self.course.id)
jsondetails.syllabus = "<a href='foo'>bar</a>" jsondetails.syllabus = "<a href='foo'>bar</a>"
# encode - decode to convert date fields and other data which changes form # encode - decode to convert date fields and other data which changes form
...@@ -135,11 +137,6 @@ class CourseDetailsTestCase(CourseTestCase): ...@@ -135,11 +137,6 @@ class CourseDetailsTestCase(CourseTestCase):
jsondetails.self_paced jsondetails.self_paced
) )
@override_settings(FEATURES=dict(settings.FEATURES, ENABLE_SELF_PACED_COURSES=False))
def test_enable_self_paced(self):
details = CourseDetails.fetch(self.course.id)
self.assertNotIn('self_paced', details.__dict__)
@override_settings(MKTG_URLS={'ROOT': 'dummy-root'}) @override_settings(MKTG_URLS={'ROOT': 'dummy-root'})
def test_marketing_site_fetch(self): def test_marketing_site_fetch(self):
settings_details_url = get_url(self.course.id) settings_details_url = get_url(self.course.id)
...@@ -325,6 +322,7 @@ class CourseDetailsViewTest(CourseTestCase): ...@@ -325,6 +322,7 @@ class CourseDetailsViewTest(CourseTestCase):
return Date().to_json(datetime_obj) return Date().to_json(datetime_obj)
def test_update_and_fetch(self): def test_update_and_fetch(self):
SelfPacedConfiguration(enabled=True).save()
details = CourseDetails.fetch(self.course.id) details = CourseDetails.fetch(self.course.id)
# resp s/b json from here on # resp s/b json from here on
......
...@@ -28,6 +28,7 @@ from openedx.core.lib.course_tabs import CourseTabPluginManager ...@@ -28,6 +28,7 @@ from openedx.core.lib.course_tabs import CourseTabPluginManager
from openedx.core.djangoapps.credit.api import is_credit_course, get_credit_requirements from openedx.core.djangoapps.credit.api import is_credit_course, get_credit_requirements
from openedx.core.djangoapps.credit.tasks import update_credit_course_requirements from openedx.core.djangoapps.credit.tasks import update_credit_course_requirements
from openedx.core.djangoapps.content.course_structures.api.v0 import api, errors from openedx.core.djangoapps.content.course_structures.api.v0 import api, errors
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from xmodule.modulestore import EdxJSONEncoder from xmodule.modulestore import EdxJSONEncoder
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
...@@ -913,6 +914,9 @@ def settings_handler(request, course_key_string): ...@@ -913,6 +914,9 @@ def settings_handler(request, course_key_string):
about_page_editable = not marketing_site_enabled about_page_editable = not marketing_site_enabled
enrollment_end_editable = GlobalStaff().has_user(request.user) or not marketing_site_enabled enrollment_end_editable = GlobalStaff().has_user(request.user) or not marketing_site_enabled
short_description_editable = settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True) short_description_editable = settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True)
self_paced_enabled = SelfPacedConfiguration.current().enabled
settings_context = { settings_context = {
'context_course': course_module, 'context_course': course_module,
'course_locator': course_key, 'course_locator': course_key,
...@@ -929,7 +933,8 @@ def settings_handler(request, course_key_string): ...@@ -929,7 +933,8 @@ def settings_handler(request, course_key_string):
'show_min_grade_warning': False, 'show_min_grade_warning': False,
'enrollment_end_editable': enrollment_end_editable, 'enrollment_end_editable': enrollment_end_editable,
'is_prerequisite_courses_enabled': is_prerequisite_courses_enabled(), 'is_prerequisite_courses_enabled': is_prerequisite_courses_enabled(),
'is_entrance_exams_enabled': is_entrance_exams_enabled() 'is_entrance_exams_enabled': is_entrance_exams_enabled(),
'self_paced_enabled': self_paced_enabled,
} }
if is_prerequisite_courses_enabled(): if is_prerequisite_courses_enabled():
courses, in_process_course_actions = get_courses_accessible_to_user(request) courses, in_process_course_actions = get_courses_accessible_to_user(request)
......
...@@ -10,6 +10,7 @@ from opaque_keys.edx.locations import Location ...@@ -10,6 +10,7 @@ from opaque_keys.edx.locations import Location
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from contentstore.utils import course_image_url, has_active_web_certificate from contentstore.utils import course_image_url, has_active_web_certificate
from models.settings import course_grading from models.settings import course_grading
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from xmodule.fields import Date from xmodule.fields import Date
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
...@@ -54,8 +55,7 @@ class CourseDetails(object): ...@@ -54,8 +55,7 @@ class CourseDetails(object):
'50' '50'
) # minimum passing score for entrance exam content module/tree, ) # minimum passing score for entrance exam content module/tree,
self.has_cert_config = None # course has active certificate configuration self.has_cert_config = None # course has active certificate configuration
if settings.FEATURES.get('ENABLE_SELF_PACED_COURSES'): self.self_paced = None
self.self_paced = None
@classmethod @classmethod
def _fetch_about_attribute(cls, course_key, attribute): def _fetch_about_attribute(cls, course_key, attribute):
...@@ -88,8 +88,7 @@ class CourseDetails(object): ...@@ -88,8 +88,7 @@ class CourseDetails(object):
# Default course license is "All Rights Reserved" # Default course license is "All Rights Reserved"
course_details.license = getattr(descriptor, "license", "all-rights-reserved") course_details.license = getattr(descriptor, "license", "all-rights-reserved")
course_details.has_cert_config = has_active_web_certificate(descriptor) course_details.has_cert_config = has_active_web_certificate(descriptor)
if settings.FEATURES.get('ENABLE_SELF_PACED_COURSES'): course_details.self_paced = descriptor.self_paced
course_details.self_paced = descriptor.self_paced
for attribute in ABOUT_ATTRIBUTES: for attribute in ABOUT_ATTRIBUTES:
value = cls._fetch_about_attribute(course_key, attribute) value = cls._fetch_about_attribute(course_key, attribute)
...@@ -192,7 +191,7 @@ class CourseDetails(object): ...@@ -192,7 +191,7 @@ class CourseDetails(object):
descriptor.language = jsondict['language'] descriptor.language = jsondict['language']
dirty = True dirty = True
if (settings.FEATURES.get('ENABLE_SELF_PACED_COURSES') if (SelfPacedConfiguration.current().enabled
and 'self_paced' in jsondict and 'self_paced' in jsondict
and jsondict['self_paced'] != descriptor.self_paced): and jsondict['self_paced'] != descriptor.self_paced):
descriptor.self_paced = jsondict['self_paced'] descriptor.self_paced = jsondict['self_paced']
......
...@@ -106,9 +106,6 @@ FEATURES['ENTRANCE_EXAMS'] = True ...@@ -106,9 +106,6 @@ FEATURES['ENTRANCE_EXAMS'] = True
FEATURES['ENABLE_PROCTORED_EXAMS'] = True FEATURES['ENABLE_PROCTORED_EXAMS'] = True
# Enable self-paced courses
FEATURES['ENABLE_SELF_PACED_COURSES'] = True
# Point the URL used to test YouTube availability to our stub YouTube server # Point the URL used to test YouTube availability to our stub YouTube server
YOUTUBE_PORT = 9080 YOUTUBE_PORT = 9080
YOUTUBE['API'] = "http://127.0.0.1:{0}/get_youtube_api/".format(YOUTUBE_PORT) YOUTUBE['API'] = "http://127.0.0.1:{0}/get_youtube_api/".format(YOUTUBE_PORT)
......
...@@ -182,9 +182,6 @@ FEATURES = { ...@@ -182,9 +182,6 @@ FEATURES = {
# Timed or Proctored Exams # Timed or Proctored Exams
'ENABLE_PROCTORED_EXAMS': False, 'ENABLE_PROCTORED_EXAMS': False,
# Enable self-paced courses.
'ENABLE_SELF_PACED_COURSES': False,
} }
ENABLE_JASMINE = False ENABLE_JASMINE = False
...@@ -796,6 +793,9 @@ INSTALLED_APPS = ( ...@@ -796,6 +793,9 @@ INSTALLED_APPS = (
# programs support # programs support
'openedx.core.djangoapps.programs', 'openedx.core.djangoapps.programs',
# Self-paced course configuration
'openedx.core.djangoapps.self_paced',
) )
......
...@@ -279,6 +279,3 @@ FEATURES['ENABLE_TEAMS'] = True ...@@ -279,6 +279,3 @@ FEATURES['ENABLE_TEAMS'] = True
# Dummy secret key for dev/test # Dummy secret key for dev/test
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
# Enable self-paced courses
FEATURES['ENABLE_SELF_PACED_COURSES'] = True
...@@ -412,7 +412,7 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url}'; ...@@ -412,7 +412,7 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url}';
</section> </section>
% endif % endif
% if settings.FEATURES.get("ENABLE_SELF_PACED_COURSES", False): % if self_paced_enabled:
<hr class="divide" /> <hr class="divide" />
......
...@@ -14,6 +14,7 @@ from ...pages.studio.utils import add_discussion, drag, verify_ordering ...@@ -14,6 +14,7 @@ from ...pages.studio.utils import add_discussion, drag, verify_ordering
from ...pages.lms.courseware import CoursewarePage from ...pages.lms.courseware import CoursewarePage
from ...pages.lms.course_nav import CourseNavPage from ...pages.lms.course_nav import CourseNavPage
from ...pages.lms.staff_view import StaffPage from ...pages.lms.staff_view import StaffPage
from ...fixtures.config import ConfigModelFixture
from ...fixtures.course import XBlockFixtureDesc from ...fixtures.course import XBlockFixtureDesc
from base_studio_test import StudioCourseTest from base_studio_test import StudioCourseTest
...@@ -1766,6 +1767,7 @@ class SelfPacedOutlineTest(CourseOutlineTest): ...@@ -1766,6 +1767,7 @@ class SelfPacedOutlineTest(CourseOutlineTest):
), ),
) )
self.course_fixture.add_course_details({'self_paced': True}) self.course_fixture.add_course_details({'self_paced': True})
ConfigModelFixture('/config/self_paced', {'enabled': True}).install()
def test_release_dates_not_shown(self): def test_release_dates_not_shown(self):
""" """
......
...@@ -4,6 +4,7 @@ Acceptance tests for Studio's Settings Details pages ...@@ -4,6 +4,7 @@ Acceptance tests for Studio's Settings Details pages
from unittest import skip from unittest import skip
from .base_studio_test import StudioCourseTest from .base_studio_test import StudioCourseTest
from ...fixtures.config import ConfigModelFixture
from ...fixtures.course import CourseFixture from ...fixtures.course import CourseFixture
from ...pages.studio.settings import SettingsPage from ...pages.studio.settings import SettingsPage
from ...pages.studio.overview import CourseOutlinePage from ...pages.studio.overview import CourseOutlinePage
...@@ -202,6 +203,9 @@ class SettingsMilestonesTest(StudioSettingsDetailsTest): ...@@ -202,6 +203,9 @@ class SettingsMilestonesTest(StudioSettingsDetailsTest):
class CoursePacingTest(StudioSettingsDetailsTest): class CoursePacingTest(StudioSettingsDetailsTest):
"""Tests for setting a course to self-paced.""" """Tests for setting a course to self-paced."""
def populate_course_fixture(self, __):
ConfigModelFixture('/config/self_paced', {'enabled': True}).install()
def test_default_instructor_led(self): def test_default_instructor_led(self):
""" """
Test that the 'instructor led' button is checked by default. Test that the 'instructor led' button is checked by default.
......
...@@ -4,6 +4,7 @@ dates for each block in the course. ...@@ -4,6 +4,7 @@ dates for each block in the course.
""" """
from .field_overrides import FieldOverrideProvider from .field_overrides import FieldOverrideProvider
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
class SelfPacedDateOverrideProvider(FieldOverrideProvider): class SelfPacedDateOverrideProvider(FieldOverrideProvider):
...@@ -20,4 +21,4 @@ class SelfPacedDateOverrideProvider(FieldOverrideProvider): ...@@ -20,4 +21,4 @@ class SelfPacedDateOverrideProvider(FieldOverrideProvider):
@classmethod @classmethod
def enabled_for(cls, course): def enabled_for(cls, course):
"""This provider is enabled for self-paced courses only.""" """This provider is enabled for self-paced courses only."""
return course.self_paced return SelfPacedConfiguration.current().enabled and course.self_paced
...@@ -7,12 +7,13 @@ from urllib import urlencode ...@@ -7,12 +7,13 @@ from urllib import urlencode
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test.utils import override_settings
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
from util.date_utils import strftime_localized from util.date_utils import strftime_localized
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_CLOSED_MODULESTORE from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_CLOSED_MODULESTORE
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
from student.models import CourseEnrollment from student.models import CourseEnrollment
from .helpers import LoginEnrollmentTestCase from .helpers import LoginEnrollmentTestCase
...@@ -114,3 +115,34 @@ class CourseInfoTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase): ...@@ -114,3 +115,34 @@ class CourseInfoTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
resp = self.client.get(url) resp = self.client.get(url)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertNotIn(self.xml_data, resp.content) self.assertNotIn(self.xml_data, resp.content)
@attr('shard_1')
@override_settings(FEATURES=dict(settings.FEATURES, EMBARGO=False))
class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
"""
Tests for the info page of self-paced courses.
"""
def setUp(self):
super(SelfPacedCourseInfoTestCase, self).setUp()
self.instructor_led_course = CourseFactory.create(self_paced=False)
self.self_paced_course = CourseFactory.create(self_paced=True)
self.setup_user()
def fetch_course_info_with_queries(self, course, sql_queries, mongo_queries):
"""
Fetch the given course's info page, asserting the number of SQL
and Mongo queries.
"""
url = reverse('info', args=[unicode(course.id)])
with self.assertNumQueries(sql_queries):
with check_mongo_calls(mongo_queries):
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
def test_num_queries_instructor_led(self):
self.fetch_course_info_with_queries(self.instructor_led_course, 14, 4)
def test_num_queries_self_paced(self):
self.fetch_course_info_with_queries(self.self_paced_course, 14, 4)
...@@ -9,6 +9,7 @@ from django.test.utils import override_settings ...@@ -9,6 +9,7 @@ from django.test.utils import override_settings
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides
from lms.djangoapps.courseware.field_overrides import OverrideFieldData from lms.djangoapps.courseware.field_overrides import OverrideFieldData
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
...@@ -22,10 +23,9 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase): ...@@ -22,10 +23,9 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase):
""" """
def setUp(self): def setUp(self):
SelfPacedConfiguration(enabled=True).save()
super(SelfPacedDateOverrideTest, self).setUp() super(SelfPacedDateOverrideTest, self).setUp()
self.due_date = datetime(2015, 5, 26, 8, 30, 00).replace(tzinfo=tzutc()) self.due_date = datetime(2015, 5, 26, 8, 30, 00).replace(tzinfo=tzutc())
self.instructor_led_course, self.il_section = self.setup_course("Instructor Led Course", False)
self.self_paced_course, self.sp_section = self.setup_course("Self-Paced Course", True)
def tearDown(self): def tearDown(self):
super(SelfPacedDateOverrideTest, self).tearDown() super(SelfPacedDateOverrideTest, self).tearDown()
...@@ -43,7 +43,14 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase): ...@@ -43,7 +43,14 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase):
return (course, section) return (course, section)
def test_instructor_led(self): def test_instructor_led(self):
self.assertEqual(self.due_date, self.il_section.due) __, il_section = self.setup_course("Instructor Led Course", False)
self.assertEqual(self.due_date, il_section.due)
def test_self_paced(self): def test_self_paced(self):
self.assertIsNone(self.sp_section.due) __, sp_section = self.setup_course("Self-Paced Course", True)
self.assertIsNone(sp_section.due)
def test_self_paced_disabled(self):
SelfPacedConfiguration(enabled=False).save()
__, sp_section = self.setup_course("Self-Paced Course", True)
self.assertEqual(self.due_date, sp_section.due)
...@@ -677,10 +677,9 @@ if FEATURES.get('INDIVIDUAL_DUE_DATES'): ...@@ -677,10 +677,9 @@ if FEATURES.get('INDIVIDUAL_DUE_DATES'):
) )
##### Self-Paced Course Due Dates ##### ##### Self-Paced Course Due Dates #####
if FEATURES.get('ENABLE_SELF_PACED_COURSES'): FIELD_OVERRIDE_PROVIDERS += (
FIELD_OVERRIDE_PROVIDERS += ( 'courseware.self_paced_overrides.SelfPacedDateOverrideProvider',
'courseware.self_paced_overrides.SelfPacedDateOverrideProvider', )
)
# PROFILE IMAGE CONFIG # PROFILE IMAGE CONFIG
PROFILE_IMAGE_BACKEND = ENV_TOKENS.get('PROFILE_IMAGE_BACKEND', PROFILE_IMAGE_BACKEND) PROFILE_IMAGE_BACKEND = ENV_TOKENS.get('PROFILE_IMAGE_BACKEND', PROFILE_IMAGE_BACKEND)
......
...@@ -131,9 +131,6 @@ FEATURES['LICENSING'] = True ...@@ -131,9 +131,6 @@ FEATURES['LICENSING'] = True
# Use the auto_auth workflow for creating users and logging them in # Use the auto_auth workflow for creating users and logging them in
FEATURES['AUTOMATIC_AUTH_FOR_TESTING'] = True FEATURES['AUTOMATIC_AUTH_FOR_TESTING'] = True
# Enable self-paced courses
FEATURES['ENABLE_SELF_PACED_COURSES'] = True
########################### Entrance Exams ################################# ########################### Entrance Exams #################################
FEATURES['MILESTONES_APP'] = True FEATURES['MILESTONES_APP'] = True
FEATURES['ENTRANCE_EXAMS'] = True FEATURES['ENTRANCE_EXAMS'] = True
......
...@@ -408,9 +408,6 @@ FEATURES = { ...@@ -408,9 +408,6 @@ FEATURES = {
# Enable LTI Provider feature. # Enable LTI Provider feature.
'ENABLE_LTI_PROVIDER': False, 'ENABLE_LTI_PROVIDER': False,
# Enable self-paced courses.
'ENABLE_SELF_PACED_COURSES': False,
} }
# Ignore static asset files on import which match this pattern # Ignore static asset files on import which match this pattern
...@@ -1970,6 +1967,9 @@ INSTALLED_APPS = ( ...@@ -1970,6 +1967,9 @@ INSTALLED_APPS = (
# programs support # programs support
'openedx.core.djangoapps.programs', 'openedx.core.djangoapps.programs',
# Self-paced course configuration
'openedx.core.djangoapps.self_paced',
) )
######################### CSRF ######################################### ######################### CSRF #########################################
......
...@@ -532,6 +532,3 @@ AUTHENTICATION_BACKENDS += ('lti_provider.users.LtiBackend',) ...@@ -532,6 +532,3 @@ AUTHENTICATION_BACKENDS += ('lti_provider.users.LtiBackend',)
# ORGANIZATIONS # ORGANIZATIONS
FEATURES['ORGANIZATIONS_APP'] = True FEATURES['ORGANIZATIONS_APP'] = True
# Enable self-paced courses
FEATURES['ENABLE_SELF_PACED_COURSES'] = True
...@@ -11,6 +11,9 @@ import django.contrib.auth.views ...@@ -11,6 +11,9 @@ import django.contrib.auth.views
from microsite_configuration import microsite from microsite_configuration import microsite
import auth_exchange.views import auth_exchange.views
from config_models.views import ConfigurationModelCurrentAPIView
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
# Uncomment the next two lines to enable the admin: # Uncomment the next two lines to enable the admin:
if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'): if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'):
admin.autodiscover() admin.autodiscover()
...@@ -739,6 +742,10 @@ if settings.FEATURES.get("ENABLE_LTI_PROVIDER"): ...@@ -739,6 +742,10 @@ if settings.FEATURES.get("ENABLE_LTI_PROVIDER"):
url(r'^lti_provider/', include('lti_provider.urls')), url(r'^lti_provider/', include('lti_provider.urls')),
) )
urlpatterns += (
url(r'config/self_paced', ConfigurationModelCurrentAPIView.as_view(model=SelfPacedConfiguration)),
)
urlpatterns = patterns(*urlpatterns) urlpatterns = patterns(*urlpatterns)
if settings.DEBUG: if settings.DEBUG:
......
"""
Admin site bindings for self-paced courses.
"""
from django.contrib import admin
from config_models.admin import ConfigurationModelAdmin
from .models import SelfPacedConfiguration
admin.site.register(SelfPacedConfiguration, ConfigurationModelAdmin)
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'SelfPacedConfiguration'
db.create_table('self_paced_selfpacedconfiguration', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('change_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('changed_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.PROTECT)),
('enabled', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal('self_paced', ['SelfPacedConfiguration'])
def backwards(self, orm):
# Deleting model 'SelfPacedConfiguration'
db.delete_table('self_paced_selfpacedconfiguration')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'self_paced.selfpacedconfiguration': {
'Meta': {'ordering': "('-change_date',)", 'object_name': 'SelfPacedConfiguration'},
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
}
}
complete_apps = ['self_paced']
\ No newline at end of file
"""
Configuration for self-paced courses.
"""
from config_models.models import ConfigurationModel
class SelfPacedConfiguration(ConfigurationModel):
"""
Configuration for self-paced courses.
"""
pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment