From fe5d154d761cdd58a7d4c8e2c6e591318f53b687 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Sat, 29 Mar 2014 14:34:18 -0400 Subject: [PATCH] AC-1040 Exposed list of choices for type field. --- awx/api/filters.py | 6 +++--- awx/api/generics.py | 8 ++++++++ awx/api/serializers.py | 5 ++--- awx/main/utils.py | 25 ++++++++++++++++++++++++- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/awx/api/filters.py b/awx/api/filters.py index 358bb62c67..72cc63448b 100644 --- a/awx/api/filters.py +++ b/awx/api/filters.py @@ -17,7 +17,7 @@ from rest_framework.exceptions import ParseError from rest_framework.filters import BaseFilterBackend # Ansible Tower -from awx.main.utils import camelcase_to_underscore +from awx.main.utils import get_type_for_model class ActiveOnlyBackend(BaseFilterBackend): ''' @@ -52,10 +52,10 @@ class TypeFilterBackend(BaseFilterBackend): ct_model = ct.model_class() if not ct_model: continue - ct_type = camelcase_to_underscore(ct_model._meta.object_name) + ct_type = get_type_for_model(ct_model) types_map[ct_type] = ct.pk model = queryset.model - model_type = camelcase_to_underscore(model._meta.object_name) + model_type = get_type_for_model(model) if 'polymorphic_ctype' in model._meta.get_all_field_names(): types_pks = set([v for k,v in types_map.items() if k in types]) queryset = queryset.filter(polymorphic_ctype_id__in=types_pks) diff --git a/awx/api/generics.py b/awx/api/generics.py index 2ce3c3ab83..b9639215fb 100644 --- a/awx/api/generics.py +++ b/awx/api/generics.py @@ -197,6 +197,14 @@ class GenericAPIView(generics.GenericAPIView, APIView): # appropriate metadata about the fields that should be supplied. serializer = self.get_serializer() actions['GET'] = serializer.metadata() + # Inject the type field choices into GET options as well as on + # the metadata itself. + if 'type' in actions['GET']: + actions['GET']['type']['type'] = 'multiple choice' + actions['GET']['type']['choices'] = [ + (x, unicode(get_model_for_type(x)._meta.verbose_name)) + for x in serializer.get_types() + ] ret['types'] = serializer.get_types() if actions: ret['actions'] = actions diff --git a/awx/api/serializers.py b/awx/api/serializers.py index d13827ac37..cc84667a18 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -30,7 +30,7 @@ from rest_framework import serializers # AWX from awx.main.models import * -from awx.main.utils import update_scm_url, camelcase_to_underscore +from awx.main.utils import update_scm_url, get_type_for_model logger = logging.getLogger('awx.api.serializers') @@ -214,8 +214,7 @@ class BaseSerializer(serializers.ModelSerializer): return ret def get_type(self, obj): - opts = get_concrete_model(self.opts.model)._meta - return camelcase_to_underscore(opts.object_name) + return get_type_for_model(self.opts.model) def get_types(self): return [self.get_type(None)] diff --git a/awx/main/utils.py b/awx/main/utils.py index 8285bacdb2..c3b69749bf 100644 --- a/awx/main/utils.py +++ b/awx/main/utils.py @@ -17,7 +17,8 @@ from rest_framework.exceptions import ParseError, PermissionDenied from Crypto.Cipher import AES __all__ = ['get_object_or_400', 'get_object_or_403', 'camelcase_to_underscore', - 'get_ansible_version', 'get_awx_version', 'update_scm_url'] + 'get_ansible_version', 'get_awx_version', 'update_scm_url', + 'get_type_for_model', 'get_model_for_type'] def get_object_or_400(klass, *args, **kwargs): ''' @@ -301,6 +302,28 @@ def model_to_dict(obj, serializer_mapping=None): attr_d[field.name] = "hidden" return attr_d +def get_type_for_model(model): + ''' + Return type name for a given model class. + ''' + from rest_framework.compat import get_concrete_model + opts = get_concrete_model(model)._meta + return camelcase_to_underscore(opts.object_name) + +def get_model_for_type(type): + ''' + Return model class for a given type name. + ''' + from django.db.models import Q + from django.contrib.contenttypes.models import ContentType + for ct in ContentType.objects.filter(Q(app_label='main') | Q(app_label='auth', model='user')): + ct_model = ct.model_class() + if not ct_model: + continue + ct_type = get_type_for_model(ct_model) + if type == ct_type: + return ct_model + def get_system_task_capacity(): from django.conf import settings if hasattr(settings, 'SYSTEM_TASK_CAPACITY'):