@@ -0,0 +1,1411 @@
+from django.contrib.auth.mixins import LoginRequiredMixin%0Afrom guardian.mixins import PermissionRequiredMixin%0A%0A%0Aclass RaisePermissionRequiredMixin(LoginRequiredMixin, PermissionRequiredMixin):%0A    %22%22%22Mixin to verify object permission with preserve correct status code in view%0A    %22%22%22%0A    raise_exception = True%0A    redirect_unauthenticated_users = True%0A%0A%0Aclass AttrPermissionRequiredMixin(RaisePermissionRequiredMixin):%0A    %22%22%22Mixin to verify object permission in SingleObjectView%0A    Attributes:%0A        permission_attribute (str): A path to traverse from object to permission object%0A    %22%22%22%0A    permission_attribute = None%0A%0A    @staticmethod%0A    def _resolve_path(obj, path=None):%0A        %22%22%22Resolve django-like path eg. object2__object3 for object%0A        Args:%0A            obj: The object the view is displaying.%0A            path (str, optional): Description%0A        Returns:%0A            A oject at end of resolved path%0A        %22%22%22%0A        if path:%0A            for attr_name in path.split('__'):%0A                obj = getattr(obj, attr_name)%0A        return obj%0A%0A    def get_permission_object(self):%0A        obj = super(AttrPermissionRequiredMixin, self).get_object()%0A        return self._resolve_path(obj, self.permission_attribute)%0A%0A    def get_object(self):%0A        if not hasattr(self, 'object'):%0A            self.object = super(AttrPermissionRequiredMixin, self).get_object()%0A        return self.object%0A

Add atom.ext.guardian.views