From: gfawcett Date: Thu, 19 Mar 2009 02:01:03 +0000 (+0000) Subject: Added Metadata table for optional item attributes. Breaks old model. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=86fdd5e465e5d789df29c54eecf469481621ae5f;p=Syrup.git Added Metadata table for optional item attributes. Breaks old model. Don't yet have a metadata-entry mechanism, other than the Django admin interface. git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@199 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- diff --git a/conifer/syrup/admin.py b/conifer/syrup/admin.py index 449c21b..a0f4324 100644 --- a/conifer/syrup/admin.py +++ b/conifer/syrup/admin.py @@ -23,5 +23,16 @@ from conifer.syrup.models import * # admin.site.register(value) for m in [LibraryUnit, ServiceDesk, Member, Department, Course, Term, UserProfile, NewsItem, - Item, Target]: + Target]: admin.site.register(m) + + +class MetadataInline(admin.StackedInline): + model = Metadata + extra = 3 + +class ItemAdmin(admin.ModelAdmin): + model = Item + inlines = [MetadataInline] + +admin.site.register(Item, ItemAdmin) diff --git a/conifer/syrup/models.py b/conifer/syrup/models.py index 1a63b62..3f0b379 100644 --- a/conifer/syrup/models.py +++ b/conifer/syrup/models.py @@ -349,85 +349,44 @@ class Item(m.Model): ('HEADING', _('Heading'))) item_type = m.CharField(max_length=7, choices=ITEM_TYPE_CHOICES) sort_order = m.IntegerField(default=0) + # parent must be a heading. could use ForeignKey.limit_choices_to, # to enforce this in the admin ui. parent_heading = m.ForeignKey('Item', blank=True, null=True) - # Metadata. - - # TODO: Are all these relevant to all item types? If not, which - # ones should be 'required' for which item-types? We cannot - # enforce these requirements through model constraints, unless we - # break Item up into multiple tables. But there are other ways we - # can specify the constraints. + # the display title may not be the same as the dc:title. title = m.CharField(max_length=255,db_index=True) - author = m.CharField(max_length=255,db_index=True, blank=True, null=True) - source = m.CharField(max_length=255,db_index=True, blank=True, null=True) - volume_title = m.CharField(max_length=255,db_index=True, blank=True, null=True) - content_notes = m.CharField(max_length=255, blank=True, null=True) - volume_edition = m.CharField(max_length=255, blank=True, null=True) - content_notes = m.CharField(max_length=255, blank=True, null=True) - volume_edition = m.CharField(max_length=255, blank=True, null=True) - pages_times = m.CharField(max_length=255, blank=True, null=True) - performer = m.CharField(max_length=255,db_index=True, blank=True, null=True) - year = m.CharField(max_length=10,db_index=True, blank=True, null=True) - - local_control_key = m.CharField(max_length=30, blank=True, null=True) + # ditto the URL: this is for display items that are links. url = m.URLField(blank=True, null=True) - mime_type = m.CharField(max_length=100,default='text/html', blank=True, null=True) - isbn = m.CharField(max_length=13,db_index=True, blank=True, null=True) - issn = m.CharField(max_length=8,db_index=True, blank=True, null=True) - oclc = m.CharField(max_length=9,db_index=True, blank=True, null=True) + # for items of type ELEC (attached electronic document) + fileobj = m.FileField(upload_to='uploads/%Y/%m/%d', max_length=255, + blank=True, null=True, default=None) - home_library = m.ForeignKey(LibraryUnit, blank=True, null=True) + fileobj_mimetype = m.CharField(max_length=128, blank=True, null=True, default=None) - # shouldn't the icon be derived from the MIME type? - ###item_icon = m.CharField(max_length=64, choices=ICON_CHOICES) - ##item_group = m.CharField(max_length=25,default='0') - ##private_user_id = m.IntegerField(null=True,blank=True) - ##old_id = m.IntegerField(null=True,blank=True) + # basic timestamps + date_created = m.DateTimeField(auto_now_add=True) + last_modified = m.DateTimeField(auto_now=True) - # Physical Item properties - ''' - want to add enumeration and chronology info - ''' - # enumeration = m.CharField(max_length=255, blank=True, null=True) - # chronology = m.CharField(max_length=255, blank=True, null=True) - call_number = m.CharField(max_length=30, blank=True, null=True) # long enough? - barcode = m.CharField(max_length=30, blank=True, null=True) # long enough? - -# # owning_library:is this supposed to be a code? -# owning_library = m.CharField(max_length=15,default='0') -# item_type = m.CharField(max_length=30) -# # who is the owner? -# owner_user_id = m.IntegerField(null=True,blank=True) + # stuff I'm not sure about yet. I don't think it belongs here. STATUS_CHOICE = (('INPROCESS', _('In Process')), # physical, pending ('ACTIVE', _('Active')), # available - ('INACTIVE', _('InActive'))) # no longer on rsrv. + ('INACTIVE', _('Inactive'))) # no longer on rsrv. phys_status = m.CharField(max_length=9, null=True, blank=True, choices=STATUS_CHOICE, default=None) # null if not physical item. - activation_date = m.DateField(auto_now=False) + activation_date = m.DateField(auto_now=False, blank=True, null=True) expiration_date = m.DateField(auto_now=False, blank=True, null=True) # requested_loan_period: why is this a text field? requested_loan_period = m.CharField(max_length=255,blank=True,default='', null=True) - # for items of type ELEC (attached electronic document) - fileobj = m.FileField(upload_to='uploads/%Y/%m/%d', max_length=255, - blank=True, null=True, default=None) - - fileobj_mimetype = m.CharField(max_length=128, blank=True, null=True, default=None) - - - date_created = m.DateTimeField(auto_now_add=True) - last_modified = m.DateTimeField(auto_now=True) def title_hl(self, terms): hl_title = self.title @@ -436,8 +395,12 @@ class Item(m.Model): return hl_title + def author(self): + creators = self.metadata_set.filter(name='dc:creator') + return creators and creators[0].value or None + def author_hl(self, terms): - hl_author = self.author + hl_author = self.author() for term in terms: hl_author = highlight(hl_author,term) @@ -480,6 +443,37 @@ class Item(m.Model): else: return self.course.course_url() + + +metadata_attributes = { + 'dc:contributor': 'Contributor', + 'dc:coverage': 'Coverage', + 'dc:creator': 'Creator', + 'dc:date': 'Date', + 'dc:description': 'Description', + 'dc:format': 'Format', + 'dc:identifier': 'Identifier', + 'dc:language': 'Language', + 'dc:publisher': 'Publisher', + 'dc:relation': 'Relation', + 'dc:rights': 'Rights', + 'dc:source': 'Source', + 'dc:subject': 'Subject', + 'dc:title': 'Title', + 'dc:type': 'Type', + 'syrup:barcode': 'Barcode', + 'syrup:enumeration': 'Enumeration', + 'syrup:chronology': 'Chronology'} + + +class Metadata(m.Model): + """Metadata for items.""" + + item = m.ForeignKey(Item) + #fixme, arbitrary sizes. + name = m.CharField(max_length=128, choices=metadata_attributes.items()) + value = m.CharField(max_length=4096) + #------------------------------------------------------------ # News items diff --git a/conifer/syrup/views.py b/conifer/syrup/views.py index 51fe881..c6a43fc 100644 --- a/conifer/syrup/views.py +++ b/conifer/syrup/views.py @@ -611,9 +611,7 @@ def item_add(request, course_id, item_id): item_type='HEADING', parent_heading=parent_item, title=title, - author=author, - activation_date=datetime.now(), - last_modified=datetime.now()) + ) item.save() elif item_type == 'URL': title = request.POST.get('title', '').strip() @@ -627,9 +625,6 @@ def item_add(request, course_id, item_id): item_type='URL', parent_heading=parent_item, title=title, - author=author, - activation_date=datetime.now(), - last_modified=datetime.now(), url = url) item.save() elif item_type == 'ELEC': @@ -643,9 +638,6 @@ def item_add(request, course_id, item_id): item_type='ELEC', parent_heading=parent_item, title=title, - author=author, - activation_date=datetime.now(), - last_modified=datetime.now(), fileobj_mimetype = upload.content_type, ) item.fileobj.save(upload.name, upload) @@ -753,7 +745,13 @@ def search(request, in_course=None): norm_query = normalize_query(query_string) #item search - this will be expanded - item_query = get_query(query_string, ['title', 'author']) + + # fixme, when moving author to the Metadata table, we can no + # longer do a straight search on author. Using + # 'metadata__value' sort of works, but also searches other + # metadata fields. + + item_query = get_query(query_string, ['title', 'metadata__value']) #need to think about sort order here, probably better by author (will make sortable at display level) results_list = models.Item.objects.filter(item_query).order_by('title') if in_course: diff --git a/conifer/templates/item_metadata.xhtml b/conifer/templates/item_metadata.xhtml index e940575..089a204 100644 --- a/conifer/templates/item_metadata.xhtml +++ b/conifer/templates/item_metadata.xhtml @@ -18,7 +18,6 @@ title = item.title -
Title${item.title}
Type${item.item_type}
Author${item.author}
URL${item.url}
@@ -28,5 +27,11 @@ title = item.title Content length${item.fileobj.size}
+ + + + + +
${attr.get_name_display()}${attr.value}