Added in Project support to be used in concert with Tags on Slice, Site, Sliver and User.
diff --git a/planetstack/core/admin.py b/planetstack/core/admin.py
index d947c6e..76810f6 100644
--- a/planetstack/core/admin.py
+++ b/planetstack/core/admin.py
@@ -15,7 +15,10 @@
 
 import django_evolution 
 
-class ReadonlyTabularInline(admin.TabularInline):
+class PlStackTabularInline(admin.TabularInline):
+    exclude = ['enacted']
+
+class ReadonlyTabularInline(PlStackTabularInline):
     can_delete = False
     extra = 0
     editable_fields = []
@@ -36,36 +39,35 @@
     exclude = ['enacted']
     extra = 1
 
-class SliverInline(admin.TabularInline):
+class SliverInline(PlStackTabularInline):
     model = Sliver
     fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
     extra = 0
     #readonly_fields = ['ip', 'instance_name', 'image']
     readonly_fields = ['ip', 'instance_name']
     
-
-class SiteInline(admin.TabularInline):
+class SiteInline(PlStackTabularInline):
     model = Site
     extra = 0
 
-class UserInline(admin.TabularInline):
+class UserInline(PlStackTabularInline):
     model = User
     fields = ['email', 'firstname', 'lastname']
     extra = 0
 
-class SliceInline(admin.TabularInline):
+class SliceInline(PlStackTabularInline):
     model = Slice
     extra = 0
 
-class RoleInline(admin.TabularInline):
+class RoleInline(PlStackTabularInline):
     model = Role
     extra = 0 
 
-class NodeInline(admin.TabularInline):
+class NodeInline(PlStackTabularInline):
     model = Node
     extra = 0
 
-class SitePrivilegeInline(admin.TabularInline):
+class SitePrivilegeInline(PlStackTabularInline):
     model = SitePrivilege
     extra = 0
 
@@ -91,7 +93,7 @@
                 kwargs['queryset'] = users
         return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
-class SliceMembershipInline(admin.TabularInline):
+class SliceMembershipInline(PlStackTabularInline):
     model = SliceMembership
     extra = 0
     fields = ('user', 'role')
@@ -118,7 +120,7 @@
 
         return super(SliceMembershipInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
-class SliceTagInline(admin.TabularInline):
+class SliceTagInline(PlStackTabularInline):
     model = SliceTag
     extra = 0
 
@@ -132,6 +134,7 @@
 
 class PlanetStackBaseAdmin(admin.ModelAdmin):
     save_on_top = False
+    exclude = ['enacted']
 
 class RoleAdmin(PlanetStackBaseAdmin):
     fieldsets = [
@@ -139,7 +142,6 @@
     ]
     list_display = ('role_type',)
 
-
 class DeploymentAdminForm(forms.ModelForm):
     sites = forms.ModelMultipleChoiceField(
         queryset=Site.objects.all(),
@@ -370,7 +372,6 @@
         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
         obj.delete()
 
-
 class ImageAdmin(admin.ModelAdmin):
     fields = ['image_id', 'name', 'disk_format', 'container_format']
 
@@ -379,7 +380,6 @@
     list_filter = ('deployment',)
     inlines = [TagInline]
 
-
 class SliverForm(forms.ModelForm):
     class Meta:
         model = Sliver
@@ -390,6 +390,12 @@
             'instance_name': PlainTextWidget(),
         }
 
+class ProjectAdmin(admin.ModelAdmin):
+    exclude = ['enacted']
+
+class TagAdmin(admin.ModelAdmin):
+    exclude = ['enacted']
+
 class SliverAdmin(PlanetStackBaseAdmin):
     form = SliverForm
     fieldsets = [
@@ -480,7 +486,6 @@
             user.save()
         return user
 
-
 class UserChangeForm(forms.ModelForm):
     """A form for updating users. Includes all the fields on
     the user, but replaces the password field with admin's
@@ -497,7 +502,6 @@
         # field does not have access to the initial value
         return self.initial["password"]
 
-
 class UserAdmin(UserAdmin):
     class Meta:
         app_label = "core"
@@ -645,25 +649,25 @@
         return super(ReservationAdmin, self).changelist_view(request, extra_context)
 
     def get_form(self, request, obj=None, **kwargs):
-        request._obj_ = obj

-        if obj is not None:

-            # For changes, set request._slice to the slice already set in the

-            # object.

-            request._slice = obj.slice

-            self.form = ReservationChangeForm

-        else:

-            if getattr(request, "_refresh", False):

-                self.form = ReservationAddRefreshForm

-            else:

-                self.form = ReservationAddForm

-        return super(ReservationAdmin, self).get_form(request, obj, **kwargs)

-

+        request._obj_ = obj
+        if obj is not None:
+            # For changes, set request._slice to the slice already set in the
+            # object.
+            request._slice = obj.slice
+            self.form = ReservationChangeForm
+        else:
+            if getattr(request, "_refresh", False):
+                self.form = ReservationAddRefreshForm
+            else:
+                self.form = ReservationAddForm
+        return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
+
     def get_readonly_fields(self, request, obj=None):
-        if (obj is not None):

-            # Prevent slice from being changed after the reservation has been

-            # created.

-            return ['slice']

-        else:

+        if (obj is not None):
+            # Prevent slice from being changed after the reservation has been
+            # created.
+            return ['slice']
+        else:
             return []
 
 # register a signal that caches the user's credentials when they log in
@@ -692,9 +696,10 @@
 admin.site.register(Deployment, DeploymentAdmin)
 admin.site.register(Site, SiteAdmin)
 admin.site.register(Slice, SliceAdmin)
+admin.site.register(Project, ProjectAdmin)
 
 if showAll:
-    admin.site.register(Tag)
+    admin.site.register(Tag, TagAdmin)
     admin.site.register(Node, NodeAdmin)
     admin.site.register(SliceMembership, SliceMembershipAdmin)
     admin.site.register(SitePrivilege, SitePrivilegeAdmin)