[open-ils-commits] r912 - in servres/trunk/conifer: . syrup syrup/migrations templates (gfawcett)

svn at svn.open-ils.org svn at svn.open-ils.org
Wed Jul 14 20:54:43 EDT 2010


Author: gfawcett
Date: 2010-07-14 20:54:42 -0400 (Wed, 14 Jul 2010)
New Revision: 912

Added:
   servres/trunk/conifer/syrup/migrations/0002_auto__add_field_site_term__add_field_site_course__add_unique_site_owne.py
Modified:
   servres/trunk/conifer/grahams-init-fixture.json
   servres/trunk/conifer/syrup/models.py
   servres/trunk/conifer/templates/edit_site.xhtml
Log:
Changed mind: each Site has exactly one Course, one Term, one Owner. Schema change.

This radically simplifies the design. Access control and
personalization can still be addressed through membership Groups.

There can be only one Site with a given (course, term, owner) triple.

Modified: servres/trunk/conifer/grahams-init-fixture.json
===================================================================
--- servres/trunk/conifer/grahams-init-fixture.json	2010-07-15 00:54:27 UTC (rev 911)
+++ servres/trunk/conifer/grahams-init-fixture.json	2010-07-15 00:54:42 UTC (rev 912)
@@ -1 +1 @@
-[{"pk": 1, "model": "syrup.userprofile", "fields": {"last_email_notice": "2010-07-08 22:26:34", "created": "2010-07-08 22:26:34", "wants_email_notices": false, "last_modified": "2010-07-08 22:26:34", "user": 1, "ils_userid": null}}, {"pk": 1, "model": "syrup.servicedesk", "fields": {"active": true, "last_modified": "2010-07-08 22:30:22", "external_id": "", "name": "Leddy Library Reserves, Lower Level", "created": "2010-07-08 22:30:22"}}, {"pk": 1, "model": "syrup.term", "fields": {"code": "2010S", "name": "2010 Summer", "created": "2010-07-08 22:29:28", "finish": "2010-09-01", "start": "2010-05-01", "last_modified": "2010-07-08 22:29:28"}}, {"pk": 2, "model": "syrup.term", "fields": {"code": "2010F", "name": "2010 Fall", "created": "2010-07-08 22:29:50", "finish": "2010-12-31", "start": "2010-09-01", "last_modified": "2010-07-08 22:29:50"}}, {"pk": 3, "model": "syrup.term", "fields": {"code": "2011W", "name": "2011 Winter", "created": "2010-07-08 22:30:05", "finish": "2011-05-01", "start": "2011-01-01", "last_modified": "2010-07-08 22:30:05"}}, {"pk": 1, "model": "syrup.department", "fields": {"active": true, "service_desk": 1, "last_modified": "2010-07-08 22:30:34", "name": "Metaphysics", "created": "2010-07-08 22:30:34"}}, {"pk": 2, "model": "syrup.department", "fields": {"active": true, "service_desk": 1, "last_modified": "2010-07-08 22:30:44", "name": "Biology", "created": "2010-07-08 22:30:44"}}, {"pk": 3, "model": "syrup.department", "fields": {"active": true, "service_desk": 1, "last_modified": "2010-07-08 22:30:54", "name": "Computer Science", "created": "2010-07-08 22:30:54"}}, {"pk": 1, "model": "syrup.course", "fields": {"code": "99-100", "department": 1, "last_modified": "2010-07-08 22:31:24", "name": "Introduction to Thought", "created": "2010-07-08 22:31:24"}}, {"pk": 2, "model": "syrup.course", "fields": {"code": "99-200", "department": 1, "last_modified": "2010-07-08 22:31:36", "name": "Intermediate Thought", "created": "2010-07-08 22:31:36"}}, {"pk": 1, "model": "syrup.z3950target", "fields": {"name": "zed/OWA", "database": "OWA", "syntax": "USMARC", "host": "zed.concat.ca", "active": true, "port": 210}}, {"pk": 1, "model": "syrup.config", "fields": {"name": "application.title", "value": "Reserv-o-Matic"}}, {"pk": 2, "model": "syrup.config", "fields": {"name": "default.desk", "value": "1"}}]
+[{"pk": 22, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 8}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 8}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 8}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_message", "name": "Can add message", "content_type": 4}}, {"pk": 1, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_message", "name": "Can change message", "content_type": 4}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_message", "name": "Can delete message", "content_type": 4}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 7}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_migrationhistory", "name": "Can add migration history", "content_type": 9}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_migrationhistory", "name": "Can change migration history", "content_type": 9}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_migrationhistory", "name": "Can delete migration history", "content_type": 9}}, {"pk": 46, "model": "auth.permission", "fields": {"codename": "add_config", "name": "Can add config", "content_type": 16}}, {"pk": 40, "model": "auth.permission", "fields": {"codename": "add_course", "name": "Can add course", "content_type": 14}}, {"pk": 37, "model": "auth.permission", "fields": {"codename": "add_department", "name": "Can add department", "content_type": 13}}, {"pk": 52, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 18}}, {"pk": 58, "model": "auth.permission", "fields": {"codename": "add_item", "name": "Can add item", "content_type": 20}}, {"pk": 55, "model": "auth.permission", "fields": {"codename": "add_membership", "name": "Can add membership", "content_type": 19}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_servicedesk", "name": "Can add service desk", "content_type": 11}}, {"pk": 49, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 17}}, {"pk": 34, "model": "auth.permission", "fields": {"codename": "add_term", "name": "Can add term", "content_type": 12}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_userprofile", "name": "Can add user profile", "content_type": 10}}, {"pk": 43, "model": "auth.permission", "fields": {"codename": "add_z3950target", "name": "Can add z3950 target", "content_type": 15}}, {"pk": 47, "model": "auth.permission", "fields": {"codename": "change_config", "name": "Can change config", "content_type": 16}}, {"pk": 41, "model": "auth.permission", "fields": {"codename": "change_course", "name": "Can change course", "content_type": 14}}, {"pk": 38, "model": "auth.permission", "fields": {"codename": "change_department", "name": "Can change department", "content_type": 13}}, {"pk": 53, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 18}}, {"pk": 59, "model": "auth.permission", "fields": {"codename": "change_item", "name": "Can change item", "content_type": 20}}, {"pk": 56, "model": "auth.permission", "fields": {"codename": "change_membership", "name": "Can change membership", "content_type": 19}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "change_servicedesk", "name": "Can change service desk", "content_type": 11}}, {"pk": 50, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 17}}, {"pk": 35, "model": "auth.permission", "fields": {"codename": "change_term", "name": "Can change term", "content_type": 12}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_userprofile", "name": "Can change user profile", "content_type": 10}}, {"pk": 44, "model": "auth.permission", "fields": {"codename": "change_z3950target", "name": "Can change z3950 target", "content_type": 15}}, {"pk": 48, "model": "auth.permission", "fields": {"codename": "delete_config", "name": "Can delete config", "content_type": 16}}, {"pk": 42, "model": "auth.permission", "fields": {"codename": "delete_course", "name": "Can delete course", "content_type": 14}}, {"pk": 39, "model": "auth.permission", "fields": {"codename": "delete_department", "name": "Can delete department", "content_type": 13}}, {"pk": 54, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 18}}, {"pk": 60, "model": "auth.permission", "fields": {"codename": "delete_item", "name": "Can delete item", "content_type": 20}}, {"pk": 57, "model": "auth.permission", "fields": {"codename": "delete_membership", "name": "Can delete membership", "content_type": 19}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "delete_servicedesk", "name": "Can delete service desk", "content_type": 11}}, {"pk": 51, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 17}}, {"pk": 36, "model": "auth.permission", "fields": {"codename": "delete_term", "name": "Can delete term", "content_type": 12}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_userprofile", "name": "Can delete user profile", "content_type": 10}}, {"pk": 45, "model": "auth.permission", "fields": {"codename": "delete_z3950target", "name": "Can delete z3950 target", "content_type": 15}}, {"pk": 1, "model": "auth.user", "fields": {"username": "graham", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2010-07-09 09:20:52", "groups": [], "user_permissions": [], "password": "sha1$c1214$8cc63f8cfc851f04d1058f8448d895d0532a48ad", "email": "fawcett at uwindsor.ca", "date_joined": "2010-07-09 09:15:14"}}, {"pk": 16, "model": "contenttypes.contenttype", "fields": {"model": "config", "name": "config", "app_label": "syrup"}}, {"pk": 5, "model": "contenttypes.contenttype", "fields": {"model": "contenttype", "name": "content type", "app_label": "contenttypes"}}, {"pk": 14, "model": "contenttypes.contenttype", "fields": {"model": "course", "name": "course", "app_label": "syrup"}}, {"pk": 13, "model": "contenttypes.contenttype", "fields": {"model": "department", "name": "department", "app_label": "syrup"}}, {"pk": 2, "model": "contenttypes.contenttype", "fields": {"model": "group", "name": "group", "app_label": "auth"}}, {"pk": 18, "model": "contenttypes.contenttype", "fields": {"model": "group", "name": "group", "app_label": "syrup"}}, {"pk": 20, "model": "contenttypes.contenttype", "fields": {"model": "item", "name": "item", "app_label": "syrup"}}, {"pk": 8, "model": "contenttypes.contenttype", "fields": {"model": "logentry", "name": "log entry", "app_label": "admin"}}, {"pk": 19, "model": "contenttypes.contenttype", "fields": {"model": "membership", "name": "membership", "app_label": "syrup"}}, {"pk": 4, "model": "contenttypes.contenttype", "fields": {"model": "message", "name": "message", "app_label": "auth"}}, {"pk": 9, "model": "contenttypes.contenttype", "fields": {"model": "migrationhistory", "name": "migration history", "app_label": "south"}}, {"pk": 1, "model": "contenttypes.contenttype", "fields": {"model": "permission", "name": "permission", "app_label": "auth"}}, {"pk": 11, "model": "contenttypes.contenttype", "fields": {"model": "servicedesk", "name": "service desk", "app_label": "syrup"}}, {"pk": 6, "model": "contenttypes.contenttype", "fields": {"model": "session", "name": "session", "app_label": "sessions"}}, {"pk": 7, "model": "contenttypes.contenttype", "fields": {"model": "site", "name": "site", "app_label": "sites"}}, {"pk": 17, "model": "contenttypes.contenttype", "fields": {"model": "site", "name": "site", "app_label": "syrup"}}, {"pk": 12, "model": "contenttypes.contenttype", "fields": {"model": "term", "name": "term", "app_label": "syrup"}}, {"pk": 3, "model": "contenttypes.contenttype", "fields": {"model": "user", "name": "user", "app_label": "auth"}}, {"pk": 10, "model": "contenttypes.contenttype", "fields": {"model": "userprofile", "name": "user profile", "app_label": "syrup"}}, {"pk": 15, "model": "contenttypes.contenttype", "fields": {"model": "z3950target", "name": "z3950 target", "app_label": "syrup"}}, {"pk": "7ab9e962df78ff5840a97773342df8bf", "model": "sessions.session", "fields": {"expire_date": "2010-07-23 09:20:53", "session_data": "gAJ9cQEoVQp0ZXN0Y29va2llcQJVBndvcmtlZHEDVRJfYXV0aF91c2VyX2JhY2tlbmRxBFUpZGph\nbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmRxBVUNX2F1dGhfdXNlcl9pZHEG\nSwF1LjI2YWFjNGJiMTNlZDE1ZjlmYjQxMzZlMWJjZGIxMDAw\n"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}, {"pk": 1, "model": "south.migrationhistory", "fields": {"applied": "2010-07-09 13:20:26", "app_name": "syrup", "migration": "0001_initial"}}, {"pk": 2, "model": "south.migrationhistory", "fields": {"applied": "2010-07-09 13:20:26", "app_name": "syrup", "migration": "0002_auto__add_field_site_term__add_field_site_course__add_unique_site_owne"}}, {"pk": 1, "model": "syrup.userprofile", "fields": {"last_email_notice": "2010-07-08 22:26:34", "created": "2010-07-08 22:26:34", "wants_email_notices": false, "last_modified": "2010-07-08 22:26:34", "user": 1, "ils_userid": null}}, {"pk": 1, "model": "syrup.servicedesk", "fields": {"active": true, "last_modified": "2010-07-08 22:30:22", "external_id": "", "name": "Leddy Library Reserves, Lower Level", "created": "2010-07-08 22:30:22"}}, {"pk": 1, "model": "syrup.term", "fields": {"code": "2010S", "name": "2010 Summer", "created": "2010-07-08 22:29:28", "finish": "2010-09-01", "start": "2010-05-01", "last_modified": "2010-07-08 22:29:28"}}, {"pk": 2, "model": "syrup.term", "fields": {"code": "2010F", "name": "2010 Fall", "created": "2010-07-08 22:29:50", "finish": "2010-12-31", "start": "2010-09-01", "last_modified": "2010-07-08 22:29:50"}}, {"pk": 3, "model": "syrup.term", "fields": {"code": "2011W", "name": "2011 Winter", "created": "2010-07-08 22:30:05", "finish": "2011-05-01", "start": "2011-01-01", "last_modified": "2010-07-08 22:30:05"}}, {"pk": 1, "model": "syrup.department", "fields": {"active": true, "service_desk": 1, "last_modified": "2010-07-08 22:30:34", "name": "Metaphysics", "created": "2010-07-08 22:30:34"}}, {"pk": 2, "model": "syrup.department", "fields": {"active": true, "service_desk": 1, "last_modified": "2010-07-08 22:30:44", "name": "Biology", "created": "2010-07-08 22:30:44"}}, {"pk": 3, "model": "syrup.department", "fields": {"active": true, "service_desk": 1, "last_modified": "2010-07-08 22:30:54", "name": "Computer Science", "created": "2010-07-08 22:30:54"}}, {"pk": 1, "model": "syrup.course", "fields": {"code": "99-100", "department": 1, "last_modified": "2010-07-08 22:31:24", "name": "Introduction to Thought", "created": "2010-07-08 22:31:24"}}, {"pk": 2, "model": "syrup.course", "fields": {"code": "99-200", "department": 1, "last_modified": "2010-07-08 22:31:36", "name": "Intermediate Thought", "created": "2010-07-08 22:31:36"}}, {"pk": 1, "model": "syrup.z3950target", "fields": {"name": "zed/OWA", "database": "OWA", "syntax": "USMARC", "host": "zed.concat.ca", "active": true, "port": 210}}, {"pk": 1, "model": "syrup.config", "fields": {"name": "application.title", "value": "Reserv-o-Matic"}}, {"pk": 2, "model": "syrup.config", "fields": {"name": "default.desk", "value": "1"}}]

Added: servres/trunk/conifer/syrup/migrations/0002_auto__add_field_site_term__add_field_site_course__add_unique_site_owne.py
===================================================================
--- servres/trunk/conifer/syrup/migrations/0002_auto__add_field_site_term__add_field_site_course__add_unique_site_owne.py	                        (rev 0)
+++ servres/trunk/conifer/syrup/migrations/0002_auto__add_field_site_term__add_field_site_course__add_unique_site_owne.py	2010-07-15 00:54:42 UTC (rev 912)
@@ -0,0 +1,205 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+    
+    def forwards(self, orm):
+        
+        # Adding field 'Site.term'
+        db.add_column('syrup_site', 'term', self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['syrup.Term']), keep_default=False)
+
+        # Adding field 'Site.course'
+        db.add_column('syrup_site', 'course', self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['syrup.Course']), keep_default=False)
+
+        # Removing M2M table for field courses on 'Site'
+        db.delete_table('syrup_site_courses')
+
+        # Removing M2M table for field terms on 'Site'
+        db.delete_table('syrup_site_terms')
+
+        # Adding unique constraint on 'Site', fields ['owner', 'course', 'term']
+        db.create_unique('syrup_site', ['owner_id', 'course_id', 'term_id'])
+    
+    
+    def backwards(self, orm):
+        
+        # Deleting field 'Site.term'
+        db.delete_column('syrup_site', 'term_id')
+
+        # Deleting field 'Site.course'
+        db.delete_column('syrup_site', 'course_id')
+
+        # Adding M2M table for field courses on 'Site'
+        db.create_table('syrup_site_courses', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('site', models.ForeignKey(orm['syrup.site'], null=False)),
+            ('course', models.ForeignKey(orm['syrup.course'], null=False))
+        ))
+        db.create_unique('syrup_site_courses', ['site_id', 'course_id'])
+
+        # Adding M2M table for field terms on 'Site'
+        db.create_table('syrup_site_terms', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('site', models.ForeignKey(orm['syrup.site'], null=False)),
+            ('term', models.ForeignKey(orm['syrup.term'], null=False))
+        ))
+        db.create_unique('syrup_site_terms', ['site_id', 'term_id'])
+
+        # Removing unique constraint on 'Site', fields ['owner', 'course', 'term']
+        db.delete_unique('syrup_site', ['owner_id', 'course_id', 'term_id'])
+    
+    
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'syrup.config': {
+            'Meta': {'object_name': 'Config'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+            'value': ('django.db.models.fields.CharField', [], {'max_length': '8192'})
+        },
+        'syrup.course': {
+            'Meta': {'object_name': 'Course'},
+            'code': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'department': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.Department']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+        },
+        'syrup.department': {
+            'Meta': {'object_name': 'Department'},
+            'active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+            'service_desk': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.ServiceDesk']"})
+        },
+        'syrup.group': {
+            'Meta': {'object_name': 'Group'},
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'external_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '2048', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.Site']"})
+        },
+        'syrup.item': {
+            'Meta': {'object_name': 'Item'},
+            'author': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '8192', 'null': 'True', 'blank': 'True'}),
+            'bib_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'fileobj': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'fileobj_mimetype': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'item_type': ('django.db.models.fields.CharField', [], {'max_length': '7'}),
+            'itemtype': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '1', 'null': 'True', 'blank': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'marcxml': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'parent_heading': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.Item']", 'null': 'True', 'blank': 'True'}),
+            'published': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'publisher': ('django.db.models.fields.CharField', [], {'max_length': '8192', 'null': 'True', 'blank': 'True'}),
+            'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.Site']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '8192', 'db_index': 'True'}),
+            'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
+        },
+        'syrup.membership': {
+            'Meta': {'unique_together': "(('group', 'user'),)", 'object_name': 'Membership'},
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.Group']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'role': ('django.db.models.fields.CharField', [], {'default': "'STUDT'", 'max_length': '6'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        },
+        'syrup.servicedesk': {
+            'Meta': {'object_name': 'ServiceDesk'},
+            'active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'external_id': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'syrup.site': {
+            'Meta': {'unique_together': "(('course', 'term', 'owner'),)", 'object_name': 'Site'},
+            'access': ('django.db.models.fields.CharField', [], {'default': "'CLOSE'", 'max_length': '5'}),
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.Course']"}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'passkey': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '256', 'null': 'True', 'blank': 'True'}),
+            'service_desk': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.ServiceDesk']"}),
+            'term': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['syrup.Term']"})
+        },
+        'syrup.term': {
+            'Meta': {'object_name': 'Term'},
+            'code': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'finish': ('django.db.models.fields.DateField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
+            'start': ('django.db.models.fields.DateField', [], {})
+        },
+        'syrup.userprofile': {
+            'Meta': {'object_name': 'UserProfile'},
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ils_userid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'last_email_notice': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}),
+            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'wants_email_notices': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'})
+        },
+        'syrup.z3950target': {
+            'Meta': {'object_name': 'Z3950Target'},
+            'active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'database': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'host': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'port': ('django.db.models.fields.IntegerField', [], {'default': '210'}),
+            'syntax': ('django.db.models.fields.CharField', [], {'default': "'USMARC'", 'max_length': '10'})
+        }
+    }
+    
+    complete_apps = ['syrup']

