2014-03-03 2 views
2

템플릿에 필드 오류를 제대로 표시하지 않는 Django ModelForm이 있습니다. 필요한 필드가 여러 개 있으며 사용자에게 오류를 캡처하고 표시하는 올바른 논리라고 생각합니다.Django ModelForm이 필드 오류를 표시하지 않습니다.

양식을 제출하면, 나는 다음과 같은 오류 얻을 : 여기

class ApplicationCreateView(CreateView): 
    model = Application 
    form_class = ApplicationForm 
    success_url = 'submitted/' 

    def dispatch(self, *args, **kwargs): 
     self.job = get_object_or_404(Job, slug=kwargs['slug']) 
     return super(ApplicationCreateView, self).dispatch(*args, **kwargs) 

    def form_valid(self, form): 
     #Get associated job and save 
     self.object = form.save(commit=False) 
     self.object.job = self.job 
     self.object.save() 

     # Gather cleaned data for email send 
     first_name = form.cleaned_data.get('first_name') 
     last_name = form.cleaned_data.get('last_name') 
     email_address = form.cleaned_data.get('email_address') 
     phone_number = form.cleaned_data.get('phone_number') 
     salary_requirement = form.cleaned_data.get('salary_requirement') 
     description = form.cleaned_data.get('description') 
     portfolio_url = form.cleaned_data.get('portfolio_url') 
     can_relocate = form.cleaned_data.get('can_relocate') 
     start_date = form.cleaned_data.get('start_date') 
     resume = self.object.resume 
     job = self.object.job 

     #Compose message 
     email = EmailMessage() 
     email.body = 'Name: ' + first_name + last_name + '\n' + 'Email: ' + email_address + '\n' + 'Phone number: ' + str(phone_number) + '\n' + 'Salary requirement: ' + str(salary_requirement) + '\n' + 'Description: ' + description + '\n' + 'Portfolio URL: ' + portfolio_url + '\n' + 'Can relocate: ' + str(can_relocate) + '\n' + 'Start date: ' + str(start_date) 
     email.subject = 'A new application has been submitted for %s' % (job) 
     email.from_email = '[email protected]' 
     email.to = ['[email protected]',] 
     email.bcc = ['[email protected]',] 
     email.attach(resume.name, resume.read()) 
     email.send() 
     return HttpResponseRedirect(self.get_success_url()) 

    def get_context_data(self, *args, **kwargs): 
     context_data = super(ApplicationCreateView, self).get_context_data(*args, **kwargs) 
     context_data.update({'job': self.job}) 
     return context_data 

그리고 다음은

Traceback (most recent call last): 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view 
    return self.dispatch(request, *args, **kwargs) 

File "/home/thevariable/webapps/va_jobs/va_jobs/jobs/views.py", line 29, in dispatch 
    return super(ApplicationCreateView, self).dispatch(*args, **kwargs) 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch 
    return handler(request, *args, **kwargs) 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/views/generic/edit.py", line 205, in post 
    return super(BaseCreateView, self).post(request, *args, **kwargs) 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/views/generic/edit.py", line 170, in post 
    if form.is_valid(): 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/forms/forms.py", line 129, in is_valid 
    return self.is_bound and not bool(self.errors) 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/forms/forms.py", line 121, in errors 
    self.full_clean() 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/forms/forms.py", line 274, in full_clean 
    self._clean_form() 

File "/home/thevariable/.virtualenvs/va_jobs/lib/python2.7/site-packages/django/forms/forms.py", line 300, in _clean_form 
    self.cleaned_data = self.clean() 

File "/home/thevariable/webapps/va_jobs/va_jobs/jobs/forms.py", line 23, in clean 
    resume_ext = resume.name.lower().split('.')[1] 

AttributeError: 'NoneType' object has no attribute 'name' 

내 forms.py입니다 :

여기
from django.forms import ModelForm 

from .models import Application 

