Skip to content
This repository has been archived by the owner on Dec 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #3607 from dkliban/return-relative-href
Browse files Browse the repository at this point in the history
Problem: identity fields are serialized as full URLs
  • Loading branch information
dkliban committed Sep 4, 2018
2 parents 57c5d4e + 1099266 commit d38aee4
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 36 deletions.
4 changes: 4 additions & 0 deletions plugin/pulpcore/plugin/serializers.py
Expand Up @@ -2,8 +2,12 @@
from pulpcore.app.serializers import ( # noqa
AsyncOperationResponseSerializer,
ContentSerializer,
IdentityField,
NestedIdentityField,
NestedRelatedField,
RemoteSerializer,
PublisherSerializer,
RelatedField,
RepositorySyncURLSerializer,
RepositoryPublishURLSerializer,
)
2 changes: 1 addition & 1 deletion pulpcore/pulpcore/app/response.py
Expand Up @@ -23,6 +23,6 @@ def __init__(self, result, request):
the response.
request (rest_framework.request.Request): Request used to generate the _href urls
"""
task = {"_href": reverse('tasks-detail', args=[result.id], request=request),
task = {"_href": reverse('tasks-detail', args=[result.id], request=None),
"task_id": result.id}
super().__init__(data=task, status=202)
4 changes: 4 additions & 0 deletions pulpcore/pulpcore/app/serializers/__init__.py
Expand Up @@ -8,6 +8,10 @@
MasterModelSerializer,
DetailIdentityField,
DetailRelatedField,
IdentityField,
NestedIdentityField,
NestedRelatedField,
RelatedField,
view_name_for_model,
viewset_for_model,
validate_unknown_fields,
Expand Down
52 changes: 50 additions & 2 deletions pulpcore/pulpcore/app/serializers/base.py
Expand Up @@ -9,6 +9,9 @@
from rest_framework.fields import SkipField
from rest_framework.relations import PKOnlyObject

from rest_framework_nested.relations import NestedHyperlinkedIdentityField, \
NestedHyperlinkedRelatedField

from pulpcore.app.apps import pulp_plugin_configs

# a little cache so viewset_for_model doesn't have iterate over every app every time
Expand Down Expand Up @@ -312,10 +315,33 @@ def _view_name(self, obj):
raise ValueError(msg)
return view_name_for_model(obj, 'detail')

def get_url(self, obj, view_name, *args, **kwargs):
def get_url(self, obj, view_name, request, *args, **kwargs):
# ignore the passed in view name and return the url to the cast unit, not the generic unit
request = None
view_name = self._view_name(obj)
return super().get_url(obj, view_name, *args, **kwargs)
return super().get_url(obj, view_name, request, *args, **kwargs)


class IdentityField(serializers.HyperlinkedIdentityField):
"""IdentityField for use in the _href field of non-Master/Detail Serializers.
The get_url method is overriden so relative URLs are returned.
"""
def get_url(self, obj, view_name, request, *args, **kwargs):
# ignore the passed in view name and return the url to the cast unit, not the generic unit
request = None
return super().get_url(obj, view_name, request, *args, **kwargs)


class RelatedField(serializers.HyperlinkedRelatedField):
"""RelatedField when relating to non-Master/Detail models
When using this field on a serializer, it will serialize the related resource as a relative URL.
"""
def get_url(self, obj, view_name, request, *args, **kwargs):
# ignore the passed in view name and return the url to the cast unit, not the generic unit
request = None
return super().get_url(obj, view_name, request, *args, **kwargs)


class DetailIdentityField(_DetailFieldMixin, serializers.HyperlinkedIdentityField):
Expand Down Expand Up @@ -353,6 +379,28 @@ class to get the relevant `view_name`.
return False


class NestedIdentityField(NestedHyperlinkedIdentityField):
"""NestedIdentityField for use with nested resources.
When using this field in a serializer, it serializes the as a relative URL.
"""
def get_url(self, obj, view_name, request, *args, **kwargs):
# ignore the passed in view name and return the url to the cast unit, not the generic unit
request = None
return super().get_url(obj, view_name, request, *args, **kwargs)


class NestedRelatedField(NestedHyperlinkedRelatedField):
"""NestedRelatedField for use when relating to nested resources.
When using this field in a serializer, it serializes the related resource as a relative URL.
"""
def get_url(self, obj, view_name, request, *args, **kwargs):
# ignore the passed in view name and return the url to the cast unit, not the generic unit
request = None
return super().get_url(obj, view_name, request, *args, **kwargs)


class AsyncOperationResponseSerializer(serializers.Serializer):
"""
Serializer for asynchronous operations.
Expand Down
4 changes: 2 additions & 2 deletions pulpcore/pulpcore/app/serializers/content.py
Expand Up @@ -22,7 +22,7 @@ class ContentSerializer(base.MasterModelSerializer):
artifacts = fields.ContentArtifactsField(
help_text=_("A dict mapping relative paths inside the Content to the corresponding"
"Artifact URLs. E.g.: {'relative/path': "
"'http://localhost/full_artifact_path'}"),
"'/artifacts/1/'"),
)