Modified: servres/trunk/conifer/syrup/models.py
===================================================================
--- servres/trunk/conifer/syrup/models.py	2010-07-15 00:54:27 UTC (rev 911)
+++ servres/trunk/conifer/syrup/models.py	2010-07-15 00:54:42 UTC (rev 912)
@@ -144,11 +144,9 @@
 
 class Site(BaseModel):
     """A a list of materials for one (or more) course offering(s)."""
-    # some courses may be ad-hoc and have no code.
-    # TODO: constrain there is at least one course and one term (deferred).
-    courses = m.ManyToManyField(Course)
-    terms = m.ManyToManyField(Term)
-    owner = m.ForeignKey(User)
+    course       = m.ForeignKey(Course)
+    term         = m.ForeignKey(Term)
+    owner        = m.ForeignKey(User)
     service_desk = m.ForeignKey(ServiceDesk)
 
     access = m.CharField(max_length=5,
@@ -165,11 +163,11 @@
     # TODO: for postgres, add UNIQUE constraint on 'passkey'.
     passkey = m.CharField(db_index=True, blank=True, null=True, max_length=256)
 
+    class Meta:
+        unique_together = (('course', 'term', 'owner'))
+
     def __unicode__(self):
-        cc = '%s' % (', '.join([c.code for c in self.courses.all()]))
-        tt = '(%s)' % (', '.join([t.code for t in self.terms.all()]))
-        oo = '(%s)' % self.owner.last_name
-        return u'%s %s %s' % (cc, tt, oo)
+        return u'%s %s %s' % (self.course, self.term, self.owner)
 
     def list_display(self):
         if self.code:

Modified: servres/trunk/conifer/templates/edit_site.xhtml
===================================================================
--- servres/trunk/conifer/templates/edit_site.xhtml	2010-07-15 00:54:27 UTC (rev 911)
+++ servres/trunk/conifer/templates/edit_site.xhtml	2010-07-15 00:54:42 UTC (rev 912)
@@ -17,6 +17,11 @@
   <div py:if="instance.id">${site_banner(instance)}</div>
   <h1>${title}</h1>
   <p py:if="instance.id"><a href="permission/">Edit site permissions</a> &bull; <a href="${instance.site_url()}">Return to site page</a></p>
+  <div py:with="nfe=form.non_field_errors()">
+    <ul py:if="nfe" class="errorlist">
+      <li py:for="err in nfe">${err}</li>
+    </ul>
+  </div>
   <form action="." method="POST">
     <tr py:def="field_row(field, example=None)">
       <th>${field.label}</th>
@@ -31,8 +36,8 @@
     <h2>General description</h2>
     <table class="metadata_table">
     ${field_row(form.owner)}
-    ${field_row(form.terms)}
-    ${field_row(form.courses)}
+    ${field_row(form.term)}
+    ${field_row(form.course)}
     ${field_row(form.service_desk)}
 
     <!-- ${field_row(form.department)} -->



More information about the open-ils-commits mailing list