django-simplecms/cms/views.py

265 wiersze
8.2 KiB
Python
Czysty Zwykły widok Historia

import json
2021-07-03 23:59:48 +00:00
from django.contrib.auth.mixins import UserPassesTestMixin
from django.http import Http404, HttpResponseBadRequest, HttpResponseRedirect
from django.shortcuts import redirect
from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache
2021-07-03 23:59:48 +00:00
from django.views.generic import base, detail, edit
from . import registry
from .forms import PageForm, SectionForm
2019-03-27 15:49:14 +00:00
2021-07-03 23:59:48 +00:00
class SectionView:
2021-07-03 23:59:48 +00:00
"""Generic section view"""
template_name = "cms/sections/section.html"
def __init__(self, request):
self.request = request
def get_context_data(self, **kwargs):
return kwargs
2021-07-03 23:59:48 +00:00
2020-03-29 00:54:56 +00:00
class SectionFormView(SectionView):
2021-07-03 23:59:48 +00:00
"""Generic section with associated form"""
2020-03-29 00:54:56 +00:00
form_class = None
success_url = None
2020-03-29 00:54:56 +00:00
def get_context_data(self, **kwargs):
2021-07-03 23:59:48 +00:00
if "form" not in kwargs:
kwargs["form"] = self.get_form()
2020-03-29 00:54:56 +00:00
return kwargs
def form_valid(self, form):
form.save()
return HttpResponseRedirect(self.success_url)
def get_form_kwargs(self):
return {}
2021-07-03 23:59:48 +00:00
def get_form(self, method="get"):
2020-03-29 00:54:56 +00:00
form_class = self.form_class
kwargs = self.get_form_kwargs()
2021-07-03 23:59:48 +00:00
if method == "post":
kwargs.update(
{
"data": self.request.POST,
"files": self.request.FILES,
}
)
2020-03-29 00:54:56 +00:00
return form_class(**kwargs)
2021-07-03 23:59:48 +00:00
2020-02-19 19:13:43 +00:00
class PageView(detail.DetailView):
2021-07-03 23:59:48 +00:00
"""View of a page with heterogeneous sections"""
model = registry.page_class
2021-07-03 23:59:48 +00:00
template_name = "cms/page.html"
2019-03-27 15:49:14 +00:00
2021-07-03 23:59:48 +00:00
def setup(self, *args, slug="", **kwargs):
"""Supply a default argument for slug"""
super().setup(*args, slug=slug, **kwargs)
def get(self, request, *args, **kwargs):
2021-07-03 23:59:48 +00:00
"""Instantiate section views and render final response"""
try:
page = self.object = self.get_object()
except Http404:
app_label = registry.page_class._meta.app_label
model_name = registry.page_class._meta.model_name
2021-07-03 23:59:48 +00:00
if self.kwargs["slug"] == "":
page = registry.page_class(title="Homepage", slug="")
page.save()
self.object = page
# Special case: Don't serve 404 pages to authorized users,
# but redirect to the edit page form with the slug pre-filled
2021-07-03 23:59:48 +00:00
elif self.request.user.has_perm(f"{app_label}.change_{model_name}"):
return redirect("cms:updatepage", slug=self.kwargs["slug"])
else:
raise
context = self.get_context_data(**kwargs)
sections = page.sections.all()
2021-07-03 23:59:48 +00:00
context.update(
{
"page": page,
"sections": sections,
}
)
return self.render_to_response(context)
def post(self, request, **kwargs):
2021-07-03 23:59:48 +00:00
"""Call the post() method of the correct section view"""
try:
2021-07-03 23:59:48 +00:00
pk = int(self.request.POST.get("section"))
except Exception:
return HttpResponseBadRequest()
page = self.object = self.get_object()
context = self.get_context_data(**kwargs)
sections = page.sections.all()
for section in sections:
if section.pk == pk:
view = registry.get_view(section, request)
2021-07-03 23:59:48 +00:00
form = view.get_form(method="post")
2020-03-29 00:54:56 +00:00
if form.is_valid():
return view.form_valid(form)
section.invalid_form = form
2021-07-03 23:59:48 +00:00
context.update(
{
"page": page,
"sections": sections,
}
)
return self.render_to_response(context)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pages = registry.page_class.objects.filter(menu=True)
2021-07-03 23:59:48 +00:00
context.update(
{
"pages": pages,
}
)
return context
2021-07-03 23:59:48 +00:00
@method_decorator(never_cache, name="dispatch")
class EditPage(
UserPassesTestMixin, edit.ModelFormMixin, base.TemplateResponseMixin, base.View
):
"""Base view with nested forms for editing the page and all its sections"""
model = registry.page_class
form_class = PageForm
2021-07-03 23:59:48 +00:00
template_name = "cms/edit.html"
2020-02-19 19:13:43 +00:00
def test_func(self):
2021-07-03 23:59:48 +00:00
"""Only allow users with the correct permissions"""
2020-05-20 16:29:22 +00:00
app_label = registry.page_class._meta.app_label
model_name = registry.page_class._meta.model_name
2021-07-03 23:59:48 +00:00
return self.request.user.has_perm(f"{app_label}.change_{model_name}")
2020-02-19 19:13:43 +00:00
2020-02-17 10:03:31 +00:00
def get_form_kwargs(self):
2021-07-03 23:59:48 +00:00
"""Set the default slug to the current URL for new pages"""
2020-02-17 10:03:31 +00:00
kwargs = super().get_form_kwargs()
2021-07-03 23:59:48 +00:00
if "slug" in self.kwargs:
kwargs.update({"initial": {"slug": self.kwargs["slug"]}})
2020-02-17 10:03:31 +00:00
return kwargs
def get_context_data(self, **kwargs):
2021-07-03 23:59:48 +00:00
"""Populate the fields_per_type dict for use in javascript"""
context = super().get_context_data(**kwargs)
2021-07-03 23:59:48 +00:00
context["fields_per_type"] = json.dumps(registry.get_fields_per_type())
return context
2020-02-19 19:13:43 +00:00
def get_object(self):
2021-07-03 23:59:48 +00:00
"""Prevent 404 by serving the new object form"""
2020-02-19 19:13:43 +00:00
try:
return super().get_object()
2020-03-13 08:39:27 +00:00
except Http404:
2020-02-19 19:13:43 +00:00
return None
def get(self, *args, **kwargs):
2021-07-03 23:59:48 +00:00
"""Handle GET requests"""
2020-05-20 16:29:22 +00:00
self.object = self.get_object()
return self.render_to_response(self.get_context_data(**kwargs))
def post(self, *args, **kwargs):
2021-07-03 23:59:48 +00:00
"""Handle POST requests"""
2020-05-20 16:29:22 +00:00
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
page = form.save()
if page:
return HttpResponseRedirect(page.get_absolute_url())
2021-07-03 23:59:48 +00:00
return HttpResponseRedirect("/")
return self.render_to_response(self.get_context_data(form=form, **kwargs))
2021-07-03 23:59:48 +00:00
2020-02-19 19:13:43 +00:00
class CreatePage(EditPage):
2021-07-03 23:59:48 +00:00
"""View for creating new pages"""
2020-02-19 19:13:43 +00:00
def get_object(self):
return registry.page_class()
2019-08-23 15:19:40 +00:00
2021-07-03 23:59:48 +00:00
2020-02-19 19:13:43 +00:00
class UpdatePage(EditPage):
2021-07-03 23:59:48 +00:00
"""View for editing existing pages"""
2021-07-03 23:59:48 +00:00
@method_decorator(never_cache, name="dispatch")
class EditSection(
UserPassesTestMixin, edit.ModelFormMixin, base.TemplateResponseMixin, base.View
):
model = registry.section_class
form_class = SectionForm
2021-07-03 23:59:48 +00:00
template_name = "cms/edit.html"
def test_func(self):
2021-07-03 23:59:48 +00:00
"""Only allow users with the correct permissions"""
2020-05-20 16:29:22 +00:00
app_label = registry.section_class._meta.app_label
model_name = registry.section_class._meta.model_name
2021-07-03 23:59:48 +00:00
return self.request.user.has_perm(f"{app_label}.change_{model_name}")
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
2021-07-03 23:59:48 +00:00
kwargs.update(
{
"prefix": "section",
}
)
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
2021-07-03 23:59:48 +00:00
context["fields_per_type"] = json.dumps(registry.get_fields_per_type())
return context
def get_object(self, queryset=None):
try:
2021-07-03 23:59:48 +00:00
self.page = registry.page_class.objects.get(slug=self.kwargs["slug"])
except registry.page_class.DoesNotExist:
raise Http404()
return self.get_section()
def get_section(self):
try:
2021-07-03 23:59:48 +00:00
section = self.page.sections.get(number=self.kwargs["number"])
except self.page.sections.DoesNotExist:
raise Http404()
return section
def get(self, *args, **kwargs):
2020-05-20 16:29:22 +00:00
self.object = self.get_object()
return self.render_to_response(self.get_context_data(**kwargs))
def post(self, *args, **kwargs):
2020-05-20 16:29:22 +00:00
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
section = form.save()
if section:
return HttpResponseRedirect(section.get_absolute_url())
elif self.page.sections.exists():
return HttpResponseRedirect(self.page.get_absolute_url())
else:
2021-07-03 23:59:48 +00:00
return HttpResponseRedirect("/")
return self.render_to_response(self.get_context_data(form=form, **kwargs))
2021-07-03 23:59:48 +00:00
class CreateSection(EditSection):
def get_section(self):
return registry.section_class(page=self.page)
2021-07-03 23:59:48 +00:00
class UpdateSection(EditSection):
pass