kopia lustrzana https://github.com/rtts/django-simplecms
342 wiersze
9.1 KiB
Python
342 wiersze
9.1 KiB
Python
"""
|
|
Some simple section views, as well as the "real" Django views that
|
|
make the simple views possible.
|
|
"""
|
|
|
|
import json
|
|
|
|
from django.contrib.auth.mixins import UserPassesTestMixin
|
|
from django.http import (
|
|
Http404,
|
|
HttpResponse,
|
|
HttpResponseBadRequest,
|
|
HttpResponseRedirect,
|
|
)
|
|
from django.shortcuts import redirect
|
|
from django.utils.decorators import method_decorator
|
|
from django.views.decorators.cache import never_cache
|
|
from django.views.generic import base, detail, edit
|
|
|
|
from . import registry
|
|
from .forms import ContactForm, PageForm, SectionForm
|
|
|
|
|
|
class SectionView:
|
|
"""
|
|
Generic section view.
|
|
"""
|
|
|
|
template_name = "cms/sections/section.html"
|
|
|
|
def __init__(self, request):
|
|
self.request = request
|
|
|
|
def get_context_data(self, **kwargs):
|
|
return kwargs
|
|
|
|
|
|
class SectionFormView(SectionView):
|
|
"""
|
|
Generic section with associated form.
|
|
"""
|
|
|
|
form_class = None
|
|
success_url = None
|
|
|
|
def get_context_data(self, **kwargs):
|
|
if "form" not in kwargs:
|
|
kwargs["form"] = self.get_form()
|
|
return kwargs
|
|
|
|
def form_valid(self, form):
|
|
form.save()
|
|
return HttpResponseRedirect(self.success_url)
|
|
|
|
def get_form_kwargs(self):
|
|
return {}
|
|
|
|
def get_form(self, method="get"):
|
|
form_class = self.form_class
|
|
kwargs = self.get_form_kwargs()
|
|
if method == "post":
|
|
kwargs.update(
|
|
{
|
|
"data": self.request.POST,
|
|
"files": self.request.FILES,
|
|
}
|
|
)
|
|
return form_class(**kwargs)
|
|
|
|
|
|
class ContactSectionFormView(SectionFormView):
|
|
"""
|
|
Generic section with a contact form.
|
|
"""
|
|
|
|
form_class = ContactForm
|
|
|
|
def form_valid(self, form):
|
|
response = HttpResponse(status=302)
|
|
response["Location"] = form.save(self.object.href, self.object.subject)
|
|
return response
|
|
|
|
|
|
class PageView(detail.DetailView):
|
|
"""
|
|
View of a page with heterogeneous sections.
|
|
"""
|
|
|
|
model = registry.page_class
|
|
template_name = "cms/page.html"
|
|
|
|
def setup(self, *args, slug="", **kwargs):
|
|
"""
|
|
Supply a default argument for slug.
|
|
"""
|
|
|
|
super().setup(*args, slug=slug, **kwargs)
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
"""
|
|
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
|
|
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
|
|
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()
|
|
context.update(
|
|
{
|
|
"page": page,
|
|
"sections": sections,
|
|
}
|
|
)
|
|
return self.render_to_response(context)
|
|
|
|
def post(self, request, **kwargs):
|
|
"""
|
|
Call the post() method of the correct section view.
|
|
"""
|
|
|
|
try:
|
|
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)
|
|
form = view.get_form(method="post")
|
|
if form.is_valid():
|
|
view.object = section
|
|
return view.form_valid(form)
|
|
section.invalid_form = form
|
|
|
|
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)
|
|
context.update(
|
|
{
|
|
"pages": pages,
|
|
}
|
|
)
|
|
return context
|
|
|
|
|
|
@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
|
|
template_name = "cms/edit.html"
|
|
|
|
def test_func(self):
|
|
"""
|
|
Only allow users with the correct permissions.
|
|
"""
|
|
|
|
app_label = registry.page_class._meta.app_label
|
|
model_name = registry.page_class._meta.model_name
|
|
return self.request.user.has_perm(f"{app_label}.change_{model_name}")
|
|
|
|
def get_form_kwargs(self):
|
|
"""
|
|
Set the default slug to the current URL for new pages.
|
|
"""
|
|
|
|
kwargs = super().get_form_kwargs()
|
|
if "slug" in self.kwargs:
|
|
kwargs.update({"initial": {"slug": self.kwargs["slug"]}})
|
|
return kwargs
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""
|
|
Populate the fields_per_type dict for use in JS.
|
|
"""
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
context["fields_per_type"] = json.dumps(registry.get_fields_per_type())
|
|
return context
|
|
|
|
def get_object(self):
|
|
"""
|
|
Prevent 404 by serving the new object form.
|
|
"""
|
|
|
|
try:
|
|
return super().get_object()
|
|
except Http404:
|
|
return None
|
|
|
|
def get(self, *args, **kwargs):
|
|
"""
|
|
Handle GET requests.
|
|
"""
|
|
|
|
self.object = self.get_object()
|
|
return self.render_to_response(self.get_context_data(**kwargs))
|
|
|
|
def post(self, *args, **kwargs):
|
|
"""
|
|
Handle POST requests.
|
|
"""
|
|
|
|
self.object = self.get_object()
|
|
form = self.get_form()
|
|
|
|
if form.is_valid():
|
|
page = form.save()
|
|
if page:
|
|
return HttpResponseRedirect(page.get_absolute_url())
|
|
return HttpResponseRedirect("/")
|
|
return self.render_to_response(self.get_context_data(form=form, **kwargs))
|
|
|
|
|
|
class CreatePage(EditPage):
|
|
"""
|
|
View for creating new pages.
|
|
"""
|
|
|
|
def get_object(self):
|
|
return registry.page_class()
|
|
|
|
|
|
class UpdatePage(EditPage):
|
|
"""
|
|
View for editing existing pages.
|
|
"""
|
|
|
|
|
|
@method_decorator(never_cache, name="dispatch")
|
|
class EditSection(
|
|
UserPassesTestMixin, edit.ModelFormMixin, base.TemplateResponseMixin, base.View
|
|
):
|
|
"""
|
|
Base view to edit a specific section.
|
|
"""
|
|
|
|
model = registry.section_class
|
|
form_class = SectionForm
|
|
template_name = "cms/edit.html"
|
|
|
|
def test_func(self):
|
|
"""
|
|
Only allow users with the correct permissions.
|
|
"""
|
|
|
|
app_label = registry.section_class._meta.app_label
|
|
model_name = registry.section_class._meta.model_name
|
|
return self.request.user.has_perm(f"{app_label}.change_{model_name}")
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super().get_form_kwargs()
|
|
kwargs.update(
|
|
{
|
|
"prefix": "section",
|
|
}
|
|
)
|
|
return kwargs
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["fields_per_type"] = json.dumps(registry.get_fields_per_type())
|
|
return context
|
|
|
|
def get_object(self, queryset=None):
|
|
try:
|
|
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:
|
|
section = self.page.sections.get(number=self.kwargs["number"])
|
|
except self.page.sections.DoesNotExist:
|
|
raise Http404()
|
|
return section
|
|
|
|
def get(self, *args, **kwargs):
|
|
self.object = self.get_object()
|
|
return self.render_to_response(self.get_context_data(**kwargs))
|
|
|
|
def post(self, *args, **kwargs):
|
|
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:
|
|
return HttpResponseRedirect("/")
|
|
return self.render_to_response(self.get_context_data(form=form, **kwargs))
|
|
|
|
|
|
class CreateSection(EditSection):
|
|
"""
|
|
View for creating new sections.
|
|
"""
|
|
|
|
def get_section(self):
|
|
return registry.section_class(page=self.page)
|
|
|
|
|
|
class UpdateSection(EditSection):
|
|
"""
|
|
View for editing existing sections.
|
|
"""
|