Fix HyperLinkedRelatedFields serializers and fields

This makes the HyperLinkedRelatedFields work as they are intended to.

Change-Id: I6c9556a4ad6127471dc7cb2139c32c1d74a36704
This commit is contained in:
Guillaume Vincent 2018-03-12 10:34:17 +01:00 committed by David Moreau Simard
parent 23fbf95672
commit a1ed3a3291
No known key found for this signature in database
GPG Key ID: 33A07694CBB71ECC
4 changed files with 101 additions and 121 deletions

View File

@ -6,7 +6,6 @@ import zlib
from api import models
from django.utils import timezone
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
DATE_FORMAT = "(iso-8601: 2016-05-06T17:20:25.749489-04:00)"
DURATION_FORMAT = "([DD] [HH:[MM:]]ss[.uuuuuu])"
@ -42,10 +41,12 @@ class BaseSerializer(serializers.ModelSerializer):
Serializer for the data in the model base
"""
created = serializers.DateTimeField(
read_only=True, help_text='Date of creation %s' % DATE_FORMAT
read_only=True,
help_text='Date of creation %s' % DATE_FORMAT
)
updated = serializers.DateTimeField(
read_only=True, help_text='Date of last update %s' % DATE_FORMAT
read_only=True,
help_text='Date of last update %s' % DATE_FORMAT
)
age = serializers.DurationField(
read_only=True,
@ -87,15 +88,15 @@ class DurationSerializer(serializers.ModelSerializer):
abstract = True
class PlaybookSerializer(BaseSerializer, DurationSerializer):
class PlaybookSerializer(serializers.HyperlinkedModelSerializer, BaseSerializer):
class Meta:
model = models.Playbook
fields = '__all__'
plays = serializers.HyperlinkedRelatedField(
many=True,
view_name='play-detail',
read_only=True,
view_name='plays',
help_text='Plays associated to this playbook'
)
# tasks = serializers.HyperlinkedRelatedField(
@ -128,11 +129,11 @@ class PlaybookSerializer(BaseSerializer, DurationSerializer):
# view_name='files',
# help_text='Records associated to this playbook'
# )
parameters = CompressedObjectField(
initial={},
help_text='A JSON dictionary containing Ansible command parameters'
)
#
# parameters = CompressedObjectField(
# initial={},
# help_text='A JSON dictionary containing Ansible command parameters'
# )
path = serializers.CharField(help_text='Path to the playbook file')
ansible_version = serializers.CharField(
help_text='Version of Ansible used to run this playbook'
@ -147,61 +148,61 @@ class PlaySerializer(BaseSerializer, DurationSerializer):
model = models.Play
fields = '__all__'
class TaskSerializer(BaseSerializer, DurationSerializer):
class Meta:
model = models.Task
fields = '__all__'
class HostSerializer(BaseSerializer):
class Meta:
model = models.Host
fields = '__all__'
class ResultSerializer(BaseSerializer, DurationSerializer):
class Meta:
model = models.Result
fields = '__all__'
class RecordSerializer(BaseSerializer):
class Meta:
model = models.Record
fields = '__all__'
class FileContentSerializer(BaseSerializer):
class Meta:
model = models.FileContent
fields = ('contents', 'sha1')
contents = CompressedTextField(help_text='Contents of the file')
sha1 = serializers.CharField(read_only=True, help_text='sha1 of the file')
def create(self, validated_data):
sha1 = hashlib.sha1(validated_data['contents']).hexdigest()
validated_data['sha1'] = sha1
obj, created = models.FileContent.objects.get_or_create(
**validated_data
)
return obj
class FileSerializer(BaseSerializer):
path = serializers.CharField(help_text='Path to the file')
content = FileContentSerializer()
def create(self, validated_data):
contents = validated_data.pop('content')['contents']
obj, created = models.FileContent.objects.get_or_create(
contents=contents,
sha1=hashlib.sha1(contents).hexdigest()
)
validated_data['content'] = obj
return models.File.objects.create(**validated_data)
class Meta:
model = models.File
fields = ('id', 'path', 'content', 'playbook')
#
# class TaskSerializer(BaseSerializer, DurationSerializer):
# class Meta:
# model = models.Task
# fields = '__all__'
#
#
# class HostSerializer(BaseSerializer):
# class Meta:
# model = models.Host
# fields = '__all__'
#
#
# class ResultSerializer(BaseSerializer, DurationSerializer):
# class Meta:
# model = models.Result
# fields = '__all__'
#
#
# class RecordSerializer(BaseSerializer):
# class Meta:
# model = models.Record
# fields = '__all__'
#
#
# class FileContentSerializer(BaseSerializer):
# class Meta:
# model = models.FileContent
# fields = ('contents', 'sha1')
#
# contents = CompressedTextField(help_text='Contents of the file')
# sha1 = serializers.CharField(read_only=True, help_text='sha1 of the file')
#
# def create(self, validated_data):
# sha1 = hashlib.sha1(validated_data['contents']).hexdigest()
# validated_data['sha1'] = sha1
# obj, created = models.FileContent.objects.get_or_create(
# **validated_data
# )
# return obj
#
#
# class FileSerializer(BaseSerializer):
# path = serializers.CharField(help_text='Path to the file')
# content = FileContentSerializer()
#
# def create(self, validated_data):
# contents = validated_data.pop('content')['contents']
# obj, created = models.FileContent.objects.get_or_create(
# contents=contents,
# sha1=hashlib.sha1(contents).hexdigest()
# )
# validated_data['content'] = obj
# return models.File.objects.create(**validated_data)
#
# class Meta:
# model = models.File
# fields = ('id', 'path', 'content', 'playbook')

View File

@ -15,28 +15,16 @@
# You should have received a copy of the GNU General Public License
# along with ARA. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from api import views
REST_FRAMEWORK = {
# Use URL-based versioning
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': {'v1'},
}
router = DefaultRouter()
router.register(r'playbooks', views.PlaybookViewSet)
router.register(r'plays', views.PlayViewSet)
router.register(r'tasks', views.TaskViewSet)
router.register(r'hosts', views.HostViewSet)
router.register(r'results', views.ResultViewSet)
router.register(r'records', views.RecordViewSet)
router.register(r'files', views.FileViewSet)
# router.register(r'filecontent', views.FileContentViewSet)
urlpatterns = [
url(r'^(?P<version>[v1]+)/', include(router.urls)),
url(r'^$', views.api_root),
url(r'^playbooks/$', views.PlaybookList.as_view(), name='playbook-list'),
url(r'^playbooks/(?P<pk>[0-9]+)/$', views.PlaybookDetail.as_view(), name='playbook-detail'),
url(r'^plays/$', views.PlayList.as_view(), name='play-list'),
url(r'^plays/(?P<pk>[0-9]+)/$', views.PlayDetail.as_view(), name='play-detail'),
]
urlpatterns = format_suffix_patterns(urlpatterns)

View File

@ -14,47 +14,38 @@
#
# You should have received a copy of the GNU General Public License
# along with ARA. If not, see <http://www.gnu.org/licenses/>.
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from api import models, serializers
from rest_framework import viewsets
from rest_framework import generics
class PlaybookViewSet(viewsets.ModelViewSet):
@api_view(['GET'])
def api_root(request, format=None):
return Response({
'playbooks': reverse('playbook-list', request=request, format=format),
'plays': reverse('play-list', request=request, format=format)
})
class PlaybookList(generics.ListCreateAPIView):
queryset = models.Playbook.objects.all()
serializer_class = serializers.PlaybookSerializer
class PlayViewSet(viewsets.ModelViewSet):
class PlaybookDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = models.Playbook.objects.all()
serializer_class = serializers.PlaybookSerializer
class PlayList(generics.ListCreateAPIView):
queryset = models.Play.objects.all()
serializer_class = serializers.PlaySerializer
class TaskViewSet(viewsets.ModelViewSet):
queryset = models.Task.objects.all()
serializer_class = serializers.TaskSerializer
class HostViewSet(viewsets.ModelViewSet):
queryset = models.Host.objects.all()
serializer_class = serializers.HostSerializer
class ResultViewSet(viewsets.ModelViewSet):
queryset = models.Result.objects.all()
serializer_class = serializers.ResultSerializer
class RecordViewSet(viewsets.ModelViewSet):
queryset = models.Record.objects.all()
serializer_class = serializers.RecordSerializer
# class FileContentViewSet(viewsets.ModelViewSet):
# queryset = models.FileContent.objects.all()
# serializer_class = serializers.FileContentSerializer
class FileViewSet(viewsets.ModelViewSet):
queryset = models.File.objects.all()
serializer_class = serializers.FileSerializer
class PlayDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = models.Play.objects.all()
serializer_class = serializers.PlaySerializer

View File

@ -7,7 +7,7 @@ admin.site.site_header = 'Administration'
admin.site.index_title = 'Administration Ara'
routes = [
url(r'^api/', include('api.urls')),
url(r'^api/v1/', include('api.urls')),
url(r'^admin/', admin.site.urls),
]
urlpatterns = routes + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)