class Meta:
Expand All @@ -31,7 +31,7 @@ class Meta:


class ArtifactSerializer(base.ModelSerializer):
_href = serializers.HyperlinkedIdentityField(
_href = base.IdentityField(
view_name='artifacts-detail',
)

Expand Down
13 changes: 6 additions & 7 deletions pulpcore/pulpcore/app/serializers/fields.py
Expand Up @@ -7,7 +7,7 @@
from rest_framework_nested.relations import NestedHyperlinkedRelatedField

from pulpcore.app import models
from pulpcore.app.serializers import DetailRelatedField
from pulpcore.app.serializers import DetailRelatedField, RelatedField


class ContentRelatedField(DetailRelatedField):
Expand Down Expand Up @@ -46,10 +46,9 @@ def run_validation(self, data):
if os.path.isabs(relative_path):
raise serializers.ValidationError(_("Relative path can't start with '/'. "
"{0}").format(relative_path))
artifactfield = \
serializers.HyperlinkedRelatedField(view_name='artifacts-detail',
queryset=models.Artifact.objects.all(),
source='*', initial=url)
artifactfield = RelatedField(view_name='artifacts-detail',
queryset=models.Artifact.objects.all(),
source='*', initial=url)
try:
artifact = artifactfield.run_validation(data=url)
ret[relative_path] = artifact
Expand Down Expand Up @@ -95,7 +94,7 @@ def to_representation(self, value):
for content_artifact in value:
if content_artifact.artifact_id:
url = reverse('artifacts-detail', kwargs={'pk': content_artifact.artifact_id},
request=self.context['request'])
request=None)
else:
url = None
ret[content_artifact.relative_path] = url
Expand Down Expand Up @@ -140,7 +139,7 @@ def get_url(self, obj, view_name, request, format):
'repository_pk': version.repository.pk,
'number': version.number,
}
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
return self.reverse(view_name, kwargs=kwargs, request=None, format=format)

