0

This is pretty much related to this: How to access data when form.is_valid() is false

In my case, if the form validation fails, I'd like to have user view the same page with an error message AND have it to show a new and modified cleaned_data comment. Right now, if it fails the form validation, it'll show the page with old user submitted comment. The reason why I want to show the modified comment is because I want the new data to match the error message. For example, If an user submitted

'            hey             bye                  '

to get around the 20 character minimum limit, my cleaning function will strip the white spaces and trim it down to

'hey bye'

and then fail the validation. The error message will say "The comment length needs to be at least 20 characters long". With the old data, the user will get confused because he actually put in more than 20 characters and the old data will show it. I want them to see the stripped comment, so they will know why I failed it.

Here's my code...

views.py

def question(request, qid):
    quest = shortcuts.get_object_or_404(askbox.models.Question, pk=qid)
    log.info("Question #{0}: {1}".format(qid, quest))
    user = SessionManager.getLoggedInUser(request)
    answerForm = AnswerForm()

    if request.method == "POST":
        if user == None:
            return HttpResponseRedirect(reverse('login.views.login'))
        answerForm = AnswerForm(request.POST)
        if answerForm.is_valid():
            # user posted an answer
            answerForm.question = quest
            answerForm.user = user
            answerForm.save()
            return HttpResponseRedirect(reverse('question.views.question', args=(quest.id,)))
        else:
            #answerForm.text = answerForm.saved_data['text'] #doesn't work too
            answerForm.text = "foo" # doesn't work...
    else: # GET request
        # landing page
        # probably do nothing
        pass
    print "AnswerForm: {0}".format(answerForm)
    mediaList = askbox.models.Media.objects.filter(question=qid)
    return shortcuts.render_to_response('question/question.html', {
        'title': 'Groupthink | {0}'.format(quest.question),
        'css_list': css_list,
        'js_list': js_list,
        'question': quest,
        'mediaList': mediaList,
        'user': user,
        'answerForm': answerForm,
    }, context_instance=RequestContext(request))

forms.py

# fake abstract class... 
class AbstractCommentForm(forms.ModelForm):
    text = forms.CharField(min_length=MIN_ANSWER_LEN, max_length=MAX_ANSWER_LEN, widget=forms.Textarea) # the comment text

    def clean_text(self):
        # we want to avoid user cheating the system. We'll trim extra spaces between characters and then strip spaces at both ends of the string
        field = 'text'
        self.cleaned_data[field] = (re.sub(r'  +', ' ', self.cleaned_data[field])).strip()
        self.text = self.cleaned_data[field] # doesn't work
        text_len = len(self.cleaned_data[field])
        self.saved_data = self.cleaned_data # doesn't work
        if text_len < MIN_ANSWER_LEN:
            raise forms.ValidationError("The comment length needs to be at least {0} characters long".format(MIN_ANSWER_LEN))
        if text_len > MAX_ANSWER_LEN:
            raise forms.ValidationError("The comment length exceeds the maximum {0} characters".format(MAX_ANSWER_LEN))
        return self.cleaned_data[field]


class CommentForm(AbstractCommentForm):
    class Meta:
        model = Comment


class AnswerForm(AbstractCommentForm):
    class Meta:
        model = Answer
Community
  • 1
  • 1
nikeairj
  • 173
  • 10
  • Why not just adding a new error message - "Multiple spaces are not allowed in response" ? This will be more informative to the users why their answer is not valid, instead of trying to evaluate the length of something they actually didn't submit... – Tisho Jun 10 '12 at 10:19
  • I could resort to that. I'm hoping that someone would know the answer to the question. If it's too complicated to achieve this, I can do what you suggested. – nikeairj Jun 10 '12 at 19:43
  • 1
    My only gut feel here is that if something is too complex, then it is probably wrong... I always try to make things simple, and to look for the fastest processing workflow in the code. If it comes to need lots of checks - then it is probably wrong. If it is hard to explain how exactly it works - then it is probably wrong... If I dig enough in the code - I'm almost sure that there is a way to do what you want. But I really think this doesn't worth the time to find it out. – Tisho Jun 10 '12 at 20:06
  • That's good philosophy to stand by. Yeah, I'm probably over thinking and over complicating this. K.I.S.S., right? :) – nikeairj Jun 11 '12 at 05:04

0 Answers0