Mercurial > hg > savane-forge
changeset 326:f34eba406e57
More model refinement + update migration script
author | Sylvain Beucler <beuc@beuc.net> |
---|---|
date | Sat, 21 Aug 2010 15:32:09 +0200 |
parents | c193bb0a8819 |
children | cdce64340e6c |
files | doc/scripts/tracker_defsgen.py migrate_old_savane.sql savane/tracker/admin.py savane/tracker/defs.py savane/tracker/models.py |
diffstat | 5 files changed, 262 insertions(+), 216 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/scripts/tracker_defsgen.py +++ b/doc/scripts/tracker_defsgen.py @@ -52,6 +52,13 @@ for row in c.fetchall(): process_field_row(row) + +# Doc: +#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')),) + tfields = ['name','bug_field_id','group_id','use_it','show_on_add', 'show_on_add_members','place','custom_label', 'custom_description','custom_display_size', @@ -61,6 +68,8 @@ FROM bugs_field_usage JOIN bugs_field USING (bug_field_id) WHERE group_id=100""") def process_field_usage_row(row): name = row[0] + if name == 'place': + name = 'rank' for i,val in enumerate(row): if i <= 2: continue @@ -72,6 +81,19 @@ : # overlays, duplicates of bugs_field in this context continue + elif tfields[i] == 'show_on_add': + if val == 0: + defs[name] += " 'show_on_add_anonymous': 0,\n" + defs[name] += " 'show_on_add_connected': 0,\n" + elif val == 1: + defs[name] += " 'show_on_add_anonymous': 0,\n" + defs[name] += " 'show_on_add_connected': 1,\n" + elif val == 2: + defs[name] += " 'show_on_add_anonymous': 1,\n" + defs[name] += " 'show_on_add_connected': 0,\n" + elif val == 3: + defs[name] += " 'show_on_add_anonymous': 1,\n" + defs[name] += " 'show_on_add_connected': 1,\n" else: defs[name] += " " \ + "'"+tfields[i]+"'" \
--- a/migrate_old_savane.sql +++ b/migrate_old_savane.sql @@ -494,7 +494,7 @@ INSERT INTO tracker_item (tracker_id, public_bugs_id, group_id, status_id, severity, privacy, discussion_lock, - vote, spamscore, ip, category_id, submitted_by_id, assigned_to, + vote, spamscore, ip, category_id, submitted_by_id, assigned_to_id, date, summary, details, close_date, bug_group_id, resolution_id, category_version_id, platform_version_id, reproducibility_id, size_id, fix_release_id, plan_release_id, hours, component_version, @@ -533,48 +533,15 @@ FROM_UNIXTIME(IF(custom_df5<0,0,custom_df5)) FROM savane_old.bugs; -- Specify "default" differently -UPDATE tracker_item SET assigned_to=NULL WHERE submitted_by=100; -UPDATE tracker_item SET submitted_by=NULL WHERE submitted_by=100; - --- We're merging all the *_field tables, so we need to assign new ids. --- (Not needed if we merge the tracker fields definitions, because --- they are mostly identical (cf. models.py).) -CREATE TEMPORARY TABLE conv_field_ids ( - new INT auto_increment PRIMARY KEY, - tracker_id VARCHAR(7), old INT, - INDEX(tracker_id), INDEX(old)); -INSERT INTO conv_field_ids (tracker_id, old) - SELECT 'bugs', bug_field_id FROM savane_old.bugs_field - UNION SELECT 'patch', bug_field_id FROM savane_old.patch_field - UNION SELECT 'support', bug_field_id FROM savane_old.patch_field - UNION SELECT 'task', bug_field_id FROM savane_old.patch_field; - --- id <- conv_field_ids.new (duplicates in savane_old.*_field tables) --- name <- field_name --- tracker_id <- 'bugs' -TRUNCATE tracker_field; -INSERT INTO tracker_field - (id, tracker_id, name, display_type, display_size, label, - description, scope, required, empty_ok, keep_history, special, custom) - SELECT - conv_field_ids.new, 'bugs', field_name, display_type, display_size, label, - description, scope, required, empty_ok, keep_history, special, custom - FROM savane_old.bugs_field JOIN conv_field_ids - ON (bug_field_id = old AND tracker_id = 'bugs'); -INSERT INTO tracker_field - (id, tracker_id, name, display_type, display_size, label, - description, scope, required, empty_ok, keep_history, special, custom) - SELECT - conv_field_ids.new, 'patch', field_name, display_type, display_size, label, - description, scope, required, empty_ok, keep_history, special, custom - FROM savane_old.patch_field JOIN conv_field_ids - ON (bug_field_id = old AND tracker_id = 'patch'); +UPDATE tracker_item SET assigned_to_id=NULL WHERE assigned_to_id=100; +UPDATE tracker_item SET submitted_by_id=NULL WHERE submitted_by_id=100; -- Get rid of duplicates (old mysql/php/savane bug?) -- It only affected group_id=100, maybe the installation was done -- twice or something. -- Give priority to the last one. -- Need to create a real table - a temporary one has issues with being "reopened" in joins +DROP TABLE IF EXISTS temp_bugs_field_usage; CREATE TABLE temp_bugs_field_usage AS SELECT * FROM savane_old.bugs_field_usage; ALTER TABLE temp_bugs_field_usage ADD (id INT auto_increment PRIMARY KEY); DELETE FROM temp_bugs_field_usage @@ -587,20 +554,23 @@ ); -- id <- <auto> -- field_id <- bug_field_id -TRUNCATE tracker_fieldusage; -INSERT INTO tracker_fieldusage - (field_id, group_id, use_it, show_on_add, show_on_add_members, place, - custom_label, custom_description, custom_display_size, custom_empty_ok, - custom_keep_history, transition_default_auth) +-- Don't import default values, they are now defined statically in +-- tracker.defs. +TRUNCATE tracker_fieldoverlay; +INSERT INTO tracker_fieldoverlay + (group_id, field_name, use_it, show_on_add_anonymous, show_on_add_connected, show_on_add_members, rank, + label, description, display_size, empty_ok, + keep_history, transition_default_auth) SELECT - conv_field_ids.new, group_id, use_it, show_on_add, show_on_add_members, place, + group_id, field_name, use_it, IF(show_on_add<2,0,1), IF(show_on_add%2=0,0,1), show_on_add_members, place, custom_label, custom_description, custom_display_size, custom_empty_ok, IFNULL(custom_keep_history, 0), transition_default_auth - FROM temp_bugs_field_usage JOIN conv_field_ids - ON (bug_field_id = old AND tracker_id = 'bugs'); + FROM temp_bugs_field_usage JOIN savane_old.bugs_field + USING (bug_field_id) + WHERE group_id != 100; DROP TABLE temp_bugs_field_usage; -- Specify "default" differently -UPDATE tracker_fieldusage SET group_id=NULL WHERE group_id=100; +-- UPDATE tracker_fieldoverlay SET group_id=NULL WHERE group_id=100; -- Get rid of duplicates (old mysql/php/savane bug?) -- Apparently this affects 'None' values. @@ -613,17 +583,17 @@ WHERE A.bug_fv_id > B.bug_fv_id AND A.bug_field_id = B.bug_field_id AND A.group_id = B.group_id AND A.value_id = B.value_id ) AS temp - ); + ); -- id <- <auto> -- field_id <- bug_field_id TRUNCATE tracker_fieldvalue; INSERT INTO tracker_fieldvalue - (field_id, group_id, value_id, `value`, description, + (group_id, field_name, value_id, `value`, description, order_id, status, email_ad, send_all_flag) SELECT - conv_field_ids.new, group_id, value_id, `value`, description, + group_id, field_name, value_id, `value`, savane_old.bugs_field_value.description, order_id, status, email_ad, send_all_flag - FROM savane_old.bugs_field_value JOIN conv_field_ids - ON (bug_field_id = old AND tracker_id = 'bugs'); + FROM savane_old.bugs_field_value JOIN savane_old.bugs_field + USING (bug_field_id); -- Specify "default" differently UPDATE tracker_fieldvalue SET group_id=NULL WHERE group_id=100;
--- a/savane/tracker/admin.py +++ b/savane/tracker/admin.py @@ -24,26 +24,13 @@ #class TrackerAdmin(admin.ModelAdmin): # list_display = ('name',) -class FieldUsageInline(admin.TabularInline): - model = FieldUsage - raw_id_fields = ('group',) -class FieldAdmin(admin.ModelAdmin): - search_fields = ('name', 'label', 'description', ) - ordering = ('tracker', 'name', ) - list_display = ('id', 'tracker', 'scope', 'name', 'label', 'display_type', 'display_size', - 'required', 'empty_ok', 'keep_history', 'special', 'custom', ) - list_display_links = ('id', 'name', 'label') - list_filter = ('tracker', 'display_type', 'scope', - 'required', 'empty_ok', 'keep_history', 'special', 'custom', ) - inlines = ( FieldUsageInline, ) - -class FieldUsageAdmin(admin.ModelAdmin): - search_fields = ('group', 'custom_label', 'custom_description', ) - ordering = ('group', 'field',) - list_display = ('id', 'group', 'field', 'use_it', 'place', ) +class FieldOverlayAdmin(admin.ModelAdmin): + search_fields = ('group', 'label', 'description', ) + ordering = ('group', 'field_name',) + list_display = ('id', 'group', 'field_name', 'use_it', 'rank', ) list_display_links = ('id',) - list_filter = ('use_it', 'show_on_add', 'show_on_add_members', 'custom_empty_ok', 'custom_keep_history',) + list_filter = ('use_it', 'show_on_add_anonymous', 'show_on_add_connected', 'show_on_add_members', + 'empty_ok', 'keep_history',) raw_id_fields = ('group',) -admin.site.register(Field, FieldAdmin) -admin.site.register(FieldUsage, FieldUsageAdmin) +admin.site.register(FieldOverlay, FieldOverlayAdmin)
--- a/savane/tracker/defs.py +++ b/savane/tracker/defs.py @@ -16,6 +16,53 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +""" +The Field definition cannot be changed, so it's been made static +instead of stored in the database. + +Here's the previous model definition. See also FieldUsage, which is +still used for non-default (i.e. override) values. + + class Meta: + unique_together = (('tracker', 'name'),) + verbose_name = _("field") + verbose_name_plural = _("fields") + + DISPLAY_TYPE_CHOICES = (('DF', _('date field')), + ('SB', _('select box')), + ('TA', _('text area')), + ('TF', _('text field')),) + SCOPE_CHOICES = (('S', _('system')), # user cannot modify related FieldValue's (TF) + ('P', _('project')),) # user can modify related FieldValue's (TF) + + tracker = models.ForeignKey('Tracker') + 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) + # DF: unused + # SB: unused + # TA: cols/rows + # TF: visible_length/max_length + label = models.CharField(max_length=255) + description = models.TextField() + + # Field values can be changed (if TF) + scope = models.CharField(max_length=1, choices=SCOPE_CHOICES) + # Field cannot be hidden (but can be made optional) + required = models.BooleanField(help_text=_("field cannot be disabled in configuration")) + # Default value (fields can always override this except for 'summary' and 'details', cf. 'special') + empty_ok = models.CharField(max_length=1, choices=EMPTY_OK_CHOICES, + default='0') + # Default value + keep_history = models.BooleanField() + # Field cannot be made optional (displayed unless 'bug_id' and 'group_id') + # Also, field are not displayed (filled by the system) - except for 'summary', 'comment_type' and 'details' + # (consequently, they cannot be customized in any way, except for 'summary' and 'details' where you can only customize the display size) + special = models.BooleanField() + # Field may change label and description + custom = models.BooleanField(help_text=_("let the user change the label and description")) +""" + from django.utils.translation import ugettext, ugettext_lazy as _ fields = {} @@ -34,7 +81,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 10, 'transition_default_auth': 'A', @@ -52,7 +100,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 30, 'transition_default_auth': 'A', @@ -70,7 +119,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 20, 'transition_default_auth': 'A', @@ -88,7 +138,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40, 'transition_default_auth': 'A', @@ -106,7 +157,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50, 'transition_default_auth': 'A', @@ -124,7 +176,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 600, 'transition_default_auth': 'A', @@ -142,7 +195,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 200, 'transition_default_auth': 'A', @@ -160,7 +214,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 100, 'transition_default_auth': 'A', @@ -178,7 +233,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 500, 'transition_default_auth': 'A', @@ -196,7 +252,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 700000, 'transition_default_auth': 'A', @@ -214,7 +271,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 700001, 'transition_default_auth': 'A', @@ -232,7 +290,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 300, 'transition_default_auth': 'A', @@ -250,7 +309,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 400, 'transition_default_auth': 'A', @@ -268,7 +328,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 402, 'transition_default_auth': 'A', @@ -286,7 +347,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 405, 'transition_default_auth': 'A', @@ -304,7 +366,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1000, 'transition_default_auth': 'A', @@ -322,7 +385,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1100, 'transition_default_auth': 'A', @@ -340,7 +404,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1200, 'transition_default_auth': 'A', @@ -358,7 +423,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1300, 'transition_default_auth': 'A', @@ -376,7 +442,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1400, 'transition_default_auth': 'A', @@ -394,7 +461,8 @@ 'special': 1, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1500, 'transition_default_auth': 'A', @@ -412,7 +480,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1700, 'transition_default_auth': 'A', @@ -430,7 +499,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1600, 'transition_default_auth': 'A', @@ -448,7 +518,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1800, 'transition_default_auth': 'A', @@ -466,7 +537,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 1900, 'transition_default_auth': 'A', @@ -484,7 +556,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 2000, 'transition_default_auth': 'A', @@ -502,7 +575,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 200, 'transition_default_auth': 'A', @@ -520,7 +594,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 3000, 'transition_default_auth': 'A', @@ -538,7 +613,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 800, 'transition_default_auth': 'A', @@ -556,7 +632,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 800, 'transition_default_auth': 'A', @@ -574,7 +651,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 550, 'transition_default_auth': 'A', @@ -592,7 +670,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 2, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 1, 'show_on_add_members': 0, 'place': 560, 'transition_default_auth': 'A', @@ -610,7 +689,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 570, 'transition_default_auth': 'A', @@ -628,7 +708,8 @@ 'special': 0, 'custom': 0, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 500, 'transition_default_auth': 'A', @@ -646,7 +727,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30000, 'transition_default_auth': 'A', @@ -664,7 +746,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30100, 'transition_default_auth': 'A', @@ -682,7 +765,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30200, 'transition_default_auth': 'A', @@ -700,7 +784,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30300, 'transition_default_auth': 'A', @@ -718,7 +803,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30400, 'transition_default_auth': 'A', @@ -736,7 +822,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30500, 'transition_default_auth': 'A', @@ -754,7 +841,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30600, 'transition_default_auth': 'A', @@ -772,7 +860,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30700, 'transition_default_auth': 'A', @@ -790,7 +879,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30800, 'transition_default_auth': 'A', @@ -808,7 +898,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 30900, 'transition_default_auth': 'A', @@ -826,7 +917,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40000, 'transition_default_auth': 'A', @@ -844,7 +936,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40100, 'transition_default_auth': 'A', @@ -862,7 +955,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40200, 'transition_default_auth': 'A', @@ -880,7 +974,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40300, 'transition_default_auth': 'A', @@ -898,7 +993,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40400, 'transition_default_auth': 'A', @@ -916,7 +1012,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40500, 'transition_default_auth': 'A', @@ -934,7 +1031,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40600, 'transition_default_auth': 'A', @@ -952,7 +1050,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40700, 'transition_default_auth': 'A', @@ -970,7 +1069,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40800, 'transition_default_auth': 'A', @@ -988,7 +1088,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 40900, 'transition_default_auth': 'A', @@ -1006,7 +1107,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50000, 'transition_default_auth': 'A', @@ -1024,7 +1126,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50100, 'transition_default_auth': 'A', @@ -1042,7 +1145,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50200, 'transition_default_auth': 'A', @@ -1060,7 +1164,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50300, 'transition_default_auth': 'A', @@ -1078,7 +1183,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50400, 'transition_default_auth': 'A', @@ -1096,7 +1202,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50500, 'transition_default_auth': 'A', @@ -1114,7 +1221,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50600, 'transition_default_auth': 'A', @@ -1132,7 +1240,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50700, 'transition_default_auth': 'A', @@ -1150,7 +1259,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50800, 'transition_default_auth': 'A', @@ -1168,7 +1278,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 50900, 'transition_default_auth': 'A', @@ -1186,7 +1297,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 60000, 'transition_default_auth': 'A', @@ -1204,7 +1316,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 60100, 'transition_default_auth': 'A', @@ -1222,7 +1335,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 60200, 'transition_default_auth': 'A', @@ -1240,7 +1354,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 60300, 'transition_default_auth': 'A', @@ -1258,7 +1373,8 @@ 'special': 0, 'custom': 1, 'use_it': 0, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 60400, 'transition_default_auth': 'A', @@ -1276,7 +1392,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 0, + 'show_on_add_connected': 0, + 'show_on_add_anonymous': 0, 'show_on_add_members': 0, 'place': 800, 'transition_default_auth': 'A', @@ -1294,7 +1411,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 56, 'transition_default_auth': 'A', @@ -1312,7 +1430,8 @@ 'special': 0, 'custom': 0, 'use_it': 1, - 'show_on_add': 1, + 'show_on_add_connected': 1, + 'show_on_add_anonymous': 0, 'show_on_add_members': 1, 'place': 55, 'transition_default_auth': 'A',
--- a/savane/tracker/models.py +++ b/savane/tracker/models.py @@ -137,89 +137,37 @@ #class SquadPermission(models.Model): pass - -class Field(models.Model): - """ - """ - class Meta: - unique_together = (('tracker', 'name'),) - verbose_name = _("field") - verbose_name_plural = _("fields") - - DISPLAY_TYPE_CHOICES = (('DF', _('date field')), - ('SB', _('select box')), - ('TA', _('text area')), - ('TF', _('text field')),) - SCOPE_CHOICES = (('S', _('system')), # user cannot modify related FieldValue's (TF) - ('P', _('project')),) # user can modify related FieldValue's (TF) - EMPTY_OK_CHOICES = (('0', _('mandatory only if it was presented to the original submitter')), - ('1', _('optional (empty values are accepted)')), - ('3', _('mandatory')),) - - tracker = models.ForeignKey('Tracker') - 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) - # DF: unused - # SB: unused - # TA: cols/rows - # TF: visible_length/max_length - label = models.CharField(max_length=255) - description = models.TextField() - - # Field values can be changed (if TF) - scope = models.CharField(max_length=1, choices=SCOPE_CHOICES) - # Field cannot be hidden (but can be made optional) - required = models.BooleanField(help_text=_("field cannot be disabled in configuration")) - # Default value (fields can always override this except for 'summary' and 'details', cf. 'special') - empty_ok = models.CharField(max_length=1, choices=EMPTY_OK_CHOICES, - default='0') - # Default value - keep_history = models.BooleanField() - # Field cannot be made optional (displayed unless 'bug_id' and 'group_id') - # Also, field are not displayed (filled by the system) - except for 'summary', 'comment_type' and 'details' - # (consequently, they cannot be customized in any way, except for 'summary' and 'details' where you can only customize the display size) - special = models.BooleanField() - # Field may change label and description - custom = models.BooleanField(help_text=_("let the user change the label and description")) - - def __unicode__(self): - return "%s.%s" % (self.tracker_id, self.name) - class FieldOverlay(models.Model): """ Per-group tracker item definition override """ class Meta: - unique_together = (('field', 'group'),) + unique_together = (('group', 'field_name'),) verbose_name = _("field usage") verbose_name_plural = _("field usages") + EMPTY_OK_CHOICES = (('0', _('mandatory only if it was presented to the original submitter')), + ('1', _('optional (empty values are accepted)')), + ('3', _('mandatory')),) 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')),) - field = models.ForeignKey('Field') - group = models.ForeignKey(auth_models.Group, blank=True, null=True, help_text=_("NULL == default")) + group = models.ForeignKey(auth_models.Group) + field_name = models.CharField(max_length=32) # If not Field.required: 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")) + # When posting a new item: + show_on_add_anonymous = models.NullBooleanField(_("show to anonymous users"), blank=True, null=True) + show_on_add_connected = models.NullBooleanField(_("show to connected users"), blank=True, null=True) + show_on_add_members = models.NullBooleanField(_("show to project members"), blank=True, null=True) # Can always be changed (expect for special 'summary' and 'details') - custom_empty_ok = models.CharField(max_length=1, choices=Field.EMPTY_OK_CHOICES, + empty_ok = models.CharField(max_length=1, choices=EMPTY_OK_CHOICES, default='0', blank=True, null=True) # Can always be changed - place = models.IntegerField(help_text=_("display rank")) # new:rank + rank = models.IntegerField(help_text=_("display rank")) # Specific to SB # Can always be changed @@ -227,29 +175,29 @@ # Specific to TA and TF # Works for both custom and non-custom fields - custom_display_size = models.CharField(max_length=255, blank=True, null=True) + display_size = models.CharField(max_length=255, blank=True, null=True) # The default value is in Field.display_size # rather than FieldUsage(group_id=100).custom_display_size # If !Field.special - custom_keep_history = models.BooleanField(_("keep field value changes in history")) + keep_history = models.BooleanField(_("keep field value changes in history")) # If Field.custom # Specific (bad!) fields for custom fields (if Field.custom is True): - custom_label = models.CharField(max_length=255, blank=True, null=True) - custom_description = models.CharField(max_length=255, blank=True, null=True) + label = models.CharField(max_length=255, blank=True, null=True) + description = models.CharField(max_length=255, blank=True, null=True) class FieldValue(models.Model): """ Per-group tracker select box values override """ class Meta: - unique_together = (('field', 'group', 'value_id'),) + unique_together = (('group', 'field_name', 'value_id'),) STATUS_CHOICES = (('A', _('active')), ('H', _('hidden')), # mask previously-active or system fields ('P', _('permanent')),) # status cannot be modified, always visible - field = models.ForeignKey('Field') - group = models.ForeignKey(auth_models.Group, blank=True, null=True, help_text=_("NULL == default")) + group = models.ForeignKey(auth_models.Group) + field_name = models.CharField(max_length=32) value_id = models.IntegerField(db_index=True) # group_specific value identifier # It's not a duplicate of 'id', as it's the value referenced by # Item fields, and the configuration of that value can be @@ -299,7 +247,7 @@ group = models.ForeignKey(auth_models.Group) spamscore = models.IntegerField(default=0) ip = models.IPAddressField(blank=True, null=True) - submitted_by = models.ForeignKey(auth_models.User, blank=True, null=True) + submitted_by = models.ForeignKey(auth_models.User, blank=True, null=True, related_name='items_submitted') date = models.DateTimeField(default=datetime.date.today) close_date = models.DateTimeField(blank=True, null=True) @@ -329,7 +277,7 @@ discussion_lock = models.IntegerField(default=0) vote = models.IntegerField(default=0) category_id = models.IntegerField(default=100) - assigned_to = models.IntegerField(blank=True, null=True) + assigned_to = models.ForeignKey(auth_models.User, related_name='items_assigned', blank=True, null=True) # - other fields status_id = models.IntegerField(default=100, verbose_name=_("open/closed"))