问题
Okay, this is a weird one, at least to me.
I have a form that contains event_date
and article_date
.
I want to confirm that event_date
is not bigger than article_date
, because that would mean that the event would take place in the future, which is not possible.
Now, what I did is this:
def clean(self):
cleaned_data = self.cleaned_data
event_date = cleaned_data.get("event_date")
location = cleaned_data.get("location")
article_date = cleaned_data.get("article_date")
if event_date and location:
cleaned_data['relevance'] = True
else:
cleaned_data['relevance'] = False
raise forms.ValidationError("You need to supply at least Event and Location information")
if event_date > article_date:
raise forms.ValidationError("This event would be in the future...try again.")
return cleaned_data
(I include the other validation to show you that validating works otherwise)
In my template, I have the following code to display form errors:
{% if form.non_field_errors %}
{{form.non_field_errors}}
{%endif%}
{% if form.errors %}
{% for field in form %}
{% if field.errors %}
<li>{{ field.errors|striptags }}</li>
{% endif %}
{% endfor %}
{% endif %}
Now, when I try to test if this works and submit a date in the future, I get the following error:
'str' object has no attribute 'label'
Error during template rendering, error at line 62:
57 {% if form.non_field_errors %}
58 {{form.non_field_errors}}
59 {%endif%}
60
61 {% if form.errors %}
62 {% for field in form %}
63 {% if field.errors %}
64 <li>{{ field.errors|striptags }}</li>
65 {% endif %}
66 {% endfor %}
67 {% endif %}
If I comment out the validation, the error disappears.
Can someone please tell me what's going on?
EDIT:
By request, my view, in all its glory:
def assignment(request, pk):
"""View for each assignment"""
if request.user.is_authenticated():
#### Get correct articles
assignment = get_object_or_404(Assignment, pk=pk)
country = assignment.country.cowcode
start_date = assignment.start_date
end_date = assignment.end_date
articles = Article.objects.filter(cowcode=country).filter(pubdate__range=(start_date,end_date)).distinct()
#### Pagination ####
paginator = Paginator(articles, 1)
page = request.GET.get('page')
try:
articles = paginator.page(page)
except PageNotAnInteger:
articles = paginator.page(1)
except EmptyPage:
articles = paginator(page(paginator.num_pages))
# Check if on first page and enable redirect
if page is None:
current_page = 1
else:
current_page = page
redirect_to = "?page=%s" % current_page
##### Show already created events on the page
current_article = paginator.page(current_page).object_list[0]
EventFormSet = modelformset_factory(EventRecord, can_delete=True, exclude=('coder','article','url','last_updated'), extra=0)
event_queryset = EventRecord.objects.filter(article__id=current_article.id).filter(coder=request.user.id)
coded_events = EventFormSet(queryset=event_queryset, prefix="event_form")
article_date = current_article.pubdate.strftime("%Y-%m-%d")
try:
last_updated = ArticleHistory.objects.filter(coder=request.user.id).filter(article__id=current_article.id).order_by('-pk')[0]
except:
last_updated = None
##### Create Forms
CodingFormSet = formset_factory(CodingForm,can_delete=True, extra=0)
###### Get correct locations
location_queryset = Geonames.objects.filter(cowcode=country).order_by('name')
if request.method=='POST':
##### Check if coder wants to go to next page or stay
if "coding_form_next" in request.POST:
formset = CodingFormSet(request.POST, prefix="coding_form")
next_article = True
if formset.is_valid():
process_form(formset, country, request, current_page, paginator, next_article, coded_events, location_queryset)
if articles.has_next():
current_page = int(current_page) + 1
else:
current_page = int(current_page)
redirect_to = "?page=%s" % current_page
return HttpResponseRedirect(redirect_to)
update_location_set(formset, coded_events, location_queryset)
insert_article_pubdate(formset, current_article)
elif "coding_form_save" in request.POST:
formset = CodingFormSet(request.POST, prefix="coding_form")
next_article = False
if formset.is_valid():
process_form(formset, country, request, current_page, paginator, next_article, coded_events, location_queryset)
update_location_set(formset, coded_events, location_queryset)
redirect_to = "?page=%s" % current_page
return HttpResponseRedirect(redirect_to)
update_location_set(formset, coded_events, location_queryset)
insert_article_pubdate(formset, current_article)
elif 'add_event' in request.POST:
cp = request.POST.copy()
cp['coding_form-TOTAL_FORMS'] = int(cp['coding_form-TOTAL_FORMS']) + 1
if int(cp['coding_form-TOTAL_FORMS']) == 1:
formset = CodingFormSet(cp, prefix='coding_form')
else:
formset = CodingFormSet(cp,prefix='coding_form')
#insert_article_pubdate(formset, current_article)
update_location_set(formset, coded_events, location_queryset)
elif 'save_changes' in request.POST:
formset = CodingFormSet(prefix="coding_form")
changed_events = EventFormSet(request.POST, prefix="event_form")
instances = changed_events.save()
try:
history_record = ArticleHistory.objects.filter(article__id=paginator.page(current_page).object_list[0].id).filter(coder=request.user.id)[0]
history_record.last_updated = datetime.datetime.now()
history_record.save()
except:
history_form = ArticleHistoryForm()
article_history = history_form.save(commit=False)
article_history.article = paginator.page(current_page).object_list[0]
article_history.coder = request.user
article_history.last_updated = datetime.datetime.now()
article_history.save()
EventFormSet = modelformset_factory(EventRecord, can_delete=True, exclude=('coder','article','url','last_updated'), extra=0)
event_queryset = EventRecord.objects.filter(article__id=current_article.id).filter(coder=request.user.id)
coded_events = EventFormSet(queryset=event_queryset, prefix="event_form")
update_location_set(formset, coded_events, location_queryset)
insert_article_pubdate(formset, current_article)
else:
formset = CodingFormSet(request.POST or None, prefix="coding_form")
update_location_set(formset, coded_events, location_queryset)
insert_article_pubdate(formset, current_article)
else:
print ERROR
return render(request, 'coding/assignment.html',
{'articles':articles,'assignment':assignment,'formset':formset,'coded_events':coded_events,'last_updated':last_updated})
EDIT 2:
And here the full form, as per request:
<form action="" method="post" accept-charset="utf-8" id="form">
<div id="organizer">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="form-container">
{% if form.non_field_errors %}
{{form.non_field_errors}}
{%endif%}
{% if form.errors %}
{% for field in form %}
{% if field.errors %}
<li>{{ field.errors|striptags }}</li>
{% endif %}
{% endfor %}
{% endif %}
<table width="100%" border="0" cellspacing="5" cellpadding="5">
<tr>
<td width="30%"><label for="id_form-0-event_date">Event Date:</label></td>
<td class="datepicker">
{{ form.event_date}}
</td>
<td><label for="id_form-0-location">Location:</label></td>
<td><div class="location_wrapper">{{ form.location }}</div></td>
<td><label for="id_form-0-actors">Actors:</label></td>
<td>{{ form.actors }}</td>
<td><label for="id_form-0-num_participants">Number of Participants:</label></td>
<td>{{ form.num_participants }}</td>
</tr>
<tr>
<td><label for="id_form-0-issue">Issue:</label></td>
<td>{{ form.issue }}</td>
<td><label for="id_form-0-side">Side:</label></td>
<td>{{ form.side }}</td>
<td><label for="id_form-0-scope">Scope:</label></td>
<td>{{ form.scope }}</td>
<td><label for="id_form-0-part_violence">Participant Violence:</label></td>
<td>{{ form.part_violence}}</td>
</tr>
<tr>
<td><label for="id_form-0-sec_engagement">Security <br/> Forces Engagement:</label></td>
<td>{{ form.sec_engagement }}</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><label for="id_event_form-0-DELETE">Delete Event:</label></td>
<td>{{ form.DELETE }}</td>
</tr>
</table>
</div>
{% endfor %}
</div>
<div id="form-nav">
<div id="add-event">
<input type="submit" name="add_event" value="Add Event"> {{ dings|date:'Y-m-d'}}
</div>
<div id="save-stay">
<input type="submit" name="coding_form_save" value="Save">
</div>
<div id="save-next">
<input type="submit" name="coding_form_next" value="Save & Next">
</div>
</div>
</form>
来源:https://stackoverflow.com/questions/18254185/str-object-has-no-attribute-label-when-validating