|
61 | 61 | from geonode.maps.models import Map
|
62 | 62 | from geonode.layers.models import Dataset
|
63 | 63 | from geonode.favorite.models import Favorite
|
64 |
| -from geonode.base.models import Configuration, ExtraMetadata |
| 64 | +from geonode.base.models import Configuration, ExtraMetadata, LinkedResource |
65 | 65 | from geonode.thumbs.exceptions import ThumbnailError
|
66 | 66 | from geonode.thumbs.thumbnails import create_thumbnail
|
67 | 67 | from geonode.thumbs.utils import _decode_base64, BASE64_PATTERN
|
|
109 | 109 | TopicCategorySerializer,
|
110 | 110 | RegionSerializer,
|
111 | 111 | ThesaurusKeywordSerializer,
|
112 |
| - ExtraMetadataSerializer, |
| 112 | + ExtraMetadataSerializer, LinkedResourceSerializer, |
113 | 113 | )
|
114 | 114 | from .pagination import GeoNodeApiPagination
|
115 | 115 | from geonode.base.utils import validate_extra_metadata
|
@@ -1489,48 +1489,59 @@ def _get_request_params(self, request, encode=False):
|
1489 | 1489 | url_name="linked_resources",
|
1490 | 1490 | )
|
1491 | 1491 | def linked_resources(self, request, pk, *args, **kwargs):
|
1492 |
| - try: |
1493 |
| - """ |
1494 |
| - To let the API be able to filter the linked result, we cannot rely on the DynamicFilterBackend |
1495 |
| - works on the resource and not on the linked one. |
1496 |
| - So if we want to filter the linked resource by "resource_type" |
1497 |
| - we have to search in the query params like in the following code: |
1498 |
| - _filters = { |
1499 |
| - x: y |
1500 |
| - for x, y |
1501 |
| - in request.query_params.items() |
1502 |
| - if x not in ["page_size", "page"] |
1503 |
| - } |
1504 |
| - We have to exclude the paging code or will raise the: |
1505 |
| - "Cannot resolve keyword into the field..." |
1506 |
| - """ |
1507 |
| - _obj = self.get_object().get_real_instance() |
1508 |
| - if issubclass(_obj.get_real_concrete_instance_class(), GeoApp): |
1509 |
| - raise NotImplementedError("Not implemented: this endpoint is not available for GeoApps") |
1510 |
| - # getting the resource dynamically list based on the above mapping |
1511 |
| - resources = _obj.linked_resources |
1512 |
| - |
1513 |
| - if request.query_params: |
1514 |
| - _filters = {x: y for x, y in request.query_params.items() if x not in ["page_size", "page"]} |
1515 |
| - if _filters: |
1516 |
| - resources = resources.filter(**_filters) |
1517 |
| - |
1518 |
| - resources = get_visible_resources( |
1519 |
| - resources, |
1520 |
| - user=request.user, |
1521 |
| - admin_approval_required=settings.ADMIN_MODERATE_UPLOADS, |
1522 |
| - unpublished_not_visible=settings.RESOURCE_PUBLISHING, |
1523 |
| - private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES, |
1524 |
| - ).order_by("-pk") |
1525 |
| - |
1526 |
| - paginator = GeoNodeApiPagination() |
1527 |
| - paginator.page_size = request.GET.get("page_size", 10) |
1528 |
| - result_page = paginator.paginate_queryset(resources, request) |
1529 |
| - serializer = SimpleResourceSerializer(result_page, embed=True, many=True) |
1530 |
| - return paginator.get_paginated_response({"resources": serializer.data}) |
1531 |
| - except NotImplementedError as e: |
1532 |
| - logger.error(e) |
1533 |
| - return Response(data={"message": e.args[0], "success": False}, status=501, exception=True) |
1534 |
| - except Exception as e: |
1535 |
| - logger.error(e) |
1536 |
| - return Response(data={"message": e.args[0], "success": False}, status=500, exception=True) |
| 1492 | + return base_linked_resources(self.get_object().get_real_instance(), request.user, request.GET) |
| 1493 | + |
| 1494 | + |
| 1495 | +def base_linked_resources(instance, user, params): |
| 1496 | + try: |
| 1497 | + visibile_resources = get_visible_resources( |
| 1498 | + ResourceBase.objects, |
| 1499 | + user=user, |
| 1500 | + admin_approval_required=settings.ADMIN_MODERATE_UPLOADS, |
| 1501 | + unpublished_not_visible=settings.RESOURCE_PUBLISHING, |
| 1502 | + private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES, |
| 1503 | + ).order_by("-pk") |
| 1504 | + visible_ids = [res.id for res in visibile_resources] |
| 1505 | + |
| 1506 | + # linked_resources = LinkedResource.get_linked_resources(source=instance).filter(target__in=resources) |
| 1507 | + # linked_by = LinkedResource.get_linked_resources(target=instance).filter(source__in=resources) |
| 1508 | + |
| 1509 | + linked_resources = [lres for lres in instance.get_linked_resources() |
| 1510 | + if lres.target.id in visible_ids] |
| 1511 | + linked_by = [lres for lres in instance.get_linked_resources(as_target=True) |
| 1512 | + if lres.source.id in visible_ids] |
| 1513 | + |
| 1514 | + warnings = { |
| 1515 | + 'DEPRECATION': "'resources' field is deprecated, please use 'linked_to'", |
| 1516 | + } |
| 1517 | + |
| 1518 | + if "page_size" in params or "page" in params: |
| 1519 | + warnings['PAGINATION'] = "Pagination is not supported on this call" |
| 1520 | + |
| 1521 | + # "resources" will be deprecated, so next block is temporary |
| 1522 | + # "resources" at the moment it's the only element rendered, so we want to add there both the linked_resources and the linked_by |
| 1523 | + # we want to tell them apart, so we're adding an attr to store this info, that will be used in the SimpleResourceSerializer |
| 1524 | + resources = [] |
| 1525 | + for lres in linked_resources: |
| 1526 | + res = lres.target |
| 1527 | + setattr(res, 'is_target', True) |
| 1528 | + resources.append(res) |
| 1529 | + for lres in linked_by: |
| 1530 | + res = lres.source |
| 1531 | + setattr(res, 'is_target', False) |
| 1532 | + resources.append(res) |
| 1533 | + |
| 1534 | + ret = { |
| 1535 | + "WARNINGS": warnings, |
| 1536 | + "resources": SimpleResourceSerializer(resources, embed=True, many=True).data, # deprecated |
| 1537 | + "linked_to": LinkedResourceSerializer(linked_resources, embed=True, many=True).data, |
| 1538 | + "linked_by": LinkedResourceSerializer(instance=linked_by, serialize_source=True, embed=True, many=True).data, |
| 1539 | + } |
| 1540 | + |
| 1541 | + return Response(ret) |
| 1542 | + except NotImplementedError as e: |
| 1543 | + logger.exception(e) |
| 1544 | + return Response(data={"message": e.args[0], "success": False}, status=501, exception=True) |
| 1545 | + except Exception as e: |
| 1546 | + logger.exception(e) |
| 1547 | + return Response(data={"message": e.args[0], "success": False}, status=500, exception=True) |
0 commit comments