class BaseExperienceViewSet(object): queryset = Experience.objects.all() pagination_class = pagination.factory('PageNumberPagination') permission_classes = [ permissions.C(permissions.IsAuthenticatedOrReadOnly) & permissions.check_owner('author', ('PATCH', 'PUT', 'DELETE')) ] def get_serializer_class(self): return DetailExperienceSerializer if self.action == 'retrieve' else ShortExperienceSerializer
class UserRelationViewSet(mixins.ListModelMixin, BaseUserViewSetMixin): queryset = User.objects.all() serializer_class = UserSerializer pagination_class = pagination.factory('PageNumberPagination', page_size=20) allowed_actions = {'followers': 'followers', 'following': 'following'} def get_queryset(self): user = self.get_user_object() try: rel_field = getattr(user, self.allowed_actions[self.action]) except KeyError: raise NotFound if self.request.user.is_authenticated(): rel_field = rel_field.annotate(followed=models.ExpressionWrapper( models.Count( models.Subquery( User.following.through.objects.filter( to_user_id=self.request.user.id, from_user_id=models.OuterRef('id')).values('id'))), output_field=models.BooleanField())) else: rel_field = rel_field.annotate(followed=models.Value( False, output_field=models.BooleanField())) return rel_field.order_by('id') # for view_name in allowed_actions: # locals()[view_name] = decorators.list_route(methods=['GET'])( # lambda self, *args, **kwargs: self.list(*args, **kwargs) # ) def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) @decorators.list_route(methods=['GET']) def followers(self, *args, **kwargs): return self.list(*args, **kwargs) @decorators.list_route(methods=['GET']) def following(self, *args, **kwargs): return self.list(*args, **kwargs)
class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.UpdateModelMixin, BaseUserViewSetMixin): lookup_value_regex = re_user_lookup_value lookup_url_kwarg = 'user_pk' queryset = User.objects.all().order_by('id') serializer_class = UserSerializer pagination_class = pagination.factory('PageNumberPagination', page_size=20) permission_classes = [p.C(p.IsAuthenticatedOrReadOnly) & p.check_owner()] filter_fields = ('username', ) def get_user_queryset(self): qs = super(UserViewSet, self).get_user_queryset() if self.request.user.is_authenticated(): qs = qs.annotate(followed=models.ExpressionWrapper( models.Count( models.Subquery( User.following.through.objects.filter( to_user_id=self.request.user.id, from_user_id=models.OuterRef('id')).values('id'))), output_field=models.BooleanField())) else: qs = qs.annotate(followed=models.Value( False, output_field=models.BooleanField())) return qs def get_object(self): obj = self.get_user_object() self.check_object_permissions(self.request, obj) return obj @decorators.detail_route(['POST']) def follow(self, request, *args, **kwargs): request.user.follow(self.get_object()) return Response('OK') @decorators.detail_route(['POST']) def unfollow(self, request, *args, **kwargs): request.user.unfollow(self.get_object()) return Response('OK') @decorators.detail_route(['GET']) def stat(self, request, *args, **kwargs): user = self.get_object() data = UserSerializer(user).data return Response(data)
class PostViewSet(viewsets.ModelViewSet): serializer_class = PostSerializer pagination_class = pagination.factory('PageNumberPagination', page_size=10) permission_classes = [permissions.C(permissions.IsAuthenticatedOrReadOnly) & permissions.check_owner('author', ('PATCH', 'PUT', 'DELETE'))] # override this function to provide "request" as "None" def get_serializer_context(self): """ Extra context provided to the serializer class. """ return { 'request': None, 'format': self.format_kwarg, 'view': self } def get_queryset(self): author = self.request.query_params.get('author', None) if author is not None: queryset = Post.objects.filter(author__username=author) if self.request.user.username != author: queryset = queryset.filter(is_visible=True) else: queryset = Post.objects.filter(is_visible=True) if 'experience_id' in self.kwargs: queryset = queryset.filter(experience__id=self.kwargs['experience_id']) return queryset def perform_create(self, serializer): serializer.save(author=self.request.user) def create(self, request, *args, **kwargs): from biohub.core.conf import settings as biohub_settings from datetime import timedelta from django.utils.timezone import now user = self.request.user if Post.objects.filter( author=user, pub_time__gte=now() - timedelta(seconds=biohub_settings.THROTTLE['post']) ).exists(): raise exceptions.Throttled() return super(PostViewSet, self).create(request, *args, **kwargs)
class ActivityViewSet(viewsets.GenericViewSet, mixins.ListModelMixin): serializer_class = ActivitySerializer pagination_class = pagination.factory('PageNumberPagination', page_size=10) def get_queryset(self): queryset = Activity.objects.all() if self.action == 'timeline': user = self.request.user queryset = queryset.filter( models.Q(user__in=models.Subquery( user.following.through.objects.filter( to_user_id=user.id).values('from_user_id'))) | (models.Q(brick_name__in=models.Subquery( user.bricks_watching.through.objects.filter( user=user.id).values('brick'))) & ~models.Q(user=user.id))) user = self.request.query_params.get('user', None) type = self.request.query_params.get('type', None) if user is not None: queryset = queryset.filter(user__username=user) if type is not None: queryset = queryset.filter(type__in=type.split(',')) queryset = queryset.annotate(score=models.Case(models.When( type='Watch', then=models.Subquery( BiobrickMeta.objects.filter(part_name=models.OuterRef( 'brick_name')).values('rate_score'))), default=None)) return queryset.order_by('-acttime') @decorators.list_route(methods=['GET'], permission_classes=[permissions.IsAuthenticated]) def timeline(self, request, *args, **kwargs): return self.list(request, *args, **kwargs)
class BaseBrickViewSet(object): pagination_class = pagination.factory('PageNumberPagination') queryset = Biobrick.objects.all() @property def detail(self): if self.action == 'list': return False elif self.action == 'retrieve': return True else: return 'detail' in self.request.query_params def get_serializer_class(self): ret = BiobrickSerializer if self.action == 'list': return ret.list_creator() if not self.detail: ret = ret.short_creator() return ret
class NoticeViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet, PassUserToSerializer): serializer_class = NoticeSerializer pagination_class = pagination.factory('PageNumberPagination') permission_classes = [ p.C(p.IsAuthenticated) & p.check_owner('user', ('GET', )) ] filter_fields = ('has_read', 'category') def get_queryset(self): qs = Notice.objects.user_notices(self.request.user) id_list = self.request.query_params.get('ids', None) if id_list is not None: qs = qs.filter(id__in=id_list.split(',')) return qs.order_by('-created') @decorators.list_route(['GET']) def mark_all_as_read(self, *args, **kwargs): self.get_queryset().mark_read() return Response('OK') @decorators.detail_route(['GET']) def mark_read(self, *args, **kwargs): self.get_object().mark_read() return Response('OK') @decorators.list_route(['GET']) def categories(self, *args, **kwargs): return Response(self.get_queryset().categories()) @decorators.list_route(['GET']) def stats(self, *args, **kwargs): return Response(self.get_queryset().stats()) @decorators.list_route(['GET']) def feeds(self, request, *args, **kwargs): """ News from the users you're following. """ qs = self.get_queryset().filter(category__startswith='Following').all() page = self.paginate_queryset(qs) qs.mark_read() # See issue 40 return self.get_paginated_response( NoticeSerializer(page, many=True).data) @decorators.list_route(['GET']) def has_new_feeds(self, request, *args, **kwargs): """ Check if there is a new feed. """ n_feeds = self.get_queryset().filter(category__startswith='Following', has_read=False).count() return Response({'count': n_feeds}) @decorators.list_route(['GET']) def my(self, request, *args, **kwargs): """ Notifications sent specifically to the current user. """ qs = self.get_queryset().filter(~Q( category__startswith='Following')).all() page = self.paginate_queryset(qs) qs.mark_read() # See issue 40 return self.get_paginated_response( NoticeSerializer(page, many=True).data) @decorators.list_route(['GET']) def has_new_notifications(self, request, *args, **kwargs): """ Check if there is a new notification. """ qs = self.get_queryset().filter(~Q(category__startswith='Following'), has_read=False) notice = qs.first() return Response({ 'count': qs.count(), 'latest': NoticeSerializer(notice).data })