diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index 9f93fa049..ba8b2a842 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -2,7 +2,7 @@ from __future__ import absolute_import, unicode_literals from time import time from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import PermissionDenied +from django.core.exceptions import PermissionDenied, ValidationError from django.core.urlresolvers import reverse from django.db.models import Count from django.http import Http404, HttpResponse, JsonResponse @@ -12,6 +12,7 @@ from django.template.loader import render_to_string from django.utils import timezone from django.utils.http import is_safe_url, urlquote from django.utils.safestring import mark_safe +from django.utils.six import string_types from django.utils.translation import ugettext as _ from django.views.decorators.http import require_GET, require_POST from django.views.decorators.vary import vary_on_headers @@ -578,50 +579,44 @@ class PreviewOnEdit(View): return get_object_or_404(Page, id=self.args[0]).get_latest_revision_as_page() - def get_form(self): - page = self.get_page() + def get_form(self, page, query_dict): form_class = page.get_edit_handler().get_form_class(page._meta.model) parent_page = page.get_parent().specific - post_data_dict, timestamp = self.request.session[self.session_key] + return form_class(query_dict, instance=page, parent_page=parent_page) - # convert post_data_dict back into a QueryDict - post_data = QueryDict('', mutable=True) - for k, v in post_data_dict.items(): - post_data.setlist(k, v) - - return form_class(post_data, instance=page, parent_page=parent_page) + @staticmethod + def is_form_valid(form): + try: + return form.is_valid() + except ValidationError: + return False def post(self, request, *args, **kwargs): # TODO: Handle request.FILES. - - # Convert request.POST to a plain dict (rather than a QueryDict) so that it can be - # stored without data loss in session data - post_data_dict = dict(request.POST.lists()) - - request.session[self.session_key] = post_data_dict, time() + request.session[self.session_key] = request.POST.urlencode(), time() self.remove_old_preview_data() - form = self.get_form() - return JsonResponse({'is_valid': form.is_valid()}) + form = self.get_form(self.get_page(), request.POST) + return JsonResponse({'is_valid': self.is_form_valid(form)}) def error_response(self, page): return render(self.request, 'wagtailadmin/pages/preview_error.html', {'page': page}) def get(self, request, *args, **kwargs): - # Receive the form submission that would typically be posted - # to the view. If submission is valid, return the rendered page; - # if not, re-render the edit form - form = self.get_form() - page = form.instance + page = self.get_page() - if form.is_valid(): - form.save(commit=False) + post_data, timestamp = self.request.session.get(self.session_key) + if not isinstance(post_data, string_types): + post_data = '' + form = self.get_form(page, QueryDict(post_data)) - preview_mode = request.GET.get('mode', page.default_preview_mode) - return page.serve_preview(page.dummy_request(request), - preview_mode) + if not self.is_form_valid(form): + return self.error_response(page) - return self.error_response(page) + form.save(commit=False) + preview_mode = request.GET.get('mode', page.default_preview_mode) + return page.serve_preview(page.dummy_request(request), + preview_mode) class PreviewOnCreate(PreviewOnEdit): @@ -651,7 +646,7 @@ class PreviewOnCreate(PreviewOnEdit): def get_form(self): form = super(PreviewOnCreate, self).get_form() - if form.is_valid(): + if self.is_form_valid(form): # Ensures our unsaved page has a suitable url. form.instance.set_url_path(form.parent_page)