Skip to content

Commit 2bd4a48

Browse files
committed
implemented async flatpages
1 parent 154e9a3 commit 2bd4a48

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

django_async_extensions/acontrib/flatpages/__init__.py

Whitespace-only changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django.urls import path
2+
3+
from django_async_extensions.acontrib.flatpages import views
4+
5+
urlpatterns = [
6+
path(
7+
"<path:url>",
8+
views.flatpage,
9+
name="django_async_extensions.acontrib.flatpages.views.flatpage",
10+
),
11+
]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from asgiref.sync import sync_to_async
2+
from django.conf import settings
3+
from django.contrib.sites.shortcuts import get_current_site
4+
from django.http import Http404, HttpResponse, HttpResponsePermanentRedirect
5+
from django.shortcuts import aget_object_or_404
6+
from django.template import loader
7+
from django.utils.safestring import mark_safe
8+
from django.views.decorators.csrf import csrf_protect
9+
10+
from django_async_extensions.acontrib.flatpages.models import AsyncFlatPage
11+
12+
DEFAULT_TEMPLATE = "flatpages/default.html"
13+
14+
# This view is called from AsyncFlatpageFallbackMiddleware.process_response
15+
# when a 404 is raised, which often means CsrfViewMiddleware.process_view
16+
# has not been called even if CsrfViewMiddleware is installed. So we need
17+
# to use @csrf_protect, in case the template needs {% csrf_token %}.
18+
# However, we can't just wrap this view; if no matching flatpage exists,
19+
# or a redirect is required for authentication, the 404 needs to be returned
20+
# without any CSRF checks. Therefore, we only
21+
# CSRF protect the internal implementation.
22+
23+
24+
async def flatpage(request, url):
25+
"""
26+
Public interface to the flat page view.
27+
28+
Models: `flatpages.flatpages`
29+
Templates: Uses the template defined by the ``template_name`` field,
30+
or :template:`flatpages/default.html` if template_name is not defined.
31+
Context:
32+
flatpage
33+
`flatpages.flatpages` object
34+
"""
35+
if not url.startswith("/"):
36+
url = "/" + url
37+
site = await sync_to_async(get_current_site)(request)
38+
site_id = site.id
39+
try:
40+
f = await aget_object_or_404(AsyncFlatPage, url=url, sites=site_id)
41+
except Http404:
42+
if not url.endswith("/") and settings.APPEND_SLASH:
43+
url += "/"
44+
f = await aget_object_or_404(AsyncFlatPage, url=url, sites=site_id)
45+
return HttpResponsePermanentRedirect("%s/" % request.path)
46+
else:
47+
raise
48+
return await render_flatpage(request, f)
49+
50+
51+
@csrf_protect
52+
async def render_flatpage(request, f):
53+
"""
54+
Internal interface to the flat page view.
55+
"""
56+
# If registration is required for accessing this page, and the user isn't
57+
# logged in, redirect to the login page.
58+
user = await request.auser()
59+
if f.registration_required and not user.is_authenticated:
60+
from django.contrib.auth.views import redirect_to_login
61+
62+
return redirect_to_login(request.path)
63+
if f.template_name:
64+
template = loader.select_template((f.template_name, DEFAULT_TEMPLATE))
65+
else:
66+
template = loader.get_template(DEFAULT_TEMPLATE)
67+
68+
# To avoid having to always use the "|safe" filter in flatpage templates,
69+
# mark the title and content as already safe (since they are raw HTML
70+
# content in the first place).
71+
f.title = mark_safe(f.title) # noqa: S308
72+
f.content = mark_safe(f.content) # noqa: S308
73+
74+
return HttpResponse(template.render({"flatpage": f}, request))

0 commit comments

Comments
 (0)