got rid of 'user_filters', moving towards putting filter-clause generators in the...
authorgfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Thu, 15 Jul 2010 00:55:46 +0000 (00:55 +0000)
committergfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Thu, 15 Jul 2010 00:55:46 +0000 (00:55 +0000)
So, if you want a clause that would show only Items accessible by the current user:

  accessible = Item.objects.filter(Item.filter_for_user(current_user))

filter_for_user() returns a Q() object, which can be combined using
binary ops to construct more complex queries.

git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@920 6d9bc8c9-1ec2-4278-b937-99fde70a366f

conifer/syrup/models.py
conifer/syrup/views/_common.py
conifer/syrup/views/general.py

index 413b2f5..a4abd6b 100644 (file)
@@ -1,20 +1,22 @@
-from django.db import models as m
-from django.contrib.auth.models import User
-from django.contrib.auth.models import AnonymousUser
-from datetime import datetime
-from genshi import Markup
-from django.utils.translation import ugettext as _
 import re
 import random
-from django.utils import simplejson
+
+from django.db                       import models as m
+from django.db.models                import Q
+from django.contrib.auth.models      import User
+from django.contrib.auth.models      import AnonymousUser
+from datetime                        import datetime
+from genshi                          import Markup
+from django.utils.translation        import ugettext as _
+from django.utils                    import simplejson
 from conifer.plumbing.genshi_support import get_request
+
 # campus and library integration
-from conifer.plumbing.hooksystem import *
-from django.conf import settings
+from conifer.plumbing.hooksystem     import *
+from django.conf                     import settings
 campus = settings.CAMPUS_INTEGRATION
-# TODO: fixme, not sure if conifer.custom is a good parent.
 import conifer.libsystems.z3950.marcxml as MX
-from django.utils import simplejson as json
+from django.utils                    import simplejson as json
 
 #----------------------------------------------------------------------
 
@@ -178,6 +180,7 @@ class Site(BaseModel):
 
     class Meta:
         unique_together = (('course', 'term', 'owner'))
+        ordering = ['-term__start', 'course__code']
 
     def __unicode__(self):
         return u'%s: %s (%s, %s)' % (
@@ -294,7 +297,24 @@ class Site(BaseModel):
             or (self.access == 'LOGIN' and user.is_authenticated()) \
             or user.is_staff \
             or self.is_member(user)
-            
+
+
+    #--------------------------------------------------
+
+    @classmethod
+    def filter_for_user(cls, user):
+        """
+        Given a user object, return an appropriate Q filter that would
+        filter only Sites that the user has permission to view.
+        """
+        if user.is_anonymous():
+            return Q(access='ANON')
+        elif user.is_staff:
+            return Q()
+        else:
+            return (Q(access__in=('LOGIN','ANON')) \
+                        | Q(group__membership__user=user))
+
 #------------------------------------------------------------
 # User membership in sites
 
@@ -468,6 +488,9 @@ class Item(BaseModel):
     fileobj_mimetype = m.CharField(max_length=128, blank=True, null=True)
 
 
+    class Meta:
+        ordering = ['title', 'author', 'published']
+
     #--------------------------------------------------
     # MARC
     def marc_as_dict(self):
@@ -553,6 +576,21 @@ class Item(BaseModel):
         return hl_author
 
 
+    @classmethod
+    def filter_for_user(cls, user):
+        """
+        Given a user object, return an appropriate Q filter that would
+        filter only Items that the user has permission to view.
+        """
+        if user.is_anonymous():
+            return Q(site__access='ANON')
+        elif user.is_staff:
+            return Q()
+        else:
+            return (Q(site__access__in=('LOGIN','ANON')) \
+                        | Q(site__group__membership__user=user))
+                     
+       
 #------------------------------------------------------------
 # TODO: move this to a utility module.
 
index 330fb87..43981d6 100644 (file)
@@ -125,30 +125,6 @@ def custom_400_handler(request):
                           _('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, Site, 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 sites are available.
-        filters = {'items': Q(site__access='ANON'),
-                   'sites': Q(access='ANON'),
-                   'instructors': Q(), # TODO: do we really need a filter here?
-                   }
-    else:
-        # logged-in users have access to sites which are of the
-        # LOGIN class ('all logged-in users') or in which they
-        # have explicit Member-ship.
-        filters = {
-            'items': (Q(site__access__in=('LOGIN','ANON')) \
-                          | Q(site__group__membership__user=user)),
-            'sites': (Q(access__in=('LOGIN','ANON')) | Q(group__membership__user=user)),
-            'instructors': Q(), # TODO: do we really need a filter here?
-            }
-    return filters
 
 #------------------------------------------------------------
 
index 1b058da..e354212 100644 (file)
@@ -96,13 +96,15 @@ def browse(request, browse_option=''):
         template = 'browse_index.xhtml'
     elif browse_option == 'instructors':
         queryset = models.User.active_instructors()
+        # TODO: fixme, user_filters is no more.
         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.
+        # TODO: fixme, course filter should not be (active=True) but based on user identity.
+        # TODO: fixme, user_filters is no more.
         for_courses = user_filters(request.user)['courses']
         queryset = models.Site.objects.filter(for_courses)
         template = 'courses.xhtml'
@@ -126,6 +128,7 @@ def instructor_detail(request, instructor_id):
     '''
     sites = models.Site.objects.filter(member__user=instructor_id,
                                            member__role='INSTR')
+    # TODO: fixme, user_filters is no more.
     filters = user_filters(request.user)
     courses = courses.filter(filters['courses'])
     paginator = Paginator(courses.order_by('title'), count)