From 0479c172561089c1b00b8fd8ac4eea64e14a3e4a Mon Sep 17 00:00:00 2001 From: Akita Noek Date: Thu, 31 Mar 2016 10:21:02 -0400 Subject: [PATCH 1/3] Made reverse_gfk implementation suck a whole lot less #1342 --- awx/api/serializers.py | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 1aa0f88572..7dbde98b5a 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -38,7 +38,7 @@ from polymorphic import PolymorphicModel from awx.main.constants import SCHEDULEABLE_PROVIDERS from awx.main.models import * # noqa from awx.main.fields import ImplicitRoleField -from awx.main.utils import get_type_for_model, get_model_for_type, build_url, timestamp_apiformat +from awx.main.utils import get_type_for_model, get_model_for_type, build_url, timestamp_apiformat, camelcase_to_underscore from awx.main.redact import REPLACE_STR from awx.main.conf import tower_settings @@ -92,7 +92,7 @@ SUMMARIZABLE_FK_FIELDS = { } -def reverseGenericForeignKey(content_object): +def reverse_gfk(content_object): ''' Computes a reverse for a GenericForeignKey field. @@ -101,34 +101,11 @@ def reverseGenericForeignKey(content_object): for example { 'organization': '/api/v1/organizations/1/' } ''' - ret = {} - if type(content_object) is Organization: - ret['organization'] = reverse('api:organization_detail', args=(content_object.pk,)) - if type(content_object) is User: - ret['user'] = reverse('api:user_detail', args=(content_object.pk,)) - if type(content_object) is Team: - ret['team'] = reverse('api:team_detail', args=(content_object.pk,)) - if type(content_object) is Project: - ret['project'] = reverse('api:project_detail', args=(content_object.pk,)) - if type(content_object) is Inventory: - ret['inventory'] = reverse('api:inventory_detail', args=(content_object.pk,)) - if type(content_object) is Host: - ret['host'] = reverse('api:host_detail', args=(content_object.pk,)) - if type(content_object) is Group: - ret['group'] = reverse('api:group_detail', args=(content_object.pk,)) - if type(content_object) is InventorySource: - ret['inventory_source'] = reverse('api:inventory_source_detail', args=(content_object.pk,)) - if type(content_object) is Credential: - ret['credential'] = reverse('api:credential_detail', args=(content_object.pk,)) - if type(content_object) is JobTemplate: - ret['job_template'] = reverse('api:job_template_detail', args=(content_object.pk,)) - if type(content_object) is Role: - ret['role'] = reverse('api:role_detail', args=(content_object.pk,)) - if type(content_object) is Job: - ret['job'] = reverse('api:job_detail', args=(content_object.pk,)) - if type(content_object) is JobEvent: - ret['job_event'] = reverse('api:job_event_detail', args=(content_object.pk,)) + try: + ret[camelcase_to_underscore(content_object.__class__.__name__)] = content_object.get_absolute_url() + except AttributeError: + pass return ret @@ -1498,7 +1475,7 @@ class RoleSerializer(BaseSerializer): ret['teams'] = reverse('api:role_teams_list', args=(obj.pk,)) try: if obj.content_object: - ret.update(reverseGenericForeignKey(obj.content_object)) + ret.update(reverse_gfk(obj.content_object)) except AttributeError: # AttributeError's happen if our content_object is pointing at # a model that no longer exists. This is dirty data and ideally @@ -1524,7 +1501,7 @@ class ResourceAccessListElementSerializer(UserSerializer): try: role_dict['resource_name'] = role.content_object.name role_dict['resource_type'] = role.content_type.name - role_dict['related'] = reverseGenericForeignKey(role.content_object) + role_dict['related'] = reverse_gfk(role.content_object) except: pass From ab034411336258b4e5ab849a3c9a8837c65fe3be Mon Sep 17 00:00:00 2001 From: Akita Noek Date: Thu, 31 Mar 2016 10:31:37 -0400 Subject: [PATCH 2/3] Let exceptions better bubble up through reverse_gfk --- awx/api/serializers.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 7dbde98b5a..46e27a2ccc 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -101,12 +101,12 @@ def reverse_gfk(content_object): for example { 'organization': '/api/v1/organizations/1/' } ''' - ret = {} - try: - ret[camelcase_to_underscore(content_object.__class__.__name__)] = content_object.get_absolute_url() - except AttributeError: - pass - return ret + if content_object is None or not hasattr(content_object, 'get_absolute_url'): + return {} + + return { + camelcase_to_underscore(content_object.__class__.__name__): content_object.get_absolute_url() + } class BaseSerializerMetaclass(serializers.SerializerMetaclass): From 0101d538764a58a4e24445d6c404b94dbeccb53b Mon Sep 17 00:00:00 2001 From: Akita Noek Date: Thu, 31 Mar 2016 10:53:27 -0400 Subject: [PATCH 3/3] super(type(obj),self) -> super(Class, self) fixes --- awx/api/views.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/awx/api/views.py b/awx/api/views.py index 971242c47d..0012ba8cc0 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -729,7 +729,7 @@ class OrganizationActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(OrganizationActivityStreamList, self).get(request, *args, **kwargs) class OrganizationNotifiersList(SubListCreateAttachDetachAPIView): @@ -807,7 +807,7 @@ class TeamRolesList(SubListCreateAttachDetachAPIView): if not sub_id: data = dict(msg='Role "id" field is missing') return Response(data, status=status.HTTP_400_BAD_REQUEST) - return super(type(self), self).post(request, *args, **kwargs) + return super(TeamRolesList, self).post(request, *args, **kwargs) class TeamProjectsList(SubListAPIView): @@ -854,7 +854,7 @@ class TeamActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(TeamActivityStreamList, self).get(request, *args, **kwargs) def get_queryset(self): parent = self.get_parent_object() @@ -949,7 +949,7 @@ class ProjectActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(ProjectActivityStreamList, self).get(request, *args, **kwargs) def get_queryset(self): parent = self.get_parent_object() @@ -1166,7 +1166,7 @@ class UserActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(UserActivityStreamList, self).get(request, *args, **kwargs) def get_queryset(self): parent = self.get_parent_object() @@ -1236,7 +1236,7 @@ class CredentialActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(CredentialActivityStreamList, self).get(request, *args, **kwargs) class CredentialAccessList(ResourceAccessList): @@ -1300,7 +1300,7 @@ class InventoryActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(InventoryActivityStreamList, self).get(request, *args, **kwargs) def get_queryset(self): parent = self.get_parent_object() @@ -1420,7 +1420,7 @@ class HostActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(HostActivityStreamList, self).get(request, *args, **kwargs) def get_queryset(self): parent = self.get_parent_object() @@ -1623,7 +1623,7 @@ class GroupActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(GroupActivityStreamList, self).get(request, *args, **kwargs) def get_queryset(self): parent = self.get_parent_object() @@ -1874,7 +1874,7 @@ class InventorySourceActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(InventorySourceActivityStreamList, self).get(request, *args, **kwargs) class InventorySourceNotifiersAnyList(SubListCreateAttachDetachAPIView): @@ -2138,7 +2138,7 @@ class JobTemplateActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(JobTemplateActivityStreamList, self).get(request, *args, **kwargs) class JobTemplateNotifiersAnyList(SubListCreateAttachDetachAPIView): @@ -2457,7 +2457,7 @@ class JobActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(JobActivityStreamList, self).get(request, *args, **kwargs) class JobStart(GenericAPIView): @@ -3071,7 +3071,7 @@ class AdHocCommandActivityStreamList(SubListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(AdHocCommandActivityStreamList, self).get(request, *args, **kwargs) class SystemJobList(ListCreateAPIView): @@ -3282,7 +3282,7 @@ class ActivityStreamList(SimpleListAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(ActivityStreamList, self).get(request, *args, **kwargs) class ActivityStreamDetail(RetrieveAPIView): @@ -3299,7 +3299,7 @@ class ActivityStreamDetail(RetrieveAPIView): 'the activity stream.') # Okay, let it through. - return super(type(self), self).get(request, *args, **kwargs) + return super(ActivityStreamDetail, self).get(request, *args, **kwargs) class SettingsList(ListCreateAPIView): @@ -3407,7 +3407,7 @@ class RoleUsersList(SubListCreateAttachDetachAPIView): if not sub_id: data = dict(msg='Role "id" field is missing') return Response(data, status=status.HTTP_400_BAD_REQUEST) - return super(type(self), self).post(request, *args, **kwargs) + return super(RoleUsersList, self).post(request, *args, **kwargs) class RoleTeamsList(ListAPIView):