overriding save to force None-ness on the interval fields
[Evergreen.git] / Open-ILS / admin / ils_admin / setup / ils_data / models.py
1 from django.db import models
2 from django.db.models import signals
3 from django.dispatch import dispatcher
4 import datetime
5 from gettext import gettext as _
6
7 INTERVAL_HELP_TEXT = _('examples: "1 hour", "14 days", "3 months", "DD:HH:MM:SS.ms"')
8 CHAR_MAXLEN=200 # just provide a sane default
9
10
11 """ --------------------------------------------------------------
12     Permission tables
13     -------------------------------------------------------------- """
14
15
16 class PermList(models.Model):
17     code = models.CharField(maxlength=100)
18     description = models.TextField(blank=True)
19     class Admin:
20         list_display = ('code','description')
21         search_fields = ['code']
22     class Meta:
23         db_table = 'perm_list'
24         ordering = ['code']
25         verbose_name = _('Permission')
26     def __str__(self):
27         return self.code
28
29 class GrpPermMap(models.Model):
30     grp_id = models.ForeignKey('GrpTree', db_column='grp')
31     perm_id = models.ForeignKey(PermList, db_column='perm')
32     depth_id = models.ForeignKey('OrgUnitType', to_field='depth', db_column='depth')
33     grantable = models.BooleanField()
34     class Admin:
35         list_filter = ['grp_id']
36         list_display = ('perm_id', 'grp_id', 'depth_id')
37     class Meta:
38         db_table = 'grp_perm_map'
39         ordering = ['perm_id', 'grp_id']
40         verbose_name = _('Permission Setting')
41     def __str__(self):
42         return str(self.grp_id)+' -> '+str(self.perm_id)
43
44 class GrpTree(models.Model):
45     name = models.CharField(maxlength=100)
46     parent_id = models.ForeignKey('self', null=True, related_name='children', db_column='parent')
47     description = models.CharField(blank=True, maxlength=CHAR_MAXLEN)
48     perm_interval = models.CharField(blank=True, maxlength=100, help_text=INTERVAL_HELP_TEXT)
49     application_perm = models.CharField(blank=True, maxlength=100)
50     usergroup = models.BooleanField()
51     class Admin:
52         list_display = ('name', 'description')
53         list_filter = ['parent_id']
54         search_fields = ['name', 'description']
55     class Meta:
56         db_table = 'grp_tree'
57         ordering = ['name']
58         verbose_name = _('User Group')
59     def __str__(self):
60         return self.name
61
62
63
64
65
66 """ There's no way to do user-based mangling given the size of the data without custom handling.
67       When you try to create a new permission map, it tries to load all users into a dropdown selector :(
68
69 class User(models.Model):
70    card_id = models.ForeignKey('Card', db_column='card')
71    profile_id = models.ForeignKey(GrpTree, db_column='profile')
72    usrname = models.CharField(blank=False, null=False, maxlength=CHAR_MAXLEN)
73    def __str__(self):
74       return "%s (%s)" % ( str(self.card_id), str(self.usrname))
75    class Meta:
76       db_table = 'usr'
77       verbose_name = 'User'
78
79 class UsrPermMap(models.Model):
80    usr_id = models.ForeignKey(User, db_column='usr')
81    perm_id = models.ForeignKey(PermList, db_column='perm')
82    depth_id = models.ForeignKey(OrgUnitType, to_field='depth', db_column='depth')
83    grantable = models.BooleanField()
84    class Admin:
85       search_fields = ['usr_id', 'perm_id']  # we need text fields to search...
86    class Meta:
87       db_table = 'usr_perm_map'
88       verbose_name = 'User Permission'
89    def __str__(self):
90       return "%s -> %s" % ( str(self.usr_id), str(self.perm_id) )
91
92
93 class Card(models.Model):
94    usr_id = models.ForeignKey(User, db_column='usr')
95    barcode = models.CharField(blank=False, null=False, maxlength=CHAR_MAXLEN)
96    active = models.BooleanField()
97    def __str__(self): 
98       return self.barcode
99    class Meta:
100       db_table = 'card'
101       verbose_name = 'Card'
102 """
103
104    
105
106 """ --------------------------------------------------------------
107     Actor tables
108     -------------------------------------------------------------- """
109
110 class OrgUnitType(models.Model):
111     name = models.CharField(maxlength=100)
112     opac_label = models.CharField(maxlength=100)
113     depth = models.IntegerField()
114     parent_id = models.ForeignKey('self', null=True, related_name='children', db_column='parent')
115     can_have_vols = models.BooleanField()
116     can_have_users = models.BooleanField()
117     class Meta:
118         db_table = 'org_unit_type'
119         verbose_name = _('Organizational Unit Type')
120     class Admin:
121         list_display = ('name', 'depth')
122         list_filter = ['parent_id']
123         ordering = ['depth']
124     def __str__(self):
125         return self.name
126
127 class OrgUnitSetting(models.Model):
128     org_unit_id = models.ForeignKey('OrgUnit', db_column='org_unit')
129     name = models.CharField(maxlength=CHAR_MAXLEN)
130     value = models.CharField(maxlength=CHAR_MAXLEN)
131     class Admin:
132         list_display = ('org_unit_id', 'name', 'value')
133         search_fields = ['name', 'value']
134         list_filter = ['name', 'org_unit_id']
135     class Meta:
136         db_table = 'org_unit_setting'
137         ordering = ['org_unit_id', 'name']
138         verbose_name = _('Organizational Unit Setting')
139     def __str__(self):
140         return "%s:%s=%s" % (self.org_unit_id.shortname, self.name, self.value)
141
142
143 class OrgAddress(models.Model):
144     valid = models.BooleanField()
145     org_unit_id = models.ForeignKey('OrgUnit', db_column='org_unit')
146     address_type = models.CharField(blank=False, maxlength=CHAR_MAXLEN, default=_('MAILING'))
147     street1 = models.CharField(blank=False, maxlength=CHAR_MAXLEN)
148     street2 = models.CharField(maxlength=CHAR_MAXLEN)
149     city = models.CharField(blank=False, maxlength=CHAR_MAXLEN)
150     county = models.CharField(maxlength=CHAR_MAXLEN)
151     state = models.CharField(blank=False, maxlength=CHAR_MAXLEN)
152     country = models.CharField(blank=False, maxlength=CHAR_MAXLEN)
153     post_code = models.CharField(blank=False, maxlength=CHAR_MAXLEN)
154     class Admin:
155         search_fields = ['street1', 'city', 'post_code']   
156         list_filter = ['org_unit_id']
157         list_display = ('street1', 'street2', 'city', 'county', 'state', 'post_code')
158     class Meta:
159         ordering = ['city']
160         db_table = 'org_address'
161         verbose_name = _('Organizational Unit Address')
162     def __str__(self):
163         return self.street1+' '+self.city+', '+self.state+' '+self.post_code
164
165 class OrgUnit(models.Model):
166     parent_ou_id = models.ForeignKey('self', null=True, related_name='children', db_column='parent_ou')
167     ou_type_id = models.ForeignKey(OrgUnitType, db_column='ou_type')
168     shortname = models.CharField(maxlength=CHAR_MAXLEN)
169     name = models.CharField(maxlength=CHAR_MAXLEN)
170     email = models.EmailField(null=True, blank=True)
171     phone = models.CharField(maxlength=CHAR_MAXLEN, null=True, blank=True)
172     opac_visible = models.BooleanField(blank=True)
173     ill_address_id = models.ForeignKey(OrgAddress, 
174         db_column='ill_address', related_name='ill_addresses', null=True, blank=True)
175     holds_address_id = models.ForeignKey(OrgAddress, 
176         db_column='holds_address', related_name='holds_addresses', null=True, blank=True)
177     mailing_address_id = models.ForeignKey(OrgAddress, 
178         db_column='mailing_address', related_name='mailing_addresses', null=True, blank=True)
179     billing_address_id = models.ForeignKey(OrgAddress, 
180         db_column='billing_address', related_name='billing_addresses', null=True, blank=True)
181     class Admin:
182         search_fields = ['name', 'shortname']
183         list_display = ('shortname', 'name')
184     class Meta:
185         db_table = 'org_unit'
186         ordering = ['shortname']
187         verbose_name = _('Organizational Unit')
188     def __str__(self):
189         return self.shortname
190
191 class HoursOfOperation(models.Model):
192     #choices = tuple([ (datetime.time(i), str(i)) for i in range(0,23) ])
193     org_unit = models.ForeignKey('OrgUnit', db_column='id')
194     # XXX add better time widget support
195     dow_0_open = models.TimeField(_('Monday Open'), null=False, blank=False, default=datetime.time(9))
196     dow_0_close = models.TimeField(_('Monday Close'), null=False, blank=False, default=datetime.time(17))
197     dow_1_open = models.TimeField(_('Tuesday Open'), null=False, blank=False, default=datetime.time(9))
198     dow_1_close = models.TimeField(_('Tuesday Close'), null=False, blank=False, default=datetime.time(17))
199     dow_2_open = models.TimeField(_('Wednesday Open'), null=False, blank=False, default=datetime.time(9))
200     dow_2_close = models.TimeField(_('Wednesday Close'), null=False, blank=False, default=datetime.time(17))
201     dow_3_open = models.TimeField(_('Thursday Open'), null=False, blank=False, default=datetime.time(9))
202     dow_3_close = models.TimeField(_('Thursday Close'), null=False, blank=False, default=datetime.time(17))
203     dow_4_open = models.TimeField(_('Friday Open'), null=False, blank=False, default=datetime.time(9))
204     dow_4_close = models.TimeField(_('Friday Close'), null=False, blank=False, default=datetime.time(17))
205     dow_5_open = models.TimeField(_('Saturday Open'), null=False, blank=False, default=datetime.time(9))
206     dow_5_close = models.TimeField(_('Saturday Close'), null=False, blank=False, default=datetime.time(17))
207     dow_6_open = models.TimeField(_('Sunday Open'), null=False, blank=False, default=datetime.time(9))
208     dow_6_close = models.TimeField(_('Sunday Close'), null=False, blank=False, default=datetime.time(17))
209     class Admin:
210         pass
211     class Meta:
212         db_table = 'hours_of_operation'
213         verbose_name = _('Hours of Operation')
214         verbose_name_plural = verbose_name
215     def __str__(self):
216         return str(self.org_unit)
217
218
219
220 """ --------------------------------------------------------------
221     Config tables
222     -------------------------------------------------------------- """
223
224 class CircModifier(models.Model):
225     code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
226     name = models.CharField(maxlength=CHAR_MAXLEN)
227     description = models.CharField(maxlength=CHAR_MAXLEN);
228     sip2_media_type = models.CharField(maxlength=CHAR_MAXLEN);
229     magnetic_media = models.BooleanField()
230     class Admin:
231         search_fields = ['name','code']
232         list_display = ('code','name','description','sip2_media_type','magnetic_media')
233     class Meta:
234         db_table = 'circ_modifier'
235         ordering = ['name']
236         verbose_name = _('Circulation Modifier')
237     def __str__(self):
238         return self.name
239
240
241 class VideoRecordingFormat(models.Model):
242     code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
243     value = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT);
244     class Admin:
245         search_fields = ['value','code']
246         list_display = ('value','code')
247     class Meta:
248         db_table = 'videorecording_format_map'
249         ordering = ['code']
250         verbose_name = _('Video Recording Format')
251     def __str__(self):
252         return self.value
253
254 class RuleCircDuration(models.Model):
255     name = models.CharField(maxlength=CHAR_MAXLEN)
256     extended = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT);
257     normal = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT);
258     shrt = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT);
259     max_renewals = models.IntegerField()
260     class Admin:
261         search_fields = ['name']
262         list_display = ('name','extended','normal','shrt','max_renewals')
263     class Meta:
264         db_table = 'rule_circ_duration'
265         ordering = ['name']
266         verbose_name = _('Circ Duration Rule')
267     def __str__(self):
268         return self.name
269
270 class CircMatrixMatchpoint(models.Model):
271     active = models.BooleanField(blank=False, default=True)
272     org_unit_id = models.ForeignKey(OrgUnit, db_column='org_unit', blank=False)
273     grp_id = models.ForeignKey(GrpTree, db_column='grp', blank=False, verbose_name=_("User Group"))
274     circ_modifier_id = models.ForeignKey(CircModifier, db_column='circ_modifier', null=True,blank=True)
275     marc_type_id = models.ForeignKey('ItemTypeMap', db_column='marc_type', null=True,blank=True)
276     marc_form_id = models.ForeignKey('ItemFormMap', db_column='marc_form', null=True,blank=True)
277     marc_vr_format_id = models.ForeignKey('VideoRecordingFormat', db_column='marc_vr_format', null=True,blank=True)
278     ref_flag = models.BooleanField(null=True)
279     usr_age_lower_bound = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT, null=True, blank=True)
280     usr_age_upper_bound = models.CharField(maxlength=CHAR_MAXLEN, help_text=INTERVAL_HELP_TEXT, null=True, blank=True)
281
282     def save(self):
283         ''' Override to force None-ness on the interval fields '''
284         if self.usr_age_lower_bound == "":
285             self.usr_age_lower_bound = None
286         if self.usr_age_upper_bound == "":
287             self.usr_age_upper_bound = None
288         return models.Model.save(self)
289
290     class Admin:
291         search_fields = ['grp_id','org_unit_id','circ_modifier_id','marc_type_id','marc_form_id',
292             'marc_vr_format_id','usr_age_lower_bound','usr_age_upper_bound']
293
294         list_display = ('grp_id','org_unit_id','circ_modifier_id','marc_type_id','marc_form_id',
295             'marc_vr_format_id','ref_flag','usr_age_lower_bound','usr_age_upper_bound')
296
297         list_filter = ['grp_id','org_unit_id','circ_modifier_id','marc_type_id','marc_form_id','marc_vr_format_id']
298     class Meta:
299         db_table = 'circ_matrix_matchpoint'
300         ordering = ['id']
301         verbose_name = _('Circulation Matrix Matchpoint')
302     def __str__(self):
303         return _("OrgUnit: %(orgid)s, Group: %(grpid)s, Circ Modifier: %(modid)s") % {
304             'orgid':self.org_unit_id, 'grpid':self.grp_id, 'modid':self.circ_modifier_id}
305
306 class CircMatrixTest(models.Model):
307     matchpoint_id =  models.ForeignKey(CircMatrixMatchpoint, db_column='matchpoint', blank=False, primary_key=True, 
308         edit_inline=models.TABULAR, core=True, num_in_admin=1)
309     max_items_out = models.IntegerField(null=True, blank=True)
310     max_overdue = models.IntegerField(null=True, blank=True)
311     max_fines = models.FloatField(max_digits=8, decimal_places=2, null=True, blank=True)
312     script_test = models.CharField(maxlength=CHAR_MAXLEN, null=True, blank=True)
313     class Admin:
314         list_display = ('matchpoint_id','max_items_out','max_overdue','max_fines','script_test')
315     class Meta:
316         db_table = 'circ_matrix_test'
317         ordering = ['matchpoint_id']
318         verbose_name = _('Circ Matrix Test')
319     def __str__(self):
320         return _("%(mid)s, Max Items Out: %(iout)s, Max Overdue: %(odue)s, Max Fines: %(fines)s") % {
321             'mid': self.matchpoint_id, 'iout' : self.max_items_out, 'odue':self.max_overdue, 'fines':self.max_fines}
322
323 class CircMatrixCircModTest(models.Model):
324     matchpoint_id =  models.ForeignKey(CircMatrixMatchpoint, db_column='matchpoint', blank=False, edit_inline=True,core=True, num_in_admin=1)
325     items_out = models.IntegerField(blank=False)
326     circ_mod_id = models.ForeignKey(CircModifier, db_column='circ_mod', blank=False)
327     class Admin:
328         search_fields = ['circ_mod_id']
329         list_display = ('matchpoint_id','circ_mod_id','items_out')
330     class Meta:
331         db_table = 'circ_matrix_circ_mod_test'
332         ordering = ['matchpoint_id']
333         verbose_name = _('Circ Matrix Items Out Cirulation Modifier Subtest')
334     def __str__(self):
335         return _("%(mid)s, Restriction: %(mod)s") % {'mid': self.matchpoint_id,'mod':self.circ_mod_id}
336
337 class CircMatrixRuleSet(models.Model):
338     matchpoint_id =  models.ForeignKey(CircMatrixMatchpoint, db_column='matchpoint', 
339         blank=False, primary_key=True, edit_inline=True,core=True, num_in_admin=1)
340     duration_rule_id = models.ForeignKey(RuleCircDuration, db_column='duration_rule', blank=False)
341     recurring_fine_rule_id = models.ForeignKey('RuleRecurringFine', db_column='recurring_fine_rule', blank=False)
342     max_fine_rule_id = models.ForeignKey('RuleMaxFine', db_column='max_fine_rule', blank=False)
343     class Admin:
344         search_fields = ['matchoint_id']
345         list_display = ('matchpoint_id','duration_rule_id','recurring_fine_rule_id','max_fine_rule_id')
346     class Meta:
347         db_table = 'circ_matrix_ruleset'
348         ordering = ['matchpoint_id']
349         verbose_name = _('Circ Matrix Rule Set')
350     def __str__(self):
351         return _("Duration: %(dur)s, Recurring Fine: %(rfine)s, Max Fine: %(mfine)s") % {
352             'dur':self.duration_rule_id, 'rfine':self.recurring_fine_rule_id, 'mfine':self.max_fine_rule_id}
353
354 class RuleMaxFine(models.Model):
355     name = models.CharField(maxlength=CHAR_MAXLEN)
356     amount = models.FloatField(max_digits=6, decimal_places=2)
357     class Admin:
358         search_fields = ['name']
359         list_display = ('name','amount')
360     class Meta:
361         db_table = 'rule_max_fine'
362         ordering = ['name']
363         verbose_name = _('Circ Max Fine Rule')
364     def __str__(self):
365         return self.name
366
367 class RuleRecurringFine(models.Model):
368     name = models.CharField(maxlength=CHAR_MAXLEN)
369     high = models.FloatField(max_digits=6, decimal_places=2)
370     normal = models.FloatField(max_digits=6, decimal_places=2)
371     low = models.FloatField(max_digits=6, decimal_places=2)
372     class Admin:
373         search_fields = ['name']
374         list_display = ('name','high', 'normal', 'low')
375     class Meta:
376         db_table = 'rule_recuring_fine'
377         ordering = ['name']
378         verbose_name = 'Circ Recurring Fine Rule'
379     def __str__(self):
380         return self.name
381
382 class IdentificationType(models.Model):
383     name = models.CharField(maxlength=CHAR_MAXLEN)
384     class Admin:
385         search_fields = ['name']
386     class Meta:
387         db_table = 'identification_type'
388         ordering = ['name']
389         verbose_name = _('Identification Type')
390     def __str__(self):
391         return self.name
392
393
394 class RuleAgeHoldProtect(models.Model):
395     name = models.CharField(maxlength=CHAR_MAXLEN)
396     age = models.CharField(blank=True, maxlength=100, help_text=INTERVAL_HELP_TEXT)
397     prox = models.IntegerField()
398     class Admin:
399         search_fields = ['name']
400     class Meta:
401         db_table = 'rule_age_hold_protect'
402         ordering = ['name']
403         verbose_name = _('Hold Age Protection Rule')
404     def __str__(self):
405         return self.name
406
407
408
409 class MetabibField(models.Model):
410     field_class_choices = (
411         ('title', 'Title'),
412         ('author', 'Author'),
413         ('subject', 'Subject'),
414         ('series', 'Series'),
415         ('keyword', 'Keyword'),
416     )
417     field_class = models.CharField(maxlength=CHAR_MAXLEN, choices=field_class_choices, null=False, blank=False)
418     name = models.CharField(maxlength=CHAR_MAXLEN, null=False, blank=False)
419     xpath = models.TextField(null=False, blank=False)
420     weight = models.IntegerField(null=False, blank=False)
421     format_id = models.ForeignKey('XmlTransform', db_column='format')
422     class Admin:
423         search_fields = ['name', 'field_class', 'format_id']
424         list_display = ('field_class', 'name', 'format_id')
425     class Meta:
426         db_table = 'metabib_field'
427         ordering = ['field_class', 'name']
428         verbose_name = _('Metabib Field')
429     def __str__(self):
430         return self.name
431
432
433 class CopyStatus(models.Model):
434     name = models.CharField(maxlength=CHAR_MAXLEN)
435     holdable = models.BooleanField()
436     class Admin:
437         search_fields = ['name']
438         list_display = ('name', 'holdable')
439     class Meta:
440         db_table = 'copy_status'
441         ordering = ['name']
442         verbose_name= _('Copy Status')
443         verbose_name_plural= _('Copy Statuses')
444     def __str__(self):
445         return self.name
446
447
448 class AudienceMap(models.Model):
449     code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
450     value = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
451     description = models.CharField(maxlength=CHAR_MAXLEN)
452     class Admin:
453         search_fields = ['code', 'value', 'description']
454         list_display = ('code', 'value', 'description')
455     class Meta:
456         db_table = 'audience_map'
457         ordering = ['code']
458         verbose_name = _('Audience Map')
459     def __str__(self):
460         return self.code
461
462
463 class BibSource(models.Model):
464     quality = models.IntegerField()
465     source = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
466     transcendant = models.BooleanField()
467     class Admin:
468         search_fields = ['source']
469         list_display = ('source', 'quality', 'transcendant')
470     class Meta:
471         db_table = 'bib_source'
472         ordering = ['source']
473         verbose_name = _('Bib Source')
474     def __str__(self):
475         return self.source
476
477 class ItemFormMap(models.Model):
478     code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
479     value = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
480     class Admin:
481         search_fields = ['code', 'value']
482         list_display = ('code', 'value')
483     class Meta:
484         db_table = 'item_form_map'
485         ordering = ['code']
486         verbose_name = _('Item Form Map')
487     def __str__(self):
488         return self.code
489
490 class ItemTypeMap(models.Model):
491     code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
492     value = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
493     class Admin:
494         search_fields = ['code', 'value']
495         list_display = ('code', 'value')
496     class Meta:
497         db_table = 'item_type_map'
498         ordering = ['code']
499         verbose_name = _('Item Type Map')
500     def __str__(self):
501         return self.code
502
503
504
505 class LanguageMap(models.Model):
506     code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
507     value = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
508     class Admin:
509         search_fields = ['code', 'value']
510         list_display = ('code', 'value')
511     class Meta:
512         db_table = 'language_map'
513         ordering = ['code']
514         verbose_name = _('Language Map')
515     def __str__(self):
516         return self.code
517
518
519 class LitFormMap(models.Model):
520     code = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
521     value = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
522     description = models.CharField(maxlength=CHAR_MAXLEN)
523     class Admin:
524         search_fields = ['code', 'value', 'description']
525         list_display = ('code', 'value', 'description')
526     class Meta:
527         db_table = 'lit_form_map'
528         ordering = ['code']
529         verbose_name = _('Lit Form Map')
530     def __str__(self):
531         return self.code
532
533 class NetAccessLevel(models.Model):
534     name = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
535     class Admin:
536         search_fields = ['name']
537     class Meta:
538         db_table = 'net_access_level'
539         ordering = ['name']
540         verbose_name = _('Net Access Level')
541     def __str__(self):
542         return self.name
543
544
545 class XmlTransform(models.Model):
546     name = models.CharField(maxlength=CHAR_MAXLEN, blank=False, primary_key=True)
547     namespace_uri = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
548     prefix = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
549     xslt = models.CharField(maxlength=CHAR_MAXLEN, blank=False)
550     class Admin:
551         search_fields = ['name', 'namespace_uri', 'prefix' ]
552         list_display = ('name', 'prefix', 'namespace_uri', 'xslt')
553     class Meta:
554         db_table = 'xml_transform'
555         ordering = ['name']
556         verbose_name = _('XML Transform')
557     def __str__(self):
558         return self.name
559
560
561
562
563