Hi, this is an old itch that keeps coming back when working with quixote/qp forms. The issue is 2-fold: - Form.is_submitted(), when the form's method is GET, does not care to check which form we are concerned about. - If we render() the form, each widget's render() is called in turn, that then calls Widget.parse(). This method implements its own "meaning" of "is submitted", that is different than that of a Form. The current code: Form: def is_submitted(self): """() -> bool Return true if a form was submitted. If the form method is 'POST' and the page was not requested using 'POST', then the form is not considered to be submitted. If the form method is 'GET' then the form is considered submitted if there is any form data in the request. """ if self.method == 'post': return get_request().get_method() == 'POST' else: return bool(get_request().get_fields()) Widget: def parse(self, request=None): if not self._parsed: self._parsed = True if request is None: request = get_request() if request.get_fields() or request.get_method() == 'POST': #<< try: self._parse(request) except WidgetValueError, exc: self.set_error(stringify(exc)) if (self.required and self.value is None and not self.has_error()): self.set_error('required') return self.value The "is submitted" check in parse() (#<<) is problematic because if a specific form is NOT submitted, but there happens to be some query string parameters in the URL requested doing a GET (even if the form's method is POST), e.g. from URL-hacking garbage, then the widget will be rendered with its error, if any... I feel that the if "is submitted" check in parse() should behave in exactly the same way as Form.is_submitted(). It should probably execute the same code... or at least use the same cached result.... The other issue, about being a little more specific about which form instance we are talking about when we call Form.is_submitted() and the method is GET, why would we not check for only incoming field names that are actually widgets of this form? Something like: def is_submitted(self): request = get_request() if self.method == 'post': return request.get_method() == 'POST' else: for name in self._names: if bool(request.get_field(name)): return True return False m.