kopia lustrzana https://github.com/wagtail/wagtail
Fix timezone handling of `TemplateResponse`s for users with a custom timezone
The PR #9628 missed the cases, where a TemplateResponse is used, which defers the rendering to a point outside the override_tz() context manager. This change re-uses the existing handling for the user's preferred language. Fixes #10243pull/10249/head
rodzic
8705124eaf
commit
0016ee7dfd
|
@ -45,6 +45,7 @@ Changelog
|
|||
* Fix: Ensure that document search results count shows the correct all matches, not the paginate total (Andy Chosak)
|
||||
* Fix: Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
|
||||
* Fix: Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
|
||||
* Fix: Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
|
||||
* Docs: Add code block to make it easier to understand contribution docs (Suyash Singh)
|
||||
* Docs: Add new "Icons" page for icons customisation and reuse across the admin interface (Coen van der Kamp)
|
||||
* Docs: Fix broken formatting for MultiFieldPanel / FieldRowPanel permission kwarg docs (Matt Westcott)
|
||||
|
@ -85,6 +86,7 @@ Changelog
|
|||
|
||||
* Fix: Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
|
||||
* Fix: Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
|
||||
* Fix: Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
|
||||
|
||||
|
||||
4.2.1 (13.03.2023)
|
||||
|
@ -260,6 +262,7 @@ Changelog
|
|||
|
||||
* Fix: Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
|
||||
* Fix: Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
|
||||
* Fix: Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
|
||||
|
||||
|
||||
4.1.3 (13.03.2023)
|
||||
|
|
|
@ -15,3 +15,4 @@ depth: 1
|
|||
|
||||
* Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
|
||||
* Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
|
||||
* Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
|
||||
|
|
|
@ -15,3 +15,4 @@ depth: 1
|
|||
|
||||
* Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
|
||||
* Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
|
||||
* Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
|
||||
|
|
|
@ -59,6 +59,7 @@ Support for adding custom validation logic to StreamField blocks has been formal
|
|||
* Ensure that document search results count shows the correct all matches, not the paginate total (Andy Chosak)
|
||||
* Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
|
||||
* Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
|
||||
* Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
|
||||
|
||||
### Documentation
|
||||
|
||||
|
|
|
@ -182,29 +182,30 @@ def require_admin_access(view_func):
|
|||
if preferred_language:
|
||||
with override(preferred_language):
|
||||
response = view_func(request, *args, **kwargs)
|
||||
|
||||
if hasattr(response, "render"):
|
||||
# If the response has a render() method, Django treats it
|
||||
# like a TemplateResponse, so we should do the same
|
||||
# In this case, we need to guarantee that when the TemplateResponse
|
||||
# is rendered, it is done within the override context manager
|
||||
# or the user preferred_language will not be used
|
||||
# (this could be replaced with simply rendering the TemplateResponse
|
||||
# for simplicity but this does remove some of its middleware modification
|
||||
# potential)
|
||||
render = response.render
|
||||
|
||||
def overridden_render(response):
|
||||
with override(preferred_language):
|
||||
return render()
|
||||
|
||||
response.render = types.MethodType(
|
||||
overridden_render, response
|
||||
)
|
||||
# decorate the response render method with the override context manager
|
||||
return response
|
||||
else:
|
||||
return view_func(request, *args, **kwargs)
|
||||
response = view_func(request, *args, **kwargs)
|
||||
|
||||
if hasattr(response, "render"):
|
||||
# If the response has a render() method, Django treats it
|
||||
# like a TemplateResponse, so we should do the same
|
||||
# In this case, we need to guarantee that when the TemplateResponse
|
||||
# is rendered, it is done within the override context manager
|
||||
# or the user preferred_language/timezone will not be used
|
||||
# (this could be replaced with simply rendering the TemplateResponse
|
||||
# for simplicity but this does remove some of its middleware modification
|
||||
# potential)
|
||||
render = response.render
|
||||
|
||||
def overridden_render(response):
|
||||
with override_tz(time_zone):
|
||||
if preferred_language:
|
||||
with override(preferred_language):
|
||||
return render()
|
||||
return render()
|
||||
|
||||
response.render = types.MethodType(overridden_render, response)
|
||||
# decorate the response render method with the override context manager
|
||||
return response
|
||||
|
||||
except PermissionDenied:
|
||||
if request.headers.get("x-requested-with") == "XMLHttpRequest":
|
||||
|
|
|
@ -444,6 +444,100 @@ class TestPageEdit(WagtailTestUtils, TestCase):
|
|||
"This publishing schedule will only take effect after you have published",
|
||||
)
|
||||
|
||||
def test_edit_post_scheduled_custom_timezone(self):
|
||||
# Set user's timezone to something different from the server timezone
|
||||
UserProfile.objects.update_or_create(
|
||||
user=self.user,
|
||||
defaults={"current_time_zone": "Asia/Jakarta"},
|
||||
)
|
||||
|
||||
post_data = {
|
||||
"title": "I've been edited!",
|
||||
"content": "Some content",
|
||||
"slug": "hello-world",
|
||||
"go_live_at": "2022-03-20 06:00",
|
||||
}
|
||||
edit_url = reverse("wagtailadmin_pages:edit", args=(self.child_page.id,))
|
||||
response = self.client.post(edit_url, post_data, follow=True)
|
||||
html = response.content.decode()
|
||||
|
||||
# Should be redirected to the edit page again
|
||||
self.assertRedirects(response, edit_url, 302, 200)
|
||||
|
||||
child_page_new = SimplePage.objects.get(id=self.child_page.id)
|
||||
|
||||
# The page will still be live
|
||||
self.assertTrue(child_page_new.live)
|
||||
|
||||
# A revision with approved_go_live_at should not exist
|
||||
self.assertFalse(
|
||||
Revision.page_revisions.filter(object_id=child_page_new.id)
|
||||
.exclude(approved_go_live_at__isnull=True)
|
||||
.exists()
|
||||
)
|
||||
|
||||
# But a revision with go_live_at in their content json *should* exist
|
||||
if settings.USE_TZ:
|
||||
# The saved timestamp should be in UTC
|
||||
self.assertTrue(
|
||||
Revision.page_revisions.filter(
|
||||
object_id=child_page_new.id,
|
||||
content__go_live_at="2022-03-19T23:00:00Z",
|
||||
).exists()
|
||||
)
|
||||
else:
|
||||
# Without TZ support, just use the submitted timestamp as-is
|
||||
self.assertTrue(
|
||||
Revision.page_revisions.filter(
|
||||
object_id=child_page_new.id,
|
||||
content__go_live_at="2022-03-20T06:00:00",
|
||||
).exists()
|
||||
)
|
||||
|
||||
# Should show the draft go_live_at under the "Once published" label
|
||||
# and should be in the user's timezone
|
||||
self.assertContains(
|
||||
response,
|
||||
'<div class="w-label-3">Once published:</div>',
|
||||
html=True,
|
||||
count=1,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<span class="w-text-primary">Go-live:</span> March 20, 2022, 6 a.m.',
|
||||
html=True,
|
||||
count=1,
|
||||
)
|
||||
|
||||
# Should show the "Edit schedule" button
|
||||
self.assertTagInHTML(
|
||||
'<button type="button" data-a11y-dialog-show="schedule-publishing-dialog">Edit schedule</button>',
|
||||
html,
|
||||
count=1,
|
||||
allow_extra_attrs=True,
|
||||
)
|
||||
|
||||
# Should show the dialog template pointing to the [data-edit-form] selector as the root
|
||||
self.assertTagInHTML(
|
||||
'<div id="schedule-publishing-dialog" class="w-dialog publishing" data-dialog-root-selector="[data-edit-form]">',
|
||||
html,
|
||||
count=1,
|
||||
allow_extra_attrs=True,
|
||||
)
|
||||
|
||||
# Should show the input with the correct value in the user's timezone
|
||||
self.assertTagInHTML(
|
||||
'<input type="text" name="go_live_at" value="2022-03-20 06:00">',
|
||||
html,
|
||||
count=1,
|
||||
allow_extra_attrs=True,
|
||||
)
|
||||
|
||||
self.assertContains(
|
||||
response,
|
||||
"This publishing schedule will only take effect after you have published",
|
||||
)
|
||||
|
||||
def test_schedule_panel_without_publish_permission(self):
|
||||
editor = self.create_user("editor", password="password")
|
||||
editor.groups.add(Group.objects.get(name="Editors"))
|
||||
|
|
Ładowanie…
Reference in New Issue