Repository: airavata-django-portal Updated Branches: refs/heads/master 4595c9cd6 -> 88e8db3d4
Fix REST API URLs for projects, experiments with special chars Project: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/repo Commit: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/commit/d5501430 Tree: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/tree/d5501430 Diff: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/diff/d5501430 Branch: refs/heads/master Commit: d5501430745d1a4cfc30660a504bd58cea1b4cb9 Parents: 4595c9c Author: Marcus Christie <[email protected]> Authored: Mon Sep 11 15:12:26 2017 -0400 Committer: Marcus Christie <[email protected]> Committed: Mon Sep 11 15:12:26 2017 -0400 ---------------------------------------------------------------------- django_airavata/apps/api/serializers.py | 21 +++++++++++++++++---- django_airavata/apps/api/urls.py | 6 ++++-- 2 files changed, 21 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d5501430/django_airavata/apps/api/serializers.py ---------------------------------------------------------------------- diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py index c8c8a18..c082f6b 100644 --- a/django_airavata/apps/api/serializers.py +++ b/django_airavata/apps/api/serializers.py @@ -3,6 +3,19 @@ from apache.airavata.model.workspace.ttypes import Project from rest_framework import serializers +from urllib.parse import quote + + +class FullyEncodedHyperlinkedIdentityField(serializers.HyperlinkedIdentityField): + def get_url(self, obj, view_name, request, format): + lookup_value = getattr(obj, self.lookup_field) + encoded_lookup_value = quote(lookup_value, safe="") + # Bit of a hack. Django's URL reversing does URL encoding but it doesn't + # encode all characters including some like '/' that are used in URL + # mappings. + kwargs = {self.lookup_url_kwarg: "__PLACEHOLDER__"} + url = self.reverse(view_name, kwargs=kwargs, request=request, format=format) + return url.replace("__PLACEHOLDER__", encoded_lookup_value) class ProjectSerializer(serializers.Serializer): @@ -10,21 +23,21 @@ class ProjectSerializer(serializers.Serializer): name = serializers.CharField(required=True) owner = serializers.CharField(required=True) gatewayId = serializers.CharField(required=True) - # TODO: fix these hyperlinked fields - # experiments = serializers.HyperlinkedIdentityField(view_name='api_project_experiments_list', lookup_field='projectID', lookup_url_kwarg='project_id') + experiments = FullyEncodedHyperlinkedIdentityField(view_name='api_project_experiments_list', lookup_field='projectID', lookup_url_kwarg='project_id') + # TODO: maybe just have a get() method to get the deserialized object? def create(self, validated_data): return Project(**validated_data) def update(self, instance, validated_data): raise Exception("Not implemented") + class ExperimentSerializer(serializers.Serializer): experimentId = serializers.CharField(required=True) projectId = serializers.CharField(required=True) - # TODO: fix these hyperlinked fields - # project = serializers.HyperlinkedIdentityField(view_name='api_project_detail', lookup_field='projectId', lookup_url_kwarg='project_id') + project = FullyEncodedHyperlinkedIdentityField(view_name='api_project_detail', lookup_field='projectId', lookup_url_kwarg='project_id') gatewayId = serializers.CharField(required=True) experimentType = serializers.CharField(required=True) userName = serializers.CharField(required=True) http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d5501430/django_airavata/apps/api/urls.py ---------------------------------------------------------------------- diff --git a/django_airavata/apps/api/urls.py b/django_airavata/apps/api/urls.py index c5d2423..9cd7d75 100644 --- a/django_airavata/apps/api/urls.py +++ b/django_airavata/apps/api/urls.py @@ -7,8 +7,10 @@ from rest_framework.urlpatterns import format_suffix_patterns urlpatterns = [ url(r'^$', views.api_root), url(r'^projects/$', views.ProjectList.as_view(), name='api_project_list'), - url(r'^projects/(?P<project_id>[^/]+)/$', views.ProjectDetail.as_view(), name='api_project_detail'), - url(r'^projects/(?P<project_id>[^/]+)/experiments/$', views.ProjectExperimentList.as_view(), name='api_project_experiments_list'), + # More specific, longer URLs should come before less specific, shorter ones + # since the regular expression for project_id allows any character, even '/' + url(r'^projects/(?P<project_id>.+)/experiments/$', views.ProjectExperimentList.as_view(), name='api_project_experiments_list'), + url(r'^projects/(?P<project_id>.+)/$', views.ProjectDetail.as_view(), name='api_project_detail'), url(r'^experiments/$', views.ExperimentList.as_view(), name='api_experiment_list'), ]