def get_attribute(self, instance):
"""
Expand Down
4 changes: 2 additions & 2 deletions pulpcore/pulpcore/app/serializers/progress.py
Expand Up @@ -3,7 +3,7 @@
from rest_framework import serializers

from pulpcore.app import models
from pulpcore.app.serializers import ModelSerializer
from pulpcore.app.serializers import ModelSerializer, RelatedField


class ProgressReportSerializer(ModelSerializer):
Expand All @@ -30,7 +30,7 @@ class ProgressReportSerializer(ModelSerializer):
help_text=_("The suffix to be shown with the progress report."),
read_only=True
)
task = serializers.HyperlinkedRelatedField(
task = RelatedField(
help_text=_("The task associated with this progress report."),
read_only=True,
view_name='tasks-detail'
Expand Down
30 changes: 16 additions & 14 deletions pulpcore/pulpcore/app/serializers/repository.py
Expand Up @@ -12,21 +12,23 @@
DetailIdentityField,
DetailRelatedField,
GenericKeyValueRelatedField,
IdentityField,
NestedIdentityField,
NestedRelatedField,
RelatedField,
LatestVersionField,
MasterModelSerializer,
ModelSerializer,
)
from pulpcore.app.serializers import validate_unknown_fields
from rest_framework_nested.relations import (NestedHyperlinkedIdentityField,
NestedHyperlinkedRelatedField)
from rest_framework_nested.serializers import NestedHyperlinkedModelSerializer


class RepositorySerializer(ModelSerializer):
_href = serializers.HyperlinkedIdentityField(
_href = IdentityField(
view_name='repositories-detail'
)
_versions_href = serializers.HyperlinkedIdentityField(
_versions_href = IdentityField(
view_name='versions-list',
lookup_url_kwarg='repository_pk',
)
Expand Down Expand Up @@ -177,7 +179,7 @@ class RepositoryPublishURLSerializer(serializers.Serializer):
view_name='repositories-detail',
)

repository_version = NestedHyperlinkedRelatedField(
repository_version = NestedRelatedField(
help_text=_('A URI of the repository version to be published.'),
required=False,
label=_('Repository Version'),
Expand Down Expand Up @@ -239,7 +241,7 @@ class Meta:


class DistributionSerializer(ModelSerializer):
_href = serializers.HyperlinkedIdentityField(
_href = IdentityField(
view_name='distributions-detail'
)
name = serializers.CharField(
Expand Down Expand Up @@ -269,7 +271,7 @@ class DistributionSerializer(ModelSerializer):
queryset=models.Publisher.objects.all(),
allow_null=True
)
publication = serializers.HyperlinkedRelatedField(
publication = RelatedField(
required=False,
help_text=_('The publication being served as defined by this distribution'),
queryset=models.Publication.objects.exclude(complete=False),
Expand Down Expand Up @@ -349,7 +351,7 @@ def validate(self, data):


class PublicationSerializer(ModelSerializer):
_href = serializers.HyperlinkedIdentityField(
_href = IdentityField(
view_name='publications-detail'
)
publisher = DetailRelatedField(
Expand All @@ -363,7 +365,7 @@ class PublicationSerializer(ModelSerializer):
read_only=True,
view_name='distributions-detail',
)
repository_version = NestedHyperlinkedRelatedField(
repository_version = NestedRelatedField(
view_name='versions-detail',
lookup_field='number',
parent_lookup_kwargs={'repository_pk': 'repository__pk'},
Expand All @@ -380,19 +382,19 @@ class Meta:


class RepositoryVersionSerializer(ModelSerializer, NestedHyperlinkedModelSerializer):
_href = NestedHyperlinkedIdentityField(
_href = NestedIdentityField(
view_name='versions-detail',
lookup_field='number', parent_lookup_kwargs={'repository_pk': 'repository__pk'},
)
_content_href = NestedHyperlinkedIdentityField(
_content_href = NestedIdentityField(
view_name='versions-content',
lookup_field='number', parent_lookup_kwargs={'repository_pk': 'repository__pk'},
)
_added_href = NestedHyperlinkedIdentityField(
_added_href = NestedIdentityField(
view_name='versions-added-content',
lookup_field='number', parent_lookup_kwargs={'repository_pk': 'repository__pk'},
)
_removed_href = NestedHyperlinkedIdentityField(
_removed_href = NestedIdentityField(
view_name='versions-removed-content',
lookup_field='number', parent_lookup_kwargs={'repository_pk': 'repository__pk'},
)
Expand All @@ -411,7 +413,7 @@ class RepositoryVersionSerializer(ModelSerializer, NestedHyperlinkedModelSeriali
help_text=_('A list of content units to remove from the latest repository version'),
write_only=True
)
base_version = NestedHyperlinkedRelatedField(
base_version = NestedRelatedField(
required=False,
help_text=_('A repository version whose content will be used as the initial set of content '
'for the new repository version'),
Expand Down
11 changes: 5 additions & 6 deletions pulpcore/pulpcore/app/serializers/task.py
Expand Up @@ -3,7 +3,8 @@
from rest_framework import serializers

from pulpcore.app import models
from pulpcore.app.serializers import ModelSerializer, ProgressReportSerializer
from pulpcore.app.serializers import IdentityField, RelatedField, ModelSerializer, \
ProgressReportSerializer

from .base import viewset_for_model

Expand All @@ -30,9 +31,7 @@ class Meta:


class TaskSerializer(ModelSerializer):
_href = serializers.HyperlinkedIdentityField(
view_name='tasks-detail',
)
_href = IdentityField(view_name='tasks-detail')
state = serializers.CharField(
help_text=_("The current state of the task. The possible values include:"
" 'waiting', 'skipped', 'running', 'completed', 'failed' and 'canceled'."),
Expand All @@ -56,7 +55,7 @@ class TaskSerializer(ModelSerializer):
"task."),
read_only=True
)
worker = serializers.HyperlinkedRelatedField(
worker = RelatedField(
help_text=_("The worker associated with this task."
" This field is empty if a worker is not yet assigned."),
read_only=True,
Expand Down Expand Up @@ -100,7 +99,7 @@ class Meta:


class WorkerSerializer(ModelSerializer):
_href = serializers.HyperlinkedIdentityField(view_name='workers-detail')
_href = IdentityField(view_name='workers-detail')

name = serializers.CharField(
help_text=_('The name of the worker.'),
Expand Down
4 changes: 2 additions & 2 deletions pulpcore/pulpcore/app/serializers/user.py
Expand Up @@ -6,7 +6,7 @@
from rest_framework.validators import UniqueValidator

from pulpcore.app.models import User
from pulpcore.app.serializers import ModelSerializer
from pulpcore.app.serializers import IdentityField, ModelSerializer


class PasswordSerializer(serializers.CharField):
Expand All @@ -25,7 +25,7 @@ def to_internal_value(self, data):


class UserSerializer(ModelSerializer):
_href = serializers.HyperlinkedIdentityField(view_name='users-detail')
_href = IdentityField(view_name='users-detail')

username = serializers.CharField(
help_text=_("Required. {} characters or fewer. Letters, digits and @/./+/-/_ only.").format(
Expand Down

0 comments on commit d38aee4

Please sign in to comment.