From patchwork Sat Nov 19 16:51:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Finucane X-Patchwork-Id: 696858 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tLgs94t94z9t1T for ; Sun, 20 Nov 2016 03:52:45 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=that.guru header.i=@that.guru header.b="lvX31cLW"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3tLgs92xlMzDvk0 for ; Sun, 20 Nov 2016 03:52:45 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=that.guru header.i=@that.guru header.b="lvX31cLW"; dkim-atps=neutral X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Received: from butterfly.birch.relay.mailchannels.net (butterfly.birch.relay.mailchannels.net [23.83.209.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3tLgrp2CYMzDvjt for ; Sun, 20 Nov 2016 03:52:25 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=that.guru header.i=@that.guru header.b="lvX31cLW"; dkim-atps=neutral X-Sender-Id: mxroute|x-authuser|stephen@that.guru Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 1136B1BC051; Sat, 19 Nov 2016 16:52:21 +0000 (UTC) Received: from one.mxroute.com (ip-10-229-2-62.us-west-2.compute.internal [10.229.2.62]) by relay.mailchannels.net (Postfix) with ESMTPA id 2EC6C1BCE91; Sat, 19 Nov 2016 16:52:20 +0000 (UTC) X-Sender-Id: mxroute|x-authuser|stephen@that.guru Received: from one.mxroute.com ([UNAVAILABLE]. [10.16.27.41]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.7.8); Sat, 19 Nov 2016 16:52:21 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: mxroute|x-authuser|stephen@that.guru X-MailChannels-Auth-Id: mxroute X-MC-Loop-Signature: 1479574340519:4074543065 X-MC-Ingress-Time: 1479574340519 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=that.guru; s=default; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=RuuQvtH/oUTIi9qnckNQpNc97X/kziH4es9oJ8l7heo=; b=lvX31cLWEtb+lmY7rHe6HIcMMn m+r5Y8s1DiVBKRcxQWAFhDLpSWOstxd8z38IVYYOvrOk3T/5nz13xC7zN2LU35F56zw9gljIuWbO4 06qSZtYDIYqueJHSX6rc/sLgMXeUKXEHhJJgIjgMjxGL/jRAefyI3qKQ0pghjwLdfmVyX86ap1KH5 LyiDogiEtu3EfEY78sK+2CtuVUGPe2f981BzR1JElHjDu7VJTsAxHFTINe3hIC9LyhJ2hICyua7B2 PoJrQY3MT8/zy4GsGV7wOPCcSZqiEX6vXT/ha1g/uMW/WbVryuQLrtUpNFaJOCz3i39fXesRiFN7B FZc/VNyg==; From: Stephen Finucane To: patchwork@lists.ozlabs.org Subject: [PATCH v2 02/13] REST: Remove '_url' suffixes Date: Sat, 19 Nov 2016 16:51:17 +0000 Message-Id: <1479574288-24171-3-git-send-email-stephen@that.guru> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1479574288-24171-1-git-send-email-stephen@that.guru> References: <1479574288-24171-1-git-send-email-stephen@that.guru> X-OutGoing-Spam-Status: No, score=-10.0 X-AuthUser: stephen@that.guru X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" This was a design decision made when implementing the REST API. The idea was that these items were URLs to related objects and should be indicated as such. However, this was a faulty assumption as the Patchwork API, unlike other some other APIs (GitHub), does not also include a full representation of said objects, like so: { "url": "http://localhost:8000/api/1.0/patches/1/", ... "delegate_url": "http://localhost:8000/api/1.0/users/1", "delegate": { "url": "http://localhost:8000/api/1.0/users/1/", "username": "admin", "first_name": "", "last_name": "", "email": "" } } Since there is no intention to support this design yet, there isn't really any reason to fight django-rest-framework in appending these suffixes. Simply remove them. Note that the API version if not bumped as the API is still considered unreleased. Signed-off-by: Stephen Finucane Cc: Andy Doan Reviewed-by: Andy Doan --- patchwork/api/__init__.py | 13 ------------- patchwork/api/check.py | 1 - patchwork/api/patch.py | 10 +++++----- patchwork/api/person.py | 5 +++-- patchwork/tests/test_rest_api.py | 10 +++++----- 5 files changed, 13 insertions(+), 26 deletions(-) diff --git a/patchwork/api/__init__.py b/patchwork/api/__init__.py index dc88a85..e91a282 100644 --- a/patchwork/api/__init__.py +++ b/patchwork/api/__init__.py @@ -22,22 +22,9 @@ from django.conf import settings from rest_framework import permissions from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response -from rest_framework.serializers import HyperlinkedModelSerializer -from rest_framework.serializers import HyperlinkedRelatedField from rest_framework.viewsets import ModelViewSet -class URLSerializer(HyperlinkedModelSerializer): - """Just like parent but puts _url for fields""" - - def to_representation(self, instance): - data = super(URLSerializer, self).to_representation(instance) - for name, field in self.fields.items(): - if isinstance(field, HyperlinkedRelatedField) and name != 'url': - data[name + '_url'] = data.pop(name) - return data - - class LinkHeaderPagination(PageNumberPagination): """Provide pagination based on rfc5988. diff --git a/patchwork/api/check.py b/patchwork/api/check.py index 12706be..e88c62e 100644 --- a/patchwork/api/check.py +++ b/patchwork/api/check.py @@ -58,7 +58,6 @@ class CheckSerializer(ModelSerializer): url = self.context['request'].build_absolute_uri(reverse( 'api_1.0:patch-detail', args=[instance.patch.id])) data['url'] = url + 'checks/%s/' % instance.id - data['users_url'] = data.pop('user') return data class Meta: diff --git a/patchwork/api/patch.py b/patchwork/api/patch.py index e8b1903..eea787d 100644 --- a/patchwork/api/patch.py +++ b/patchwork/api/patch.py @@ -19,12 +19,12 @@ import email.parser +from rest_framework.serializers import HyperlinkedModelSerializer from rest_framework.serializers import ListSerializer from rest_framework.serializers import SerializerMethodField from patchwork.api import PatchworkPermission from patchwork.api import PatchworkViewSet -from patchwork.api import URLSerializer from patchwork.models import Patch @@ -37,8 +37,8 @@ class PatchListSerializer(ListSerializer): return super(PatchListSerializer, self).to_representation(data) -class PatchSerializer(URLSerializer): - mbox_url = SerializerMethodField() +class PatchSerializer(HyperlinkedModelSerializer): + mbox = SerializerMethodField() state = SerializerMethodField() class Meta: @@ -53,13 +53,13 @@ class PatchSerializer(URLSerializer): def get_state(self, obj): return obj.state.name - def get_mbox_url(self, patch): + def get_mbox(self, patch): request = self.context.get('request', None) return request.build_absolute_uri(patch.get_mbox_url()) def to_representation(self, instance): data = super(PatchSerializer, self).to_representation(instance) - data['checks_url'] = data['url'] + 'checks/' + data['checks'] = data['url'] + 'checks/' data['check'] = instance.combined_check_state headers = data.get('headers') if headers is not None: diff --git a/patchwork/api/person.py b/patchwork/api/person.py index 9a97dbb..9fda027 100644 --- a/patchwork/api/person.py +++ b/patchwork/api/person.py @@ -17,13 +17,14 @@ # along with Patchwork; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +from rest_framework.serializers import HyperlinkedModelSerializer + from patchwork.api import AuthenticatedReadOnly from patchwork.api import PatchworkViewSet -from patchwork.api import URLSerializer from patchwork.models import Person -class PersonSerializer(URLSerializer): +class PersonSerializer(HyperlinkedModelSerializer): class Meta: model = Person fields = ('email', 'name', 'user') diff --git a/patchwork/tests/test_rest_api.py b/patchwork/tests/test_rest_api.py index 44a2859..3be8ecf 100644 --- a/patchwork/tests/test_rest_api.py +++ b/patchwork/tests/test_rest_api.py @@ -175,7 +175,7 @@ class TestPersonAPI(APITestCase): self.assertEqual(1, len(resp.data)) self.assertEqual(user.username, resp.data[0]['name']) self.assertEqual(user.email, resp.data[0]['email']) - self.assertIn('users/%d/' % user.id, resp.data[0]['user_url']) + self.assertIn('users/%d/' % user.id, resp.data[0]['user']) def test_unlinked_user(self): person = create_person() @@ -187,7 +187,7 @@ class TestPersonAPI(APITestCase): self.assertEqual(2, len(resp.data)) self.assertEqual(person.name, resp.data[0]['name']) - self.assertIsNone(resp.data[0]['user_url']) + self.assertIsNone(resp.data[0]['user']) def test_readonly(self): user = create_maintainer() @@ -291,13 +291,13 @@ class TestPatchAPI(APITestCase): self.assertEqual(status.HTTP_200_OK, resp.status_code) self.assertEqual(patch.name, resp.data['name']) self.assertIn(TestProjectAPI.api_url(patch.project.id), - resp.data['project_url']) + resp.data['project']) self.assertEqual(patch.msgid, resp.data['msgid']) self.assertEqual(patch.diff, resp.data['diff']) self.assertIn(TestPersonAPI.api_url(patch.submitter.id), - resp.data['submitter_url']) + resp.data['submitter']) self.assertEqual(patch.state.name, resp.data['state']) - self.assertIn(patch.get_mbox_url(), resp.data['mbox_url']) + self.assertIn(patch.get_mbox_url(), resp.data['mbox']) def test_detail_tags(self): patch = create_patch(