IMPORTANT:
-* set up a proper issue-tracker?
+* "create course site" (not "add course")
-* CSS fixes for Internet Explorer. It looks crappy in IE.
+* save-sequence fails on IE6.
-* if someone has item checked out, show due date/time on item-about page.
+* set up a proper issue-tracker?
* need more than 10 results on physical-item search results.
+* if someone has item checked out, show due date/time on item-about page.
+
* People should be able to register themselves into open courses.
That is, actually become a member of them.
* Send me email when my sites change?
-* "create course site" (not "add course")
-
MAYBE:
* Generating barcodes in emails, printable screens? (3 of 9 enough?)
"""Return a queryset of all active instructors."""
# We are using the Django is_active flag to model activeness.
return cls.objects.filter(member__role='INSTR', is_active=True) \
- .order_by('-last_name','-first_name')
+ .order_by('-last_name','-first_name').distinct()
for k,v in [(k,v) for k,v in UserExtensionHack.__dict__.items() \
if not k.startswith('_')]:
allowed = user.is_superuser
if not allowed:
course = models.Course.objects.get(pk=course_id)
- allowed = ((user.is_anonymous() and course.access=='ANON') or \
- (user.is_authenticated() and course.access=='LOGIN'))
+ allowed = course.access=='ANON' or \
+ (user.is_authenticated() and course.access=='LOGIN')
if not allowed:
allowed = _fast_user_membership_query(user.id, course_id)
if allowed:
msg = simple_message(_('Not found'),
_('The page you requested could not be found'))
return HttpResponse(msg._container, status=404)
+
+#-----------------------------------------------------------
+
+def user_filters(user):
+ """Returns a dict of filters for Item, Course, etc. querysets,
+ based on the given user's permissions."""
+ # TODO, figure out a way of EXPLAIN'ing these queries! I have no
+ # idea of their complexity.
+ if user.is_anonymous():
+ # then only anonymous-access courses are available.
+ filters = {'items': Q(course__access='ANON'),
+ 'courses': Q(access='ANON'),
+ 'instructors': Q(member__course__access='ANON'),
+ }
+ else:
+ # logged-in users have access to courses which are of the
+ # LOGIN class ('all logged-in users') or in which they
+ # have explicit Member-ship.
+ filters = {'items': (Q(course__access__in=('LOGIN','ANON')) | Q(course__member__user=user)),
+ 'courses': (Q(access__in=('LOGIN','ANON')) | Q(member__user=user)),
+ 'instructors': (Q(member__course__access__in=('LOGIN','ANON')) | Q(member__course__member__user=user)),
+ }
+ return filters
# the ones in 'models'.
choices = [
# note: I'm leaving ANON out for now, until we discuss it further.
+ (u'ANON', _(u'Anyone on the planet may access this site.')),
(u'CLOSE', _(u'No students: this site is closed.')),
(u'STUDT', _(u'Students in my course -- I will provide section numbers')),
(u'INVIT', _(u'Students in my course -- I will share an Invitation Code with them')),
template = 'browse_index.xhtml'
elif browse_option == 'instructors':
queryset = models.User.active_instructors()
+ queryset = queryset.filter(user_filters(request.user)['instructors'])
template = 'instructors.xhtml'
elif browse_option == 'departments':
queryset = models.Department.objects.filter(active=True)
template = 'departments.xhtml'
elif browse_option == 'courses':
# fixme, course filter should not be (active=True) but based on user identity.
- queryset = models.Course.objects.all()
+ for_courses = user_filters(request.user)['courses']
+ queryset = models.Course.objects.filter(for_courses)
template = 'courses.xhtml'
- paginator = queryset and Paginator(queryset, count) or None # index has no queryset.
+ queryset = queryset and queryset.distinct()
+ paginator = Paginator(queryset, count)
return g.render(template, paginator=paginator,
page_num=page_num,
count=count)
'''
courses = models.Course.objects.filter(member__user=instructor_id,
member__role='INSTR')
+ filters = user_filters(request.user)
+ courses = courses.filter(filters['courses'])
paginator = Paginator(courses.order_by('title'), count)
'''
# we start with an empty results_list, as a default
results_list = models.Item.objects.filter(pk=-1)
+ # Next, we filter based on user permissions.
+ flt = user_filters(request.user)
+ user_filter_for_items, user_filter_for_courses = flt['items'], flt['courses']
+ # Note, we haven't user-filtered anything yet; we've just set
+ # up the filters.
+
# numeric search: If the query-string is a single number, then
- # we do an item-ID search, or a barcode search. fixme:
- # item-ID is not a good short-id, since the physical item may
- # be represented in multiple Item records. We need a
- # short-number for barcodes.
+ # we do a short-number search, or a barcode search.
if re.match(r'\d+', query_string):
# Search by short ID.
results_list = models.Item.objects.filter(item_query)
if in_course:
+ # For an in-course search, we know the user has
+ # permissions to view the course; no need for
+ # user_filter_for_items.
results_list = results_list.filter(course=in_course)
+ else:
+ results_list = results_list.filter(user_filter_for_items)
+
results_list = results_list.order_by('title')
results_len = len(results_list)
paginator = Paginator(results_list, count)
course_list = []; course_len = 0
else:
course_query = get_query(query_string, ['title', 'department__name'])
- print 'course_query'
- print course_query
- course_results = models.Course.objects.filter(course_query).all()
- # course_list = models.Course.objects.filter(course_query).filter(active=True).order_by('title')[0:5]
- course_list = course_results.order_by('title')[0:5]
- #there might be a better way of doing this, though instr and course tables should not be expensive to query
- #len directly on course_list will reflect limit
+ # apply the search-filter and the user-filter
+ course_results = models.Course.objects.filter(course_query).filter(user_filter_for_courses)
+ course_list = course_results.order_by('title')
course_len = len(course_results)
#instructor search
- instr_query = get_query(query_string, ['user__last_name'])
- instructor_results = models.Member.objects.filter(instr_query).filter(role='INSTR')
if in_course:
- instructor_results = instructor_results.filter(course=in_course)
- instructor_list = instructor_results.order_by('user__last_name')[0:5]
- instr_len = len(instructor_results)
+ instructor_list = []; instr_len = 0
+ else:
+ instr_query = get_query(query_string, ['user__last_name'])
+ instructor_results = models.Member.objects.filter(instr_query).filter(role='INSTR')
+ if in_course:
+ instructor_results = instructor_results.filter(course=in_course)
+ instructor_list = instructor_results.order_by('user__last_name')[0:5]
+ instr_len = len(instructor_results)
elif in_course:
# we are in a course, but have no query? Return to the course-home page.
return HttpResponseRedirect('../')