# HG changeset patch # User Daniel Diniz # Date 1246296555 -7200 # Node ID c58a7ea6c12630e5e1d7cf4c1deffc1d42c3c37c # Parent 596fad6da0e15925b83840bfb206b2bd5ccc55e1 Added SurveyContentSchema to improve readability for the survey helper. Reviewed by: Lennard de Rijk diff -r 596fad6da0e1 -r c58a7ea6c126 app/soc/views/helper/surveys.py --- a/app/soc/views/helper/surveys.py Mon Jun 29 16:51:48 2009 +0200 +++ b/app/soc/views/helper/surveys.py Mon Jun 29 19:29:15 2009 +0200 @@ -66,23 +66,21 @@ """ self.kwargs = kwargs - self.survey_content = self.kwargs.get('survey_content', None) - self.this_user = self.kwargs.get('this_user', None) - self.project = self.kwargs.get('project', None) - self.survey_record = self.kwargs.get('survey_record', None) + self.survey_content = self.kwargs.pop('survey_content', None) + self.this_user = self.kwargs.pop('this_user', None) + self.project = self.kwargs.pop('project', None) + self.survey_record = self.kwargs.pop('survey_record', None) + + self.read_only = self.kwargs.pop('read_only', None) + self.editing = self.kwargs.pop('editing', None) - del self.kwargs['survey_content'] - del self.kwargs['this_user'] - del self.kwargs['project'] - del self.kwargs['survey_record'] - - self.read_only = self.kwargs.get('read_only', None) - if 'read_only' in self.kwargs: - del self.kwargs['read_only'] - - self.editing = self.kwargs.get('editing', None) - if 'editing' in self.kwargs: - del self.kwargs['editing'] + self.fields_map = dict( + long_answer=self.addLongField, + short_answer=self.addShortField, + selection=self.addSingleField, + pick_multi=self.addMultiField, + pick_quant=self.addQuantField, + ) super(SurveyForm, self).__init__(*args, **self.kwargs) @@ -125,31 +123,13 @@ # use prompts set by survey creator value = getattr(self.survey_content, field) - if field not in schema: - logging.error('field %s not found in schema %s' % - (field, str(schema) ) ) - continue - elif 'question' in schema[field]: - label = schema[field].get('question', None) or field - else: - label = field + label = schema.getLabel(field) + if label is None: + continue # dispatch to field-specific methods - if schema[field]["type"] == "long_answer": - self.addLongField(field, value, extra_attrs, label=label, - comment=comment) - elif schema[field]["type"] == "short_answer": - self.addShortField(field, value, extra_attrs, label=label, - comment=comment) - elif schema[field]["type"] == "selection": - self.addSingleField(field, value, extra_attrs, schema, label=label, - comment=comment) - elif schema[field]["type"] == "pick_multi": - self.addMultiField(field, value, extra_attrs, schema, label=label, - comment=comment) - elif schema[field]["type"] == "pick_quant": - self.addQuantField(field, value, extra_attrs, schema, label=label, - comment=comment) + addField = self.fields_map[schema.getType(field)] + addField(field, value, extra_attrs, schema, label=label, comment=comment) return self.insertFields() @@ -169,7 +149,7 @@ self.survey_fields[property]) return self.fields - def addLongField(self, field, value, attrs, req=False, label='', tip='', + def addLongField(self, field, value, attrs, schema, req=False, label='', tip='', comment=''): """Add a long answer fields to this form. @@ -177,10 +157,11 @@ field: the current field value: the initial value for this field attrs: additional attributes for field + schema: schema for survey req: required bool label: label for field tip: tooltip text for field - comment: initial comment value for field + comment: initial comment value for field """ widget = widgets.Textarea(attrs=attrs) @@ -190,15 +171,11 @@ question = CharField(help_text=tip, required=req, label=label, widget=widget, initial=value) - self.survey_fields[field] = question - if not self.editing: - widget = widgets.Textarea(attrs=attrs) - comment = CharField(help_text=tip, required=False, label='Comments', - widget=widget, initial=comment) - self.survey_fields['comment_for_' + field] = comment + self.survey_fields[field] = question + self.addCommentField(field, comment, attrs, tip) - def addShortField(self, field, value, attrs, req=False, label='', tip='', + def addShortField(self, field, value, attrs, schema, req=False, label='', tip='', comment=''): """Add a short answer fields to this form. @@ -206,10 +183,11 @@ field: the current field value: the initial value for this field attrs: additional attributes for field + schema: schema for survey req: required bool label: label for field tip: tooltip text for field - comment: initial comment value for field + comment: initial comment value for field """ attrs['class'] = "text_question" @@ -220,13 +198,9 @@ question = CharField(help_text=tip, required=req, label=label, widget=widget, max_length=140, initial=value) + self.survey_fields[field] = question - - if not self.editing: - widget = widgets.Textarea(attrs=attrs) - comment = CharField(help_text=tip, required=False, label='Comments', - widget=widget, initial=comment) - self.survey_fields['comment_for_' + field] = comment + self.addCommentField(field, comment, attrs, tip) def addSingleField(self, field, value, attrs, schema, req=False, label='', tip='', comment=''): @@ -243,12 +217,7 @@ comment: initial comment value for field """ - if self.editing: - kind = schema[field]["type"] - render = schema[field]["render"] - widget = UniversalChoiceEditor(kind, render) - else: - widget = WIDGETS[schema[field]['render']](attrs=attrs) + widget = schema.getWidget(field, self.editing, attrs) these_choices = [] # add all properties, but select chosen one @@ -266,13 +235,9 @@ question = PickOneField(help_text=tip, required=req, label=label, choices=tuple(these_choices), widget=widget) + self.survey_fields[field] = question - - if not self.editing: - widget = widgets.Textarea(attrs=attrs) - comment = CharField(help_text=tip, required=False, label='Comments', - widget=widget, initial=comment) - self.survey_fields['comment_for_' + field] = comment + self.addCommentField(field, comment, attrs, tip) def addMultiField(self, field, value, attrs, schema, req=False, label='', tip='', comment=''): @@ -287,14 +252,10 @@ label: label for field tip: tooltip text for field comment: initial comment value for field + """ - if self.editing: - kind = schema[field]["type"] - render = schema[field]["render"] - widget = UniversalChoiceEditor(kind, render) - else: - widget = WIDGETS[schema[field]['render']](attrs=attrs) + widget = schema.getWidget(field, self.editing, attrs) # TODO(ajaksu) need to allow checking checkboxes by default if self.survey_record and isinstance(value, basestring): @@ -310,12 +271,9 @@ question = PickManyField(help_text=tip, required=req, label=label, choices=tuple(these_choices), widget=widget, initial=value) + self.survey_fields[field] = question - if not self.editing: - widget = widgets.Textarea(attrs=attrs) - comment = CharField(help_text=tip, required=False, label='Comments', - widget=widget, initial=comment) - self.survey_fields['comment_for_' + field] = comment + self.addCommentField(field, comment, attrs, tip) def addQuantField(self, field, value, attrs, schema, req=False, label='', tip='', comment=''): @@ -330,14 +288,10 @@ label: label for field tip: tooltip text for field comment: initial comment value for field + """ - if self.editing: - kind = schema[field]["type"] - render = schema[field]["render"] - widget = UniversalChoiceEditor(kind, render) - else: - widget = WIDGETS[schema[field]['render']](attrs=attrs) + widget = schema.getWidget(field, self.editing, attrs) if self.survey_record: value = value @@ -352,18 +306,60 @@ choices=tuple(these_choices), widget=widget, initial=value) self.survey_fields[field] = question + self.addCommentField(field, comment, attrs, tip) + + def addCommentField(self, field, comment, attrs, tip): if not self.editing: widget = widgets.Textarea(attrs=attrs) comment = CharField(help_text=tip, required=False, label='Comments', widget=widget, initial=comment) self.survey_fields['comment_for_' + field] = comment - class Meta(object): model = SurveyContent exclude = ['schema'] +class SurveyContentSchema(object): + """Abstract question metadata handling. + """ + + def __init__(self, schema): + self.schema = eval(schema) + + def getType(self, field): + return self.schema[field]["type"] + + def getRender(self, field): + return self.schema[field]["render"] + + def getWidget(self, field, editing, attrs): + """Get survey editing or taking widget for choice questions. + """ + + if editing: + kind = self.getType(field) + render = self.getRender(field) + widget = UniversalChoiceEditor(kind, render) + else: + widget = WIDGETS[self.schema[field]['render']](attrs=attrs) + return widget + + def getLabel(self, field): + """Fetch the free text 'question' or use field name as label. + """ + + if field not in self.schema: + logging.error('field %s not found in schema %s' % + (field, str(self.schema))) + return + elif 'question' in self.schema[field]: + label = self.schema[field].get('question') or field + else: + label = field + return label + + class UniversalChoiceEditor(widgets.Widget): """Edit interface for choice questions. @@ -600,9 +596,9 @@ def getRoleSpecificFields(survey, user, this_project, survey_form, survey_record): """For evaluations, mentors get required Project and Grade fields, and - students get a required Project field. + students get a required Project field. - Because we need to get a list of the user's projects, we call the + Because we need to get a list of the user's projects, we call the logic getProjects method, which doubles as an access check. (No projects means that the survey cannot be taken.) @@ -615,11 +611,10 @@ or None """ - from django import forms - field_count = len(eval(survey.survey_content.schema).items()) these_projects = survey_logic.getProjects(survey, user) - if not these_projects: return False # no projects found + if not these_projects: + return False # no projects found project_pairs = [] #insert a select field with options for each project