class ApplicationForm(ModelForm): 
    class Meta: 
     model = Application 
     fields = [ 
      'first_name', 
      'last_name', 
      'email_address', 
      'phone_number', 
      'salary_requirement', 
      'resume', 
      'portfolio_url', 
      'description', 
      'can_relocate', 
      'start_date', 
     ] 

    def __init__(self, *args, **kwargs): 
     super(ApplicationForm, self).__init__(*args, **kwargs) 
     self.fields['first_name'].required = True 
     self.fields['last_name'].required = True 
     self.fields['email_address'].required = True 
     self.fields['phone_number'].required = True 
     self.fields['salary_requirement'].required = False 
     self.fields['resume'].required = True 
     self.fields['portfolio_url'].required = False 
     self.fields['description'].required = False 
     self.fields['can_relocate'].required = True 
     self.fields['start_date'].required = False 

    def clean(self): 
     cleaned_data = super(ApplicationForm, self).clean() 
     resume = cleaned_data.get('resume') 
     resume_ext = resume.name.lower().split('.')[1] 
     if not resume_ext in ('pdf', 'doc', 'docx'): 
      del cleaned_data["resume"] 
      msg = u"Your file must be a PDF or DOC file type." 
      raise forms.ValidationError(msg) 
      #self._errors["resume"] = self.error_class([msg])  
     return cleaned_data 

내보기입니다 내 템플릿입니다 (Django 위젯을 사용하여 https://pypi.python.org/pypi/django-widget-tweaks 조정) :

스택 트레이스의 모든 간단한3210
<p><em>Note: Fields with an asterisk are required.</em></p> 
<form role="form" action="" enctype="multipart/form-data" method="post"> 
{% csrf_token %} 
{% for field in form.visible_fields %} 
    <div class="form-group"> 
     {% if field.errors %} 
     <ul class="list-unstyled list-inline"> 
      {% for error in field.errors %} 
      <li class="text-warning"><span class="glyphicon glyphicon-warning-sign"></span> {{ error|escape }}</li> 
      {% endfor %} 
     </ul> 
     {% endif %} 
     {{ field.label_tag }} 
     {% if field.name == "portfolio_url" %} 
      {% if job.portfolio_required %} <small><span class="glyphicon glyphicon-asterisk"></span></small> 
      {% endif %} 
     {% endif %} 
     {% if field.field.required %} <small><span class="glyphicon glyphicon-asterisk"></span></small>{% endif %} 
     {% if field.name == "resume" or field.name == "can_relocate" %} 
      {{ field|add_class:"form-control short" }} 
     {% elif field.name == "start_date" %} 
      <input id="id_start_date" class="form-control short" name="start_date" type="date" /><input id="initial-id_start_date" name="initial-start_date" type="hidden" /> 
     {% elif field.name == "portfolio_url" %} 
      {% if job.portfolio_required %} 
       <input class="form-control" id="id_portfolio_url" maxlength="200" name="portfolio_url" type="url" required /> 
      {% endif %} 
     {% else %} 
     {{ field|add_class:"form-control" }} 
     {% endif %} 
     {% if field.help_text %}<p class="help-block">{{ field.help_text }}</p>{% endif %} 
    </div> 
{% endfor %} 
    <input type="submit" class="btn btn-default" value="Apply"> 
</form> 
+0

'resume' 객체가 어떤 이유로 'None'으로 평가됩니다. 거기에 흐름을 확인하십시오. – karthikr

+1

기본적으로'resume'가 설정되어 있지 않으면이 에러가 발생합니다 :'resume_ext = resume.name.lower(). split ('.') [1] resume and resume.name else ''' – karthikr

+0

그건 내거야. 생각뿐. 'if cleaned_data.get ('resume') :'....'else : return cleaned_data' –

답변

1

내 솔루션 (forms.py에서) 다음과 같이했다 : 그는 아무도없는 사촌 여기

는 예외입니다 질문 (Django ModelForm not showing field errors).

+0

"_errors"를 어떻게 든 사용 하시겠습니까? –

+0

정확합니다. 이것은'self.add_error ('resume', msg)'로 쓰여질 수있다. –

-1

는 말한다 : 청소 데이터

resume = cleaned_data.get('resume') 
어쩌면

resume 없다 "resume 더 속성 name이없는 개체"? 인쇄를 시도하거나 pudb을 입력하십시오.

def clean(self): 
    cleaned_data = super(ApplicationForm, self).clean() 
    if cleaned_data.get('resume'): 
     resume = cleaned_data.get('resume') 
     resume_ext = resume.name.lower().split('.')[1] 
     if not resume_ext in ('pdf', 'doc', 'docx'): 
      del cleaned_data["resume"] 
      msg = u"Your file must be a PDF or DOC file type." 
      self._errors["resume"] = self.error_class([msg])   
     return cleaned_data 
    else: 
     return cleaned_data 

이 원래의 의견에 의해 영감을했다 : 공식적으로

resume_ext = resume.name.lower().split('.')[1] 
+0

답변이 아닙니다. 그리고 그것에 snarky. –

관련 문제