diff --git a/Pipfile b/Pipfile index 9bd1909..4a83d5d 100644 --- a/Pipfile +++ b/Pipfile @@ -30,3 +30,4 @@ markdown = "<3.2" django-filter = "==2.4.0" coreapi = "*" psycopg2-binary = "*" +django-restql = "*" diff --git a/core/serializers.py b/core/serializers.py index 7e5ca67..625d153 100644 --- a/core/serializers.py +++ b/core/serializers.py @@ -170,8 +170,8 @@ class BoardSerializer(serializers.HyperlinkedModelSerializer): "id", "name", "private", - "pins", - "pins_detail", + "total_pins", + "cover", "published", "submitter", "pins_to_add", @@ -183,15 +183,11 @@ class BoardSerializer(serializers.HyperlinkedModelSerializer): } submitter = UserSerializer(read_only=True) - pins_detail = serializers.SerializerMethodField( + total_pins = serializers.SerializerMethodField( read_only=True, ) - pins = serializers.HyperlinkedRelatedField( - write_only=True, - queryset=Pin.objects.all(), - view_name="pin-detail", - many=True, - required=False, + cover = serializers.SerializerMethodField( + read_only=True, ) pins_to_add = PinIdListField( max_length=10, @@ -208,11 +204,17 @@ class BoardSerializer(serializers.HyperlinkedModelSerializer): help_text="only patch method works for this field" ) - def get_pins_detail(self, instance): + def get_total_pins(self, instance): query = instance.pins.all() request = self.context['request'] query = filter_private_pin(request, query) - return [PinSerializer(pin, context=self.context).data for pin in query] + return query.count() + + def get_cover(self, instance: Board) -> dict or None: + pin = instance.pins.first() + if pin is None: + return None + return PinSerializer(pin, context=self.context).data @staticmethod def _get_list(pins_id): diff --git a/core/views.py b/core/views.py index df4a7d7..773945e 100644 --- a/core/views.py +++ b/core/views.py @@ -23,7 +23,7 @@ class ImageViewSet(mixins.CreateModelMixin, GenericViewSet): class PinViewSet(viewsets.ModelViewSet): serializer_class = api.PinSerializer filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter) - filter_fields = ("submitter__username", 'tags__name', ) + filter_fields = ("submitter__username", 'tags__name', "pins__id") ordering_fields = ('-id', ) ordering = ('-id', ) permission_classes = [IsOwnerOrReadOnly("submitter"), OwnerOnlyIfPrivate("submitter")] diff --git a/pinry-spa/src/components/Boards.vue b/pinry-spa/src/components/Boards.vue index 1daa97e..d89373a 100644 --- a/pinry-spa/src/components/Boards.vue +++ b/pinry-spa/src/components/Boards.vue @@ -67,17 +67,16 @@ import bus from './utils/bus'; function createBoardItem(board) { const defaultPreviewImage = placeholder; const boardItem = {}; - const pins4Board = board.pins_detail; let previewImage = { image: { thumbnail: { image: null, width: 240, height: 240 } }, }; - if (pins4Board.length > 0) { - [previewImage] = pins4Board; + if (board.cover !== null) { + previewImage = board.cover; } boardItem.id = board.id; boardItem.name = board.name; boardItem.private = board.private; - boardItem.total_pins = pins4Board.length; + boardItem.total_pins = board.total_pins; if (previewImage.image.thumbnail.image !== null) { boardItem.preview_image_url = pinHandler.escapeUrl( previewImage.image.thumbnail.image, diff --git a/pinry-spa/src/components/Pins.vue b/pinry-spa/src/components/Pins.vue index 7497933..ebb71c2 100644 --- a/pinry-spa/src/components/Pins.vue +++ b/pinry-spa/src/components/Pins.vue @@ -256,23 +256,11 @@ export default { this.status.loading = true; let promise; if (this.pinFilters.tagFilter) { - promise = API.fetchPins(this.status.offset, this.pinFilters.tagFilter); + promise = API.fetchPins(this.status.offset, this.pinFilters.tagFilter, null, null); } else if (this.pinFilters.userFilter) { - promise = API.fetchPins(this.status.offset, null, this.pinFilters.userFilter); + promise = API.fetchPins(this.status.offset, null, this.pinFilters.userFilter, null); } else if (this.pinFilters.boardFilter) { - promise = new Promise( - (resolve, reject) => { - API.fetchPinsForBoard(this.pinFilters.boardFilter).then( - (resp) => { - this.editorMeta.currentBoard = resp.data.board; - resolve(resp); - }, - (error) => { - reject(error); - }, - ); - }, - ); + promise = API.fetchPins(this.status.offset, null, null, this.pinFilters.boardFilter); } else if (this.pinFilters.idFilter) { promise = API.fetchPin(this.pinFilters.idFilter); } else { diff --git a/pinry-spa/src/components/api.js b/pinry-spa/src/components/api.js index 885b65d..3db9755 100644 --- a/pinry-spa/src/components/api.js +++ b/pinry-spa/src/components/api.js @@ -111,7 +111,7 @@ const Pin = { }; -function fetchPins(offset, tagFilter, userFilter) { +function fetchPins(offset, tagFilter, userFilter, boardFilter) { const url = `${API_PREFIX}pins/`; const queryArgs = { format: 'json', @@ -121,6 +121,7 @@ function fetchPins(offset, tagFilter, userFilter) { }; if (tagFilter) queryArgs.tags__name = tagFilter; if (userFilter) queryArgs.submitter__username = userFilter; + if (boardFilter) queryArgs.pins__id = boardFilter; return axios.get( url, { params: queryArgs }, @@ -149,20 +150,6 @@ function fetchPin(pinId) { ); } -function fetchPinsForBoard(boardId) { - const url = `${API_PREFIX}boards/${boardId}/`; - return new Promise( - (resolve, reject) => { - axios.get(url).then( - (resp) => { - resolve({ data: { results: resp.data.pins_detail, next: null, board: resp.data } }); - }, - error => reject(error), - ); - }, - ); -} - function fetchBoardForUser(username, offset = 0, limit = 50) { const prefix = `${API_PREFIX}boards/?submitter__username=${username}`; const url = `${prefix}&offset=${offset}&limit=${limit}`; @@ -298,7 +285,6 @@ export default { Board, fetchPin, fetchPins, - fetchPinsForBoard, fetchBoardForUser, User, };