From 8188dd5c9ffda97deb2f7154b8fe7bd6b1b785f5 Mon Sep 17 00:00:00 2001 From: gfawcett Date: Sun, 8 Mar 2009 01:48:58 +0000 Subject: [PATCH] more work on new-course; changes to Course model; various bugfixes. git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@143 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- conifer/syrup/models.py | 29 ++++++++++++----- conifer/syrup/views.py | 57 +++++++++++++++++++++++++--------- conifer/templates/add_new_course.xhtml | 30 ++++++++++-------- conifer/templates/welcome.xhtml | 3 +- 4 files changed, 83 insertions(+), 36 deletions(-) diff --git a/conifer/syrup/models.py b/conifer/syrup/models.py index 7266eee..f76f292 100644 --- a/conifer/syrup/models.py +++ b/conifer/syrup/models.py @@ -153,21 +153,36 @@ class Course(m.Model): term = m.ForeignKey(Term) title = m.CharField(max_length=1024) access = m.CharField(max_length=5, - choices = [('ANON', _('World-accessible')), - ('LOGIN', _('Accessible to all logged-in users')), - ('STUDT', _('Accessible to course students')), - ('CLOSE', _('Accessible only to course owners'))], + choices = [ + ('ANON', _('World-accessible')), + ('LOGIN', _('Accessible to all logged-in users')), + ('STUDT', _('Accessible to course students (by section)')), + ('PASWD', _('Accessible to course students (by password)')), + ('CLOSE', _('Accessible only to course owners'))], default='CLOSE') - # For sites that use a passphrase as an invitation (STUDT access). - passkey = m.CharField(db_index=True, unique=True, blank=True, null=True, - max_length=255) + # For sites that use a passphrase as an invitation (PASWD access). + passkey = m.CharField(db_index=True, blank=True, null=True, max_length=255) # For sites that have registration-lists from an external system # (STUDT access). enrol_codes = m.CharField(_('Registrar keys for class lists'), max_length=4098, blank=True, null=True) + + + def save(self, force_insert=False, force_update=False): + # We need to override save() to ensure unique passkey + # values. Django (and some backend databases) will not allow + # multiple NULL values in a unique column. + if self.passkey: + try: + already = Course.objects.get(passkey=self.passkey) + except Course.DoesNotExist: + super(Course, self).save(force_insert, force_update) + else: + super(Course, self).save(force_insert, force_update) + def __unicode__(self): return self.code or self.title diff --git a/conifer/syrup/views.py b/conifer/syrup/views.py index 57e6b17..4412c52 100644 --- a/conifer/syrup/views.py +++ b/conifer/syrup/views.py @@ -57,7 +57,7 @@ def welcome(request): def open_courses(request): page_num = int(request.GET.get('page', 1)) count = int(request.GET.get('count', 5)) - paginator = Paginator(models.Course.objects.filter(moderated=False), count) + paginator = Paginator(models.Course.objects.all(), count) # fixme, what filter? return g.render('open_courses.xhtml', paginator=paginator, page_num=page_num, count=count) @@ -71,9 +71,9 @@ def instructors(request): if action == 'join': paginator = Paginator(models.UserProfile.active_instructors(), count) elif action == 'drop': - paginator = Paginator(models.Course.objects.filter(moderated=False), count) + paginator = Paginator(models.Course.objects.all(), count) # fixme, what filter? else: - paginator = Paginator(models.Course.objects.filter(moderated=False), count) + paginator = Paginator(models.Course.objects.all(), count) # fixme, what filter? return g.render('instructors.xhtml', paginator=paginator, page_num=page_num, @@ -117,9 +117,26 @@ def browse_courses(request, browse_option=''): def my_courses(request): return g.render('my_courses.xhtml') +def course_detail(request, course_id): + course = get_object_or_404(models.Course, pk=course_id) + if course.access != 'ANON' and request.user.is_anonymous(): + #fixme, don't stop access just if anonymous, but rather if not + #allowed to access. We need to set up a permissions model. + return login_required(lambda *args: None)(request) + return g.render('course_detail.xhtml', course=course) + +def course_search(request, course_id): + course = get_object_or_404(models.Course, pk=course_id) + return search(request, in_course=course) + + +#------------------------------------------------------------ +# Creating a new course + class NewCourseForm(ModelForm): class Meta: model = models.Course + def clean_code(self): v = (self.cleaned_data.get('code') or '').strip() is_valid_func = models.course_codes.course_code_is_valid @@ -128,6 +145,15 @@ class NewCourseForm(ModelForm): else: raise ValidationError, _('invalid course code') +# I want different choice labels on the access screen than are given +# in the model. +NewCourseForm.base_fields['access'].widget.choices = [ + ('CLOSE', _('For now, just myself and designated colleagues')), + ('STUDT', _('Students in my course (I will provide section numbers)')), + ('PASWD', _('Students in my course (I will share a password with them)')), + ('LOGIN', _('All Reserves patrons'))] + + # hack the new-course form if we have course-code lookup COURSE_CODE_LIST = bool(models.course_codes.course_code_list) COURSE_CODE_LOOKUP_TITLE = bool(models.course_codes.course_code_lookup_title) @@ -153,23 +179,22 @@ def add_new_course(request): form = NewCourseForm(request.POST, instance=models.Course()) if not form.is_valid(): return g.render('add_new_course.xhtml', **locals()) + else: + form.save() + course = form.instance + assert course.id + mbr = course.member_set.create(user=request.user, role='INSTR') + mbr.save() + + # fixme, need to ask about PASWD and STUDT settings before redirect. + return HttpResponseRedirect('../') # back to My Courses def add_new_course_ajax_title(request): course_code = request.GET['course_code'] title = models.course_codes.course_code_lookup_title(course_code) return HttpResponse(simplejson.dumps({'title':title})) -def course_detail(request, course_id): - course = get_object_or_404(models.Course, pk=course_id) - if course.moderated and request.user.is_anonymous(): - #fixme, don't stop access just if anonymous, but rather if not - #allowed to access. We need to set up a permissions model. - return login_required(lambda *args: None)(request) - return g.render('course_detail.xhtml', course=course) - -def course_search(request, course_id): - course = get_object_or_404(models.Course, pk=course_id) - return search(request, in_course=course) +#------------------------------------------------------------ def instructor_detail(request, instructor_id): page_num = int(request.GET.get('page', 1)) @@ -319,7 +344,9 @@ def item_add(request, course_id, item_id): def item_edit(request, course_id, item_id): course = get_object_or_404(models.Course, pk=course_id) item = get_object_or_404(models.Item, pk=item_id, course__id=course_id) - template = 'item_add_%s.xhtml' % item.item_type.lower() + item_type = item.item_type + template = 'item_add_%s.xhtml' % item_type.lower() + parent_item = item.parent_heading if request.method == 'GET': return g.render(template, **locals()) else: diff --git a/conifer/templates/add_new_course.xhtml b/conifer/templates/add_new_course.xhtml index cdba3f4..3f39a6c 100644 --- a/conifer/templates/add_new_course.xhtml +++ b/conifer/templates/add_new_course.xhtml @@ -11,17 +11,26 @@ title = _('Add a new course site')

${title}

+
- - ${field.label}${Markup(field)} !!! + + ${field.label} + + + ${Markup(field)} + + e.g., ${example} +
General description - - - - - + ${field_row(form.code, example)} + ${field_row(form.title)} + ${field_row(form.term)} ${field_row(form.department)}
Course code${Markup(form.code)}e.g. ${example}
Title${Markup(form.title)} ${form.title.errors}
Term${Markup(form.term)}
Access${Markup(form.access)}
@@ -29,12 +38,7 @@ title = _('Add a new course site')
Access controls

This site will be available to:

- + ${Markup(form.access)}

diff --git a/conifer/templates/welcome.xhtml b/conifer/templates/welcome.xhtml index 05ef1cc..7607d07 100644 --- a/conifer/templates/welcome.xhtml +++ b/conifer/templates/welcome.xhtml @@ -13,7 +13,8 @@ title = _('Welcome!')

${news.subject}

${news.generated_body()}
-
posted ${news.published.strftime('%c')}
+
posted ${news.published.strftime('%c')} + edit
-- 2.11.0