This is an automated email from the ASF dual-hosted git repository. gjm pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/bloodhound-core.git
commit ac3d18794ac0566a8f28f2fb19bac0843d3c8c29 Author: Gary Martin <g...@apache.org> AuthorDate: Tue Feb 19 13:29:30 2019 +0000 Refactor api * move api under its own path * add urls to model views to help with api navigation * add user and group to api * experiment with change events as a subpath of tickets git-svn-id: https://svn.apache.org/repos/asf/bloodhound/branches/bh_core_experimental@1853879 13f79535-47bb-0310-9956-ffa450edef68 --- bh_core/settings.py | 6 ++++++ trackers/models.py | 16 +++++++++++++--- trackers/serializers.py | 31 +++++++++++++++++++++++++++++++ trackers/urls.py | 17 +++++++++++++---- trackers/views.py | 28 +++++++++++++++------------- 5 files changed, 78 insertions(+), 20 deletions(-) diff --git a/bh_core/settings.py b/bh_core/settings.py index 1cf7328..67148b7 100644 --- a/bh_core/settings.py +++ b/bh_core/settings.py @@ -142,3 +142,9 @@ USE_TZ = True # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' + +REST_FRAMEWORK = { + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', + ] +} diff --git a/trackers/models.py b/trackers/models.py index 6ddd882..7baab71 100644 --- a/trackers/models.py +++ b/trackers/models.py @@ -35,11 +35,12 @@ class ModelCommon(models.Model): class Ticket(ModelCommon): - title = models.CharField(max_length=200, null=True) - description = models.TextField(null=True) def api_url(self): - return reverse('ticket_view', args=(self.id,)) + return reverse('ticket-detail', args=(self.id,)) + + def api_events_url(self): + return reverse('changeevent-list', args=(self.id,)) def last_update(self): last_event = self.changeevent_set.order_by('created').last() @@ -67,6 +68,9 @@ class Ticket(ModelCommon): class TicketField(ModelCommon): name = models.CharField(max_length=32) + def api_url(self): + return reverse('ticketfield-detail', args=(self.id,)) + class ChangeEvent(ModelCommon): ticket = models.ForeignKey(Ticket, models.CASCADE, null=False) @@ -81,3 +85,9 @@ class ChangeEvent(ModelCommon): def __str__(self): return "Change to: {}; Field: {}; Diff: {}".format( self.ticket, self.field, self.diff) + + def api_url(self): + return reverse('changeevent-detail', args=(self.ticket.id, self.id,)) + + def api_ticket_url(self): + return reverse('ticket-detail', args=(self.ticket.id,)) diff --git a/trackers/serializers.py b/trackers/serializers.py index b38dcdb..2616ff1 100644 --- a/trackers/serializers.py +++ b/trackers/serializers.py @@ -1,9 +1,23 @@ +from django.contrib.auth.models import User, Group from rest_framework import serializers from trackers import models +class UserSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = User + fields = ('url', 'username', 'email', 'is_staff') + + +class GroupSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Group + fields = ('url', 'name') + + class TicketSerializer(serializers.ModelSerializer): api_url = serializers.SerializerMethodField() + api_events_url = serializers.SerializerMethodField() class Meta: model = models.Ticket @@ -12,14 +26,31 @@ class TicketSerializer(serializers.ModelSerializer): def get_api_url(self, obj): return self.context['request'].build_absolute_uri(obj.api_url()) + def get_api_events_url(self, obj): + return self.context['request'].build_absolute_uri(obj.api_events_url()) + class TicketFieldSerializer(serializers.ModelSerializer): + api_url = serializers.SerializerMethodField() + class Meta: model = models.TicketField fields = '__all__' + def get_api_url(self, obj): + return self.context['request'].build_absolute_uri(obj.api_url()) + class ChangeEventSerializer(serializers.ModelSerializer): + api_url = serializers.SerializerMethodField() + api_ticket_url = serializers.SerializerMethodField() + class Meta: model = models.ChangeEvent fields = '__all__' + + def get_api_url(self, obj): + return self.context['request'].build_absolute_uri(obj.api_url()) + + def get_api_ticket_url(self, obj): + return self.context['request'].build_absolute_uri(obj.api_ticket_url()) diff --git a/trackers/urls.py b/trackers/urls.py index d211bb4..bebc31c 100644 --- a/trackers/urls.py +++ b/trackers/urls.py @@ -16,13 +16,22 @@ # under the License. from django.urls import path +from django.conf.urls import include +from rest_framework import routers from . import views +router = routers.DefaultRouter() +router.register('users', views.UserViewSet) +router.register('groups', views.GroupViewSet) +router.register('tickets', views.TicketViewSet) +router.register('ticketfields', views.TicketFieldViewSet) + +ticket_router = routers.DefaultRouter() +ticket_router.register('ticketevents', views.ChangeEventViewSet) + urlpatterns = [ path('', views.home, name='home'), + path('api/', include(router.urls)), + path('api/tickets/<uuid:id>/', include(ticket_router.urls)), path('schema_view/', views.schema_view), - path('field/', views.TicketFieldListCreate.as_view()), - path('ticket/', views.TicketListCreate.as_view()), - path('ticket/<uuid:id>', views.TicketViewUpdate.as_view(), name='ticket_view'), - path('ticket/<uuid:id>/event/', views.ChangeEventListCreate.as_view()), ] diff --git a/trackers/views.py b/trackers/views.py index 13498ed..03559b8 100644 --- a/trackers/views.py +++ b/trackers/views.py @@ -15,9 +15,9 @@ # specific language governing permissions and limitations # under the License. +from django.contrib.auth.models import User, Group from django.http import HttpResponse -from django.shortcuts import render -from rest_framework import generics +from rest_framework import viewsets from . import serializers from . import models @@ -30,24 +30,26 @@ def home(request): return HttpResponse('<html><title>Bloodhound Trackers</title></html>') -class TicketListCreate(generics.ListCreateAPIView): - queryset = models.Ticket.objects.all() - serializer_class = serializers.TicketSerializer +class UserViewSet(viewsets.ModelViewSet): + queryset = User.objects.all() + serializer_class = serializers.UserSerializer -class TicketViewUpdate(generics.RetrieveUpdateAPIView): - queryset = models.Ticket.objects.all() - serializer_class = serializers.TicketSerializer - lookup_field = 'id' +class GroupViewSet(viewsets.ModelViewSet): + queryset = Group.objects.all() + serializer_class = serializers.GroupSerializer -class TicketFieldListCreate(generics.ListCreateAPIView): +class TicketFieldViewSet(viewsets.ModelViewSet): queryset = models.TicketField.objects.all() serializer_class = serializers.TicketFieldSerializer - lookup_field = 'ticket' -class ChangeEventListCreate(generics.ListCreateAPIView): +class TicketViewSet(viewsets.ModelViewSet): + queryset = models.Ticket.objects.all() + serializer_class = serializers.TicketSerializer + + +class ChangeEventViewSet(viewsets.ModelViewSet): queryset = models.ChangeEvent.objects.all() serializer_class = serializers.ChangeEventSerializer - lookup_field = 'ticket'