Hi, I'm using ObjectPermission backend explained at `http://
djangoadvent.com/1.2/object-permissions/`
and I create timeline model which save `content_type` and `object_id`
for each object when the object is saved for making
website update history timeline.

what my problem is that how can i filtering timeline queryset with
permission for each user. the code below
do what i want but it is too stupid.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class TimelineManager(models.Manager):
    def published(self, request):
        # I know that the code below is so stupid but how?
        pks = []
        for timeline in self.all():
            if request.user.has_perm('view', timeline.content_object):
                pks.append(timeline.pk)
        return self.filter(pk__in=pks).order_by('-created_at')
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

while ObjectPermission and Timeline both have `content_type` and
`object_id`, i wonder i can join the two queryset
and filtering them but I have no idea to JOIN and neither FILTER from
joined queryset.

Any idea is very welcome even completely different way least i can
have ObjectPermission and Timeline for updating website.

Thanks.

P.S.
in case if the code below makes you help

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
###############################################
# Timeline
###############################################
class Timeline(models.Model):
    u"""Django model's history model"""

    ACTION_FLAGS = (
        (u'create',    _('created')),
        (u'update',    _('modified')),
        (u'delete',    _('deleted')),
    )
    content_type    = models.ForeignKey(ContentType,
verbose_name=_('content type'))
    object_id       = models.PositiveIntegerField(_('object ID'))
    content_object  = generic.GenericForeignKey()

    user            = models.ForeignKey(User, null=True)
    label           = models.TextField(_('label'))
    action_flag     = models.CharField(_('action flag'),
max_length=10, choices=ACTION_FLAGS)
    created_at      = models.DateTimeField(_('action time'),
auto_now_add=True)

    objects         = TimelineManager()

    class Meta:
        ordering            = ['-created_at']
        verbose_name        = _('timeline')
        verbose_name_plural = _('timelines')

    def get_absolute_url(self):
        if hasattr(self.content_object, 'get_absolute_url'):
            return self.content_object.get_absolute_url()
        else:
            warnings.warn(u"`get_absolute_url` method was called for
object which doesn't has permalink.")
            return u''

#########################################################
# ObjectPermission
#########################################################
class ObjectPermission(models.Model):
    u"""
    Permission model for perticular object
    """
    content_type    = models.ForeignKey(ContentType,
verbose_name=_('content type'), null=True)
    object_id       = models.PositiveIntegerField(_('object id'),
null=True)
    subject         = generic.GenericForeignKey()

    can_view        = models.BooleanField(_('can view'))
    can_change      = models.BooleanField(_('can change'))
    can_delete      = models.BooleanField(_('can delete'))

    class Meta:
        abstract    = True

class GroupObjectPermission(ObjectPermission):
    u"""
    Object permission model for group
    """
    group   = models.ForeignKey(Group, verbose_name=_('group'))

    class Meta:
        ordering            = ('content_type', 'group')
        unique_together     = ('content_type', 'object_id', 'group')
        verbose_name        = _('group object permission')
        verbose_name_plural = _('group object permissions')

class AnonymousObjectPermission(ObjectPermission):
    u"""
    Object permission model for anonymous user
    """
    class Meta:
        ordering            = ('content_type',)
        unique_together     = ('content_type', 'object_id')
        verbose_name        = _('anonymous object permission')
        verbose_name_plural = _('anonymous object permissions')

class UserObjectPermission(ObjectPermission):
    u"""
    Object permission model for user
    """
    user    = models.ForeignKey(User, blank=True, null=True,
verbose_name=_('user'), help_text=_('`None` for all authenticated
user'))

    class Meta:
        ordering            = ('content_type', 'user')
        unique_together     = ('content_type', 'object_id', 'user')
        verbose_name        = _('user object permission')
        verbose_name_plural = _('user object permissions')

#############################################################
# Backends
#############################################################
class ObjectPermBackend(object):
    supports_object_permissions = True
    supports_anonymous_user     = True

    def authenticate(self, username, password):
        return None

    def has_perm(self, user_obj, perm, obj=None):
        def exists(qs, perm):
            return qs.filter(**{'can_%s' % perm: True}).exists()

        if obj is None:
            return False

        ct = ContentType.objects.get_for_model(obj)

        try:
            perm = perm.split('.')[-1].split('_')[0]
        except IndexError:
            return False

        if user_obj.is_authenticated():
            # try to find from UserObjectPermission first
            qs = UserObjectPermission.objects.filter(content_type=ct,
object_id=obj.pk, user=user_obj)
            if qs.count() == 0:
                # permission for particular user should have priority
over permission for all authenticated users
                qs =
UserObjectPermission.objects.filter(content_type=ct, object_id=obj.pk,
user=None)
            if exists(qs, perm): return True
            # try to find from GroupObjectPermission
            groups = [group.pk for group in user_obj.groups.all()]
            qs = GroupObjectPermission.objects.filter(content_type=ct,
object_id=obj.pk, group__in=groups)
            return exists(qs, perm)
        else:
            # try to find from AnonymousObjectPermission
            qs =
AnonymousObjectPermission.objects.filter(content_type=ct,
object_id=obj.pk)
            return exists(qs, perm)

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to