Merge branch 'master' of github.com:open-cloud/xos
diff --git a/xos/core/admin.py b/xos/core/admin.py
index b33b115..b3cee88 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -728,9 +728,9 @@
     suit_classes = 'suit-tab suit-tab-serviceattrs'
 
 class ServiceAdmin(XOSBaseAdmin):
-    list_display = ("backend_status_icon","name","description","versionNumber","enabled","published")
+    list_display = ("backend_status_icon","name","kind","versionNumber","enabled","published")
     list_display_links = ('backend_status_icon', 'name', )
-    fieldList = ["backend_status_text","name","description","versionNumber","enabled","published","view_url","icon_url"]
+    fieldList = ["backend_status_text","name","kind","description","versionNumber","enabled","published","view_url","icon_url"]
     fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-general']})]
     inlines = [ServiceAttrAsTabInline,SliceInline]
     readonly_fields = ('backend_status_text', )
diff --git a/xos/core/models/service.py b/xos/core/models/service.py
index 10f3dd9..c6e0061 100644
--- a/xos/core/models/service.py
+++ b/xos/core/models/service.py
@@ -1,17 +1,30 @@
 from django.db import models
-from core.models import PlCoreBase,SingletonModel
+from core.models import PlCoreBase,SingletonModel,PlCoreBaseManager
 from core.models.plcorebase import StrippedCharField
 import json
 
 class Service(PlCoreBase):
+    # when subclassing a service, redefine KIND to describe the new service
+    KIND = "generic"
+
     description = models.TextField(max_length=254,null=True, blank=True,help_text="Description of Service")
     enabled = models.BooleanField(default=True)
+    kind = StrippedCharField(max_length=30, help_text="Kind of service", default=KIND)
     name = StrippedCharField(max_length=30, help_text="Service Name")
     versionNumber = StrippedCharField(max_length=30, help_text="Version of Service Definition")
     published = models.BooleanField(default=True)
     view_url = StrippedCharField(blank=True, null=True, max_length=1024)
     icon_url = StrippedCharField(blank=True, null=True, max_length=1024)
 
+    def __init__(self, *args, **kwargs):
+        # for subclasses, set the default kind appropriately
+        self._meta.get_field("kind").default = self.KIND
+        super(Service, self).__init__(*args, **kwargs)
+
+    @classmethod
+    def get_service_objects(cls):
+        return cls.objects.filter(kind = cls.KIND)
+
     def __unicode__(self): return u'%s' % (self.name)
 
 class ServiceAttribute(PlCoreBase):
@@ -27,7 +40,11 @@
 
         The provider is always a Service.
     """
-    kind = StrippedCharField(max_length=30)
+
+    # when subclassing a service, redefine KIND to describe the new service
+    KIND = "generic"
+
+    kind = StrippedCharField(max_length=30, default=KIND)
     provider_service = models.ForeignKey(Service, related_name='tenants')
     subscriber_service = models.ForeignKey(Service, related_name='subscriptions', blank=True, null=True)
     subscriber_tenant = models.ForeignKey("Tenant", related_name='subscriptions', blank=True, null=True)
@@ -35,11 +52,18 @@
     service_specific_id = StrippedCharField(max_length=30)
     service_specific_attribute = models.TextField()
 
+    def __init__(self, *args, **kwargs):
+        # for subclasses, set the default kind appropriately
+        self._meta.get_field("kind").default = self.KIND
+        super(Tenant, self).__init__(*args, **kwargs)
+
     def __unicode__(self):
         if self.subscriber_service:
-            return u'%s tenant %s on %s' % (str(self.kind), str(self.subscriber_service), str(self.provider_service))
+            return u'%s service %s on service %s' % (str(self.kind), str(self.subscriber_service.id), str(self.provider_service.id))
+        elif self.subscriber_tenant:
+            return u'%s tenant %s on service %s' % (str(self.kind), str(self.subscriber_tenant.id), str(self.provider_service.id))
         else:
-            return u'%s tenant %s on %s' % (str(self.kind), str(self.subscriber_tenant), str(self.provider_service))
+            return u'%s on service %s' % (str(self.kind), str(self.provider_service.id))
 
     # helper for extracting things from a json-encoded service_specific_attribute
     def get_attribute(self, name, default=None):
@@ -57,4 +81,8 @@
         attributes[name]=value
         self.service_specific_attribute = json.dumps(attributes)
 
+    @classmethod
+    def get_tenant_objects(cls):
+        return cls.objects.filter(kind = cls.KIND)
+