Mercurial > hg > savane-forge
changeset 157:38e55e62349e
More on trackers data structure
author | Sylvain Beucler <beuc@beuc.net> |
---|---|
date | Sun, 14 Mar 2010 13:36:25 +0100 |
parents | b8f224f37ddc |
children | a861ae5f73e5 |
files | savane/tracker/models.py |
diffstat | 1 files changed, 149 insertions(+), 98 deletions(-) [+] |
line wrap: on
line diff
--- a/savane/tracker/models.py +++ b/savane/tracker/models.py @@ -21,122 +21,173 @@ name = models.CharField(max_length=255, db_index=True) display_type = models.CharField(max_length=255, choices=DISPLAY_TYPE_CHOICES) display_size = models.CharField(max_length=255) + # new: + # display_size_min = models.IntegerField(blank=True, null=True) + # display_size_max = models.IntegerField(blank=True, null=True) label = models.CharField(max_length=255) description = models.TextField() scope = models.CharField(max_length=1, choices=SCOPE_CHOICES) required = models.BooleanField() empty_ok = models.BooleanField() keep_history = models.BooleanField() - special = models.BooleanField() # TODO: ??? - custom = models.BooleanField() # TODO: ??? + special = models.BooleanField(help_text="field is not entered by the user but by the system") + custom = models.BooleanField(help_text="let the user change the label and description") + +class FieldUsage(models.Model): + TRANSITION_DEFAULT_AUTH_CHOICES = (('', 'undefined'), + ('A', 'allowed'), + ('F', 'forbidden'),) + SHOW_ON_ADD_CHOICES = (('0', 'no'), + ('1', 'show to logged in users'), + ('2', 'show to anonymous users'), + ('3', 'show to both logged in and anonymous users'),) + CUSTOM_EMPTY_OK_CHOICES = (('0', 'mandatory only if it was presented to the original submitter'), + ('1', 'optional (empty values are accepted)'), + ('3', 'mandatory'),) + group = models.ForeignKey('auth.Group') + use_it = models.BooleanField("used") + show_on_add = models.CharField(max_length=1, choices=SHOW_ON_ADD_CHOICES, + default='0', blank=True, null=True) + # new: + # show_on_add_logged_in = models.BooleanField("show to logged in users") + # show_on_add_anonymous = models.BooleanField("show to anonymous users") + show_on_add_members = models.BooleanField("show to project members") + place = models.IntegerField() # new:rank + transition_default_auth = models.CharField(max_lenth=1, choices=TRANSITION_DEFAULT_AUTH, default='A') + + # Specific (bad!) fields for custom fields: + custom_label = models.CharField(max_length=255, blank=True, null=True) + custom_description = models.CharField(max_length=255, blank=True, null=True) + custom_display_size = models.CharField(max_length=255, blank=True, null=True) + # new: + # custom_display_size_min = models.IntegerField(blank=True, null=True) + # custom_display_size_max = models.IntegerField(blank=True, null=True) + custom_empty_ok = models.CharField(max_length=1, choices=CUSTOM_EMPTY_OK_CHOICES, + default='0', blank=True, null=True) + custom_keep_history = models.BooleanField("keep field value changes in history") class FieldValue(models.Model): """ - Values for select-box (SB) fields + Choice for a select-box (SB) field """ + class Meta: + unique_together = (('bug_field', 'group', 'value_id'),) + STATUS_CHOICES = (('A', 'active'), ('H', 'hidden'), # mask previously-active or system fields ('P', 'permanent'),) # status cannot be modified, always visible bug_field = models.ForeignKey('Field') - group = models.ForeignKey(auth.Group, null=True) - # => NULL if value is system-wide; - # but not a duplicate of status='P': 114 group_id's for status=H at SV - value_id = models.IntegerField(db_index=True) # TODO: ??? - value = models.CharField(max_length=255) + group = models.ForeignKey('auth.Group') + value_id = models.IntegerField(db_index=True) # group_specific value identifier + # somehow duplicate of 'id', but might be useful when moving a bug to another group + value = models.CharField(max_length=255) # label description = models.TextField() - rank = models.IntegerField() # old:order_id + order_id = models.IntegerField() # new:rank status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='A', db_index=True) # Field category: specific (bad!) field for e-mail notifications - email_ad = models.TextField(help_text="comma-separated list of e-mail addresses") - send_all_flag = models.BooleanField(default=True) - -class FieldUsage(models.Model): - group = models.ForeignKey(auth.Group) - #`use_it` int(11) NOT NULL default '0', - #`show_on_add` int(11) NOT NULL default '0', - #`show_on_add_members` int(11) NOT NULL default '0', - #`place` int(11) NOT NULL default '0', - #`custom_label` varchar(255) default NULL, - #`custom_description` varchar(255) default NULL, - #`custom_display_size` varchar(255) default NULL, - #`custom_empty_ok` int(11) default NULL, - #`custom_keep_history` int(11) default NULL, - #`transition_default_auth` char(1) NOT NULL default 'A', - + email_ad = models.TextField(help_text="comma-separated list of e-mail addresses" + + " to notify when an item is created or modified" + + " in this category") + send_all_flag = models.BooleanField("send on all updates", default=True) class Item(models.Model): - pass - #group = models.ForeignKey(auth.Group) - #`status_id` int(11) NOT NULL default '100', - #`severity` int(11) NOT NULL default '5', - #`privacy` int(2) NOT NULL default '1', - #`discussion_lock` int(1) default '0', - #`vote` int(11) NOT NULL default '0', - #`spamscore` int(2) default '0', - #`ip` varchar(15) default NULL, - #`category_id` int(11) NOT NULL default '100', - #`submitted_by` int(11) NOT NULL default '100', - #`assigned_to` int(11) NOT NULL default '100', - #`date` int(11) NOT NULL default '0', - #`summary` text, - #`details` text, - #`close_date` int(11) default NULL, - #`bug_group_id` int(11) NOT NULL default '100', - #`resolution_id` int(11) NOT NULL default '100', - #`category_version_id` int(11) NOT NULL default '100', - #`platform_version_id` int(11) NOT NULL default '100', - #`reproducibility_id` int(11) NOT NULL default '100', - #`size_id` int(11) NOT NULL default '100', - #`fix_release_id` int(11) NOT NULL default '100', - #`plan_release_id` int(11) NOT NULL default '100', - #`hours` float(10,2) NOT NULL default '0.00', - #`component_version` varchar(255) NOT NULL default '', - #`fix_release` varchar(255) NOT NULL default '', - #`plan_release` varchar(255) NOT NULL default '', - #`priority` int(11) NOT NULL default '5', - #`planned_starting_date` int(11) default NULL, - #`planned_close_date` int(11) default NULL, - #`percent_complete` int(11) NOT NULL default '1', - #`keywords` varchar(255) NOT NULL default '', - #`release_id` int(11) NOT NULL default '100', - #`release` varchar(255) NOT NULL default '', - #`originator_name` varchar(255) NOT NULL default '', - #`originator_email` varchar(255) NOT NULL default '', - #`originator_phone` varchar(255) NOT NULL default '', - #`custom_tf1` varchar(255) NOT NULL default '', - #`custom_tf2` varchar(255) NOT NULL default '', - #`custom_tf3` varchar(255) NOT NULL default '', - #`custom_tf4` varchar(255) NOT NULL default '', - #`custom_tf5` varchar(255) NOT NULL default '', - #`custom_tf6` varchar(255) NOT NULL default '', - #`custom_tf7` varchar(255) NOT NULL default '', - #`custom_tf8` varchar(255) NOT NULL default '', - #`custom_tf9` varchar(255) NOT NULL default '', - #`custom_tf10` varchar(255) NOT NULL default '', - #`custom_ta1` text NOT NULL, - #`custom_ta2` text NOT NULL, - #`custom_ta3` text NOT NULL, - #`custom_ta4` text NOT NULL, - #`custom_ta5` text NOT NULL, - #`custom_ta6` text NOT NULL, - #`custom_ta7` text NOT NULL, - #`custom_ta8` text NOT NULL, - #`custom_ta9` text NOT NULL, - #`custom_ta10` text NOT NULL, - #`custom_sb1` int(11) NOT NULL default '100', - #`custom_sb2` int(11) NOT NULL default '100', - #`custom_sb3` int(11) NOT NULL default '100', - #`custom_sb4` int(11) NOT NULL default '100', - #`custom_sb5` int(11) NOT NULL default '100', - #`custom_sb6` int(11) NOT NULL default '100', - #`custom_sb7` int(11) NOT NULL default '100', - #`custom_sb8` int(11) NOT NULL default '100', - #`custom_sb9` int(11) NOT NULL default '100', - #`custom_sb10` int(11) NOT NULL default '100', - #`custom_df1` int(11) NOT NULL default '0', - #`custom_df2` int(11) NOT NULL default '0', - #`custom_df3` int(11) NOT NULL default '0', - #`custom_df4` int(11) NOT NULL default '0', - #`custom_df5` int(11) NOT NULL default '0', + # TODO: default '100' (aka 'nobody' or 'None', depending on + # fields) -> change to NULL? + + group = models.ForeignKey('auth.Group') + spamscore = models.IntegerField(default=0) + ip = IPAddressField(blank=True, null=True) + submitted_by = models.ForeignKey('auth.User', default=100) + date = models.DateTimeField() + close_date = models.DateTimeField(blank=True, null=True) + + ## + # Field values + ## + # Note: For select boxes, FK should be limited to same group, and + # to a specific field each e.g.: + # severity = models.ForeignKey('FieldValue', to_field='value_id', default=5) + # + constraint(same group) + constraint(field_name='severity') + # To avoid unnecessary burden, let's drop the above incomplete ForeignKey + + # More generally one can wonder if this should be moved to a M2M + # bug<->field table; but after we're done with the migration from + # the previous database :) + + # - fields with hard-coded processing + summary = models.TextField() + details = models.TextField() + privacy = models.IntegerField(default=5) + discussion_lock = models.IntegerField(default=0) + vote = models.IntegerField(default=0) + category_id = models.IntegerField(default=100) + assigned_to = models.IntegerField(default=100) + + # - other fields + status_id = models.IntegerField(default=100, verbose_name="open/closed") + resolution_id = models.IntegerField(default=100) + severity = models.IntegerField(default=5) + planned_starting_date = models.DateTimeField(blank=True, null=True) + planned_close_date = models.DateTimeField(blank=True, null=True) + percent_complete = models.IntegerField(default=1) # SB + reproducibility_id = models.IntegerField(default=100) + bug_group_id = models.IntegerField(default=100, verbose_name="item group") + keywords = models.CharField(max_length=255) + hours = models.FloatField(default=0.0) + priority = models.IntegerField(default=5) + size_id = models.IntegerField(default=100) + platform_version_id = models.IntegerField(default=100) + fix_release = models.CharField(max_length=255) + fix_release_id = models.IntegerField(default=100) + plan_release = models.CharField(max_length=255) + plan_release_id = models.IntegerField(default=100) + release = models.CharField(max_length=255) + release_id = models.IntegerField(default=100) + category_version_id = models.IntegerField(default=100) + component_version = models.CharField(max_length=255) + originator_name = models.CharField(max_length=255) + originator_email = models.CharField(max_length=255) + originator_phone = models.CharField(max_length=255) + + # - fields dedicated to user customization + custom_tf1 = models.CharField(max_length=255) + custom_tf2 = models.CharField(max_length=255) + custom_tf3 = models.CharField(max_length=255) + custom_tf4 = models.CharField(max_length=255) + custom_tf5 = models.CharField(max_length=255) + custom_tf5 = models.CharField(max_length=255) + custom_tf6 = models.CharField(max_length=255) + custom_tf7 = models.CharField(max_length=255) + custom_tf8 = models.CharField(max_length=255) + custom_tf9 = models.CharField(max_length=255) + custom_tf10 = models.CharField(max_length=255) + + custom_ta1 = models.TextField() + custom_ta2 = models.TextField() + custom_ta3 = models.TextField() + custom_ta4 = models.TextField() + custom_ta5 = models.TextField() + custom_ta6 = models.TextField() + custom_ta7 = models.TextField() + custom_ta8 = models.TextField() + custom_ta9 = models.TextField() + custom_ta10 = models.TextField() + + custom_sb1 = models.IntegerField(default=100) + custom_sb2 = models.IntegerField(default=100) + custom_sb3 = models.IntegerField(default=100) + custom_sb4 = models.IntegerField(default=100) + custom_sb5 = models.IntegerField(default=100) + custom_sb6 = models.IntegerField(default=100) + custom_sb7 = models.IntegerField(default=100) + custom_sb8 = models.IntegerField(default=100) + custom_sb9 = models.IntegerField(default=100) + custom_sb10 = models.IntegerField(default=100) + + custom_df1 = models.DateTimeField() + custom_df2 = models.DateTimeField() + custom_df3 = models.DateTimeField() + custom_df4 = models.DateTimeField() + custom_df5 = models.DateTimeField()