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)
diff --git a/planetstack/core/models/__init__.py b/planetstack/core/models/__init__.py
index 4e6cc83..2280822 100644
--- a/planetstack/core/models/__init__.py
+++ b/planetstack/core/models/__init__.py
@@ -1,5 +1,6 @@
 from .plcorebase import PlCoreBase
 from .deployment import Deployment
+from .project import Project
 from .tag import Tag
 from .site import Site
 from .site import SitePrivilege
diff --git a/planetstack/core/models/project.py b/planetstack/core/models/project.py
new file mode 100644
index 0000000..9f1a863
--- /dev/null
+++ b/planetstack/core/models/project.py
@@ -0,0 +1,11 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+
+# Create your models here.
+
+class Project(PlCoreBase):
+    name = models.CharField(max_length=200, unique=True, help_text="Name of Project")
+
+    def __unicode__(self):  return u'%s' % (self.name)
+
diff --git a/planetstack/core/models/tag.py b/planetstack/core/models/tag.py
index 786b036..7c957a1 100644
--- a/planetstack/core/models/tag.py
+++ b/planetstack/core/models/tag.py
@@ -1,6 +1,7 @@
 import os
 from django.db import models
 from core.models import PlCoreBase
+from core.models import Project
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes import generic
 
@@ -8,6 +9,8 @@
 
 class Tag(PlCoreBase):
 
+    project = models.ForeignKey(Project, related_name='tags', help_text="The Project this Tag is associated with")
+
     name = models.SlugField(help_text="The name of this tag", max_length=128)
     value = models.CharField(help_text="The value of this tag", max_length=1024)