django-simplecms/cms/views.py

205 wiersze
6.7 KiB
Python
Czysty Zwykły widok Historia

import json
import swapper
2020-02-19 19:13:43 +00:00
from django.views.generic import base, detail, edit
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect
from django.core.exceptions import ImproperlyConfigured
from django.contrib.contenttypes.models import ContentType
2019-03-27 15:49:14 +00:00
from django.contrib.auth.mixins import UserPassesTestMixin
2020-02-19 19:13:43 +00:00
#from django.http import HttpResponseRedirect, HttpResponseBadRequest
from .decorators import register_view
from .forms import PageForm, SectionForm, SectionFormSet
2019-03-27 15:49:14 +00:00
Page = swapper.load_model('cms', 'Page')
Section = swapper.load_model('cms', 'Section')
@register_view(Section)
class SectionView:
'''Generic section view'''
template_name = 'cms/sections/section.html'
def setup(self, request, section):
'''Initialize request and section attributes'''
self.request = request
self.section = section
def get_context_data(self, **kwargs):
'''Override this to customize a section's context'''
return kwargs
2020-02-19 19:13:43 +00:00
class SectionFormView(edit.FormMixin, SectionView):
'''Generic section with associated form'''
def post(self, request):
'''Process form'''
form = self.get_form()
if form.is_valid():
form.save(request)
return redirect(self.get_success_url())
return form
2019-03-27 15:49:14 +00:00
class SectionFormSetView(SectionView):
2020-02-19 19:13:43 +00:00
'''Generic section with associated formset'''
2020-02-16 13:54:06 +00:00
formset_class = None
def post(self, request):
'''Process form'''
formset = self.get_formset()
if formset.is_valid():
formset.save(request)
return redirect(self.get_success_url())
return formset
2020-02-16 13:54:06 +00:00
def get_formset(self):
2020-02-16 13:54:06 +00:00
# todo: handle initials!
return self.formset_class()
def get_context_data(self, **kwargs):
if 'formset' not in kwargs:
kwargs['formset'] = self.get_formset()
return super().get_context_data(**kwargs)
2020-02-19 19:13:43 +00:00
class PageView(detail.DetailView):
'''View of a page with heterogeneous (polymorphic) sections'''
2019-03-27 15:49:14 +00:00
model = Page
template_name = 'cms/page.html'
def setup(self, *args, slug='', **kwargs):
'''Supply a default argument for slug'''
super().setup(*args, slug=slug, **kwargs)
def initialize_section(self, section):
section.view = section.__class__.view_class()
section.view.setup(self.request, section)
section.context = section.view.get_context_data(
request = self.request,
section = section,
)
def get(self, request, *args, **kwargs):
'''Initialize sections and render final response'''
try:
page = self.object = self.get_object()
except Http404:
if self.request.user.has_perm('cms_page_create'):
2020-02-19 19:13:43 +00:00
return redirect('cms:updatepage', self.kwargs['slug'])
else:
raise
context = self.get_context_data(**kwargs)
sections = page.sections.all()
for section in sections:
self.initialize_section(section)
context.update({
'page': page,
'sections': sections,
})
return self.render_to_response(context)
def post(self, request, **kwargs):
'''Initialize sections and call the post() function of the correct
section view'''
try:
pk = int(self.request.POST.get('section'))
except:
return HttpResponseBadRequest()
page = self.object = self.get_object()
context = self.get_context_data(**kwargs)
sections = page.sections.all()
for section in sections:
self.initialize_section(section)
if section.pk == pk:
result = section.view.post(request)
if isinstance(result, HttpResponseRedirect):
return result
section.context['form'] = result
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 = Page.objects.filter(menu=True)
context.update({
'pages': pages,
})
return context
2020-02-19 19:13:43 +00:00
class EditPage(UserPassesTestMixin, edit.ModelFormMixin, base.TemplateResponseMixin, base.View):
model = Page
form_class = PageForm
template_name = 'cms/edit.html'
2020-02-19 19:13:43 +00:00
def test_func(self):
return self.request.user.has_perm('cms_page_change')
def setup(self, *args, slug='', **kwargs):
'''Supply a default argument for slug'''
super().setup(*args, slug=slug, **kwargs)
2020-02-17 10:03:31 +00:00
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
2020-02-19 19:13:43 +00:00
kwargs.update({
'label_suffix': '',
'initial': {'slug': self.kwargs['slug']},
})
2020-02-17 10:03:31 +00:00
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if 'formset' not in context:
2020-02-17 10:03:31 +00:00
context['formset'] = SectionFormSet(instance=self.object, form_kwargs={'label_suffix': ''})
fields_per_type = {}
for model, _ in Section.TYPES:
ctype = ContentType.objects.get(
app_label = Section._meta.app_label,
model = model.lower(),
)
fields_per_type[ctype.model] = ['type', 'number'] + ctype.model_class().fields
context.update({
'fields_per_type': json.dumps(fields_per_type),
})
return context
2020-02-19 19:13:43 +00:00
def get_object(self):
try:
return super().get_object()
except:
return None
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
2020-02-19 19:13:43 +00:00
if form.is_valid():
page = form.save()
formset = SectionFormSet(request.POST, request.FILES, instance=page)
if formset.is_valid():
if formset.save():
if page.slug and not page.sections.exists(): # anymore
page.delete()
return HttpResponseRedirect('/')
return HttpResponseRedirect(page.get_absolute_url())
else:
# TODO: show sensible error
formset.errors.append([{}, {'title': ['You have to add sections']}])
formset = SectionFormSet(request.POST, request.FILES)
return self.render_to_response(self.get_context_data(form=form, formset=formset))
2020-02-19 19:13:43 +00:00
class CreatePage(EditPage):
def get_object(self):
pass
2019-08-23 15:19:40 +00:00
2020-02-19 19:13:43 +00:00
class UpdatePage(EditPage):
pass