class SuiteForm(mtforms.NonFieldErrorsClassFormMixin, mtforms.MTModelForm): """Base form for adding/editing suites.""" cases = mtforms.MTMultipleChoiceField( required=False, widget=mtforms.FilteredSelectMultiple( choice_template= "manage/multi_select/case_select/_case_select_item.html", listordering_template=( "manage/multi_select/case_select/_case_select_listordering.html" ), filters=[ filters.KeywordFilter("name"), filters.ModelFilter("tag", lookup="tags", queryset=model.Tag.objects.all()), filters.ModelFilter("author", queryset=model.User.objects.all()), filters.ChoicesFilter("priority", choices=Choices(1, 2, 3, 4)) ], )) product = mtforms.MTModelChoiceField( queryset=model.Product.objects.all(), choice_attrs=lambda p: {"data-product-id": p.id}) class Meta: model = model.Suite fields = ["product", "name", "description", "status"] widgets = { "name": forms.TextInput, "description": mtforms.BareTextarea, "status": forms.Select, } def clean_cases(self): """ Make sure all the ids for the cases are valid and populate self.cleaned_data with the real objects. """ # fetch the case objects in one query, but loses order. cases = dict((unicode(x.id), x) for x in model.Case.objects.filter( pk__in=self.cleaned_data["cases"])) # put them back in order and remove dups, if any try: # remove dups, if there are any. clean_cases = [] for case_id in self.cleaned_data["cases"]: case = cases[case_id] if case not in clean_cases: clean_cases.append(case) # if number is different, then add this to changed data if (("cases" in self.initial and self.initial["cases"] != self.cleaned_data["cases"]) or len(self.cleaned_data["cases"]) is not len(clean_cases)): self.changed_data.append("cases") return clean_cases except KeyError as e: raise ValidationError("Not a valid case for this suite.")
class RunForm(mtforms.NonFieldErrorsClassFormMixin, mtforms.MTModelForm): """Base form for adding/editing runs.""" suites = mtforms.MTMultipleChoiceField( required=False, widget=mtforms.FilteredSelectMultiple( choice_template="manage/run/suite_select/_suite_select_item.html", listordering_template=( "manage/run/suite_select/_suite_select_listordering.html"), filters=[ filters.KeywordFilter("name"), filters.ModelFilter("author", queryset=model.User.objects.all()), ], )) productversion = mtforms.MTModelChoiceField( queryset=model.ProductVersion.objects.all(), choice_attrs=mtforms.product_id_attrs, ) build = forms.CharField(max_length=200, required=False) is_series = forms.BooleanField(required=False) class Meta: model = model.Run fields = [ "productversion", "name", "description", "is_series", "build", "start", "end", "is_series", ] widgets = { "name": forms.TextInput, "description": mtforms.BareTextarea, "build": forms.TextInput, "is_series": forms.CheckboxInput, "start": forms.DateInput, "end": forms.DateInput, } def clean_suites(self): """ Make sure all the ids for the suites are valid and populate self.cleaned_data with the real objects. If these are not ids, then they are read-only strings of the title and therefore don't need to be validated. So first verify they're all ints. """ try: suites = dict((unicode(x.id), x) for x in model.Suite.objects.filter( pk__in=self.cleaned_data["suites"])) try: return [suites[x] for x in self.cleaned_data["suites"]] except KeyError as e: raise ValidationError("Not a valid suite for this run.") except ValueError: # some of the values weren't ints, and therefore this is # from the read-only list of suites. so return None so that we # don't try to remove and re-add them. if "suites" in self.changed_data: # pragma: no cover self.changed_data.remove("suites") return None def clean_build(self): """If this is a series, then null out the build field.""" if self.cleaned_data["is_series"]: return None def save(self, user=None): """Save and return run, with suite associations.""" user = user or self.user run = super(RunForm, self).save(user=user) if "suites" in self.changed_data: # if this is empty, then don't make any changes, because # either there are no suites, or this came from the read # only suite list. run.runsuites.all().delete(permanent=True) for i, suite in enumerate(self.cleaned_data["suites"]): model.RunSuite.objects.create(run=run, suite=suite, order=i, user=user) return run