2015-12-04 26 views
0

我有一个Django 1.8表单,其中包含一个段落标记,呈现一些反馈或用户提交的问题。它还包含一个textarea输入'response_text'和一对单选按钮'close_issue'。此响应输入可用于向用户发送可选响应。如果用户提交了一些反馈,管理员应该能够点击“关闭问题”单选按钮并提交没有回复的表单。但是,如果textarea输入包含一个问题,那么表单应该显示一个错误,告诉管理员他/她无法在响应输入中输入回答而无法提交表单。我遇到的问题是,如果用户提交问题但管理员没有输入回复,我无法获取表单以使模板呈现错误消息。我的视图,模型,表单和模板如下所示。 forms.py显示了所有的方法(全部注释掉了)如果用户提交了一个问题以便模板会显示一个错误,我试图做出所需的响应输入字段。我也尝试覆盖默认的'clean'方法,如果用户提交了一个问题,并且响应输入是空白的,但是这也不起作用,那么会引发ValidationError。谁能告诉我我做错了什么?Django模板不呈现动态表单错误

谢谢。

# view.py 
def review_feedback_or_question(request, template, *args, **kwargs): 
    fqid = kwargs['fqid']## Heading ## 
    submission = FeedbackQuestion.objects.get(pk=fqid) 
    if request.method == 'POST': 
     form = FeedbackQuestionResponseForm(request.POST, submission=submission) 
     if form.is_valid(): 
      # process the form 
      return redirect('review-feedback-or-question-queue') 
    else: 
     pass 
    form = FeedbackQuestionResponseForm(submission=submission) 
    context = {'form': form, 'submission': submission,} 
    return render(request, template, context) 

# models.py 
class FeedbackQuestion(models.Model): 
    SELECT = '' 
    FEEDBACK = 'feedback' 
    QUESTION = 'question' 
    SUBMISSION_TYPE_CHOICES = (
     (SELECT , '-- Select --'), 
     (FEEDBACK, 'Feedback'), 
     (QUESTION, 'Question'), 
    ) 
    user = models.ForeignKey(User, related_name="user") 
    submission_type = models.CharField(max_length=8, 
             choices=SUBMISSION_TYPE_CHOICES, 
             default=SELECT) 
    submission_text = models.TextField() 
    date_submitted = models.DateTimeField(auto_now_add=True) 
    response_text = models.TextField() 
    respondent = models.ForeignKey(User, related_name='respondent') 
    date_responded = models.DateTimeField(auto_now=True) 
    issue_closed = models.BooleanField(default=False) 

    class Meta: 
     db_table = 'feedback_question' 

# forms.py 
class FeedbackQuestionResponseForm(forms.Form): 
    TRUE = 1 
    FALSE = 0 
    BLANK = '' 
    CHOICES = ((TRUE, 'Yes'), (FALSE, 'No')) 

    response_text = forms.CharField(
     required=False, 
     label='', 
     widget=forms.Textarea(attrs={'placeholder': 'Enter response...'})) 
    close_issue = forms.TypedChoiceField(
     choices=CHOICES, 
     label='Close this issue?', 
     widget=forms.RadioSelect(renderer=HorizontalRadioRenderer), 
     coerce=int) 

    def __init__(self, *args, **kwargs): 
     if 'submission' in kwargs: 
      submission = kwargs.pop('submission') 
      if submission.submission_type == 'question': 
       # NONE OF THESE WORKED! 
       #self.fields.get('response_text').required = True 
       #self.declared_fields['response_text'].required = self.TRUE 
       #self.declared_fields['response_text'].required = self.TRUE 
       #self.declared_fields['response_text'].required = True 
       #self._errors['response_text'] = "You must enter a response" 
       pass 
     super(FeedbackQuestionResponseForm, self).__init__(*args, **kwargs) 

# template.html 
    <p>{{ submission.submission_text }}</p> 

    <form action="" method="post">{% csrf_token %} 

    {{ form.non_field_errors }} 

    {% if form.errors %} 
     {% if form.errors.items|length == 1 %} 
      Please correct the error below. 
     {% else %} 
      Please correct the errors below. 
     {% endif %} 
     </p> 
    {% endif %} 

    {{ form.response_text.errors }} 
    {{ form.response_text.label_tag }} {{ form.response_text }} 

    {{ form.close_issue.errors }} 
    {{ form.close_issue }} {{ form.close_issue.label_tag }} 

    <input type="submit" value="Submit" class="" /> 
    </form> 

回答

0

丹尼尔罗斯曼是正确的,因为我需要通过'提交'表单时,我在POST上实例化窗体。但还有其他两个问题。首先,我需要在else块中实例化表单。如果没有完成并且表单无法验证,那么您会将未绑定的表单传递回查看器,并且不会显示任何错误。此外,它是没有必要的,当你在这里实例为“提交”传递到形式:

... 
else: 
    form = FeedbackQuestionResponseForm() 
context = {...} 
... 

接下来的问题是,我的init方法中语句的顺序是不正确的。看来我需要在尝试引用'response_text'字段之前执行'super()'。我需要在Django源代码中找到并研究此方法,以便准确理解原因。在任何情况下,这个工程:

def __init__(self, *args, **kwargs): 
    if 'submission' in kwargs: 
     submission = kwargs.pop('submission') 
    else: 
     submission = False 
    super(FeedbackQuestionResponseForm, self).__init__(*args, **kwargs) 
    if submission: 
     if submission.submission_type == 'question': 
      self.fields['response_text'].required = True 
     else: 
      self.fields['response_text'].required = False 

当上述修改的落实,形式将所需要的response_text场,如果用户提交一个问题,如果管理员不输入的响应,将显示一个错误提交表单之前。非常感谢丹尼尔让我回到寻找解决方案的轨道上。

1

你不及格submission成当实例它POST的形式,让所需要的属性是永远不会被设置。

+0

丹尼尔,这是一个很好的抓住,你是绝对正确的(我已经更新了问题)。但是,当我修复该错误并尝试在表单的init方法中逐个取消注释每个单独的“self ...”语句时,模板仍然不会显示错误。表单或模板还有其他问题吗?非常感谢。 – William

+0

有些东西仍然是错误的,因为这些行中的任何一行都会立即引发异常(它们都以某种方式无效)。你确定你正在进入'if'块吗?在那里打印一份声明。 –

+0

是的,我在init中的“if submission.submission_type =='问题'之前放了一个调试语句,我正在进入内部的”if“块。我只是不确定当我在那里时该做什么。我已经注释掉的东西是其他类似问题中提到的东西,但是没有一个需要response_text,以便模板呈现错误。 – William