Refactor page view with Django's black magic powered DetailView&co

This commit is contained in:
Skia 2015-11-25 14:45:18 +01:00
parent d72b18c120
commit b237cdbaae
11 changed files with 163 additions and 185 deletions

View File

@ -4,6 +4,7 @@ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse
from datetime import datetime from datetime import datetime
class User(AbstractBaseUser, PermissionsMixin): class User(AbstractBaseUser, PermissionsMixin):
@ -188,8 +189,6 @@ class Page(models.Model):
p = p.parent p = p.parent
return l return l
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.full_clean() self.full_clean()
# This reset the full_name just before saving to maintain a coherent field quicker for queries than the # This reset the full_name just before saving to maintain a coherent field quicker for queries than the
@ -200,6 +199,12 @@ class Page(models.Model):
c.save() c.save()
super(Page, self).save(*args, **kwargs) super(Page, self).save(*args, **kwargs)
def get_absolute_url(self):
"""
This is needed for black magic powered UpdateView's children
"""
return reverse('core:page', kwargs={'page_name': self.full_name})
def __str__(self): def __str__(self):
return self.get_full_name() return self.get_full_name()

View File

@ -6,48 +6,16 @@
{% elif page_list %} {% elif page_list %}
Page list Page list
{% else %} {% else %}
{{ title }} Not found
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% if view_page %} {% if page %}
<h3>Page</h3> {% block page %}
<p><a href="{% url 'core:page_list' %}">Back to list</a></p> {% endblock %}
{% if user.is_superuser %}
<p><a href="{% url 'core:page_edit' page.get_full_name %}">Edit</a></p>
<p><a href="{% url 'core:page_prop' page.get_full_name %}">Prop</a></p>
{% endif %}
<p>You're seeing the page <strong>{{ page.get_display_name }}</strong></p>
<h3>{{ page.title }}</h3>
<p>{{ page.content }}</p>
{% elif page_list %}
<h3>Page list</h3>
<ul>
{% for p in page_list %}
<li><a href="{% url 'core:page' p.get_full_name %}">{{ p.get_display_name }}</a></li>
{% endfor %}
</ul>
{% elif new_page %}
<h2>{{ title }}</h2>
<p><a href="{% url 'core:page_prop' new_page %}">Create it?</a></p>
{% elif page_prop %}
<h2>Page properties</h2>
<form action="{% url 'core:page_prop' page_name=page.get_full_name %}" method="post">
{% csrf_token %}
{{ page_prop }}
<p><input type="submit" value="Save!" /></p>
</form>
{% elif page_edit %}
<h2>Edit page</h2>
<form action="{% url 'core:page_edit' page_name=page.get_full_name %}" method="post">
{% csrf_token %}
{{ page_edit }}
<p><input type="submit" value="Save!" /></p>
</form>
{% else %} {% else %}
There is no page in this website. <h2>Page does not exist</h2>
<p><a href="{% url 'core:page_prop' new_page %}">Create it?</a></p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -0,0 +1,16 @@
{% extends "core/page.html" %}
{% block page %}
<h3>Page</h3>
<p><a href="{% url 'core:page_list' %}">Back to list</a></p>
{% if user.is_superuser %}
<p><a href="{% url 'core:page_edit' page.get_full_name %}">Edit</a></p>
<p><a href="{% url 'core:page_prop' page.get_full_name %}">Prop</a></p>
{% endif %}
<p>You're seeing the page <strong>{{ page.get_display_name }}</strong></p>
<h3>{{ page.title }}</h3>
<p>{{ page.content }}</p>
{% endblock %}

View File

@ -0,0 +1,13 @@
{% extends "core/page.html" %}
{% block page %}
<h2>Edit page</h2>
<form action="{% url 'core:page_edit' page_name=page.get_full_name %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="Save!" /></p>
</form>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends "core/base.html" %}
{% block title %}
Page list
{% endblock %}
{% block content %}
{% if page_list %}
<h3>Page list</h3>
<ul>
{% for p in page_list %}
<li><a href="{% url 'core:page' p.get_full_name %}">{{ p.get_display_name }}</a></li>
{% endfor %}
</ul>
{% else %}
There is no page in this website.
{% endif %}
{% endblock %}

View File

@ -0,0 +1,13 @@
{% extends "core/page.html" %}
{% block content %}
<h2>Page properties</h2>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="Save!" /></p>
</form>
{% endblock %}

View File

@ -161,7 +161,7 @@ class UserRegistrationTest(SimpleTestCase):
Should create a page correctly Should create a page correctly
""" """
c = Client() c = Client()
response = c.post(reverse('core:page_edit', kwargs={'page_name': 'guy'}), {'parent': '', response = c.post(reverse('core:page_prop', kwargs={'page_name': 'guy'}), {'parent': '',
'name': 'guy', 'name': 'guy',
'title': 'Guy', 'title': 'Guy',
'Content': 'Guyéuyuyé', 'Content': 'Guyéuyuyé',
@ -174,12 +174,12 @@ class UserRegistrationTest(SimpleTestCase):
Should create a page correctly Should create a page correctly
""" """
c = Client() c = Client()
c.post(reverse('core:page_edit', kwargs={'page_name': 'guy'}), {'parent': '', c.post(reverse('core:page_prop', kwargs={'page_name': 'guy'}), {'parent': '',
'name': 'guy', 'name': 'guy',
'title': 'Guy', 'title': 'Guy',
'Content': 'Guyéuyuyé', 'Content': 'Guyéuyuyé',
}) })
response = c.post(reverse('core:page_edit', kwargs={'page_name': 'guy/bibou'}), {'parent': '1', response = c.post(reverse('core:page_prop', kwargs={'page_name': 'guy/bibou'}), {'parent': '1',
'name': 'bibou', 'name': 'bibou',
'title': 'Bibou', 'title': 'Bibou',
'Content': 'Content':
@ -193,12 +193,12 @@ class UserRegistrationTest(SimpleTestCase):
Should display a page correctly Should display a page correctly
""" """
c = Client() c = Client()
c.post(reverse('core:page_edit', kwargs={'page_name': 'guy'}), {'parent': '', c.post(reverse('core:page_prop', kwargs={'page_name': 'guy'}), {'parent': '',
'name': 'guy', 'name': 'guy',
'title': 'Guy', 'title': 'Guy',
'Content': 'Guyéuyuyé', 'Content': 'Guyéuyuyé',
}) })
c.post(reverse('core:page_edit', kwargs={'page_name': 'guy/bibou'}), {'parent': '1', c.post(reverse('core:page_prop', kwargs={'page_name': 'guy/bibou'}), {'parent': '1',
'name': 'bibou', 'name': 'bibou',
'title': 'Bibou', 'title': 'Bibou',
'Content': 'Content':

View File

@ -1,18 +1,18 @@
from django.conf.urls import url from django.conf.urls import url
from . import views from core.views import *
urlpatterns = [ urlpatterns = [
url(r'^$', views.index, name='index'), url(r'^$', index, name='index'),
url(r'^login$', views.login, name='login'), url(r'^login$', login, name='login'),
url(r'^logout$', views.logout, name='logout'), url(r'^logout$', logout, name='logout'),
url(r'^register$', views.register, name='register'), url(r'^register$', register, name='register'),
url(r'^user/$', views.user, name='user_list'), url(r'^user/$', user, name='user_list'),
url(r'^user/(?P<user_id>[0-9]+)/$', views.user, name='user_profile'), url(r'^user/(?P<user_id>[0-9]+)/$', user, name='user_profile'),
url(r'^user/(?P<user_id>[0-9]+)/edit$', views.user_edit, name='user_edit'), url(r'^user/(?P<user_id>[0-9]+)/edit$', user_edit, name='user_edit'),
url(r'^page/$', views.page, name='page_list'), url(r'^page/$', PageListView.as_view(), name='page_list'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/$', views.page, name='page'), url(r'^page/(?P<page_name>[a-z0-9/]*)/$', PageView.as_view(), name='page'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/edit$', views.page_edit, name='page_edit'), url(r'^page/(?P<page_name>[a-z0-9/]*)/edit$', PageEditView.as_view(), name='page_edit'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/prop$', views.page_prop, name='page_prop'), url(r'^page/(?P<page_name>[a-z0-9/]*)/prop$', PagePropView.as_view(), name='page_prop'),
] ]

View File

@ -56,42 +56,3 @@ class UserEditForm(UserChangeForm):
"""We never handle password in this form""" """We never handle password in this form"""
return return
class PagePropForm(forms.ModelForm):
error_css_class = 'error'
required_css_class = 'required'
parent = forms.ModelChoiceField(queryset=Page.objects.all())
def __init__(self, *args, **kwargs):
super(PagePropForm, self).__init__(*args, **kwargs)
self.fields['parent'].required = False
class Meta:
model = Page
fields = ['parent', 'name', 'owner_group', 'edit_group', 'view_group']
def save(self, commit=True):
page = super(PagePropForm, self).save(commit=False)
if commit:
page.save()
return page
class PageEditForm(forms.ModelForm):
error_css_class = 'error'
required_css_class = 'required'
def __init__(self, *args, **kwargs):
super(PageEditForm, self).__init__(*args, **kwargs)
class Meta:
model = Page
fields = ['title', 'content', ]
def save(self, commit=True):
page = super(PageEditForm, self).save(commit=False)
if commit:
page.save()
return page

View File

@ -1,42 +1,44 @@
# This file contains all the views that concern the page model # This file contains all the views that concern the page model
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView
from core.models import Page from core.models import Page
from core.views.forms import PageEditForm, PagePropForm
def page(request, page_name=None): class PageListView(ListView):
""" model = Page
This view displays a page or the link to create it if 404
""" def get_context_data(self, **kwargs):
context = {'title': 'View a Page'} context = super(PageListView, self).get_context_data(**kwargs)
if page_name == None: return context
context['page_list'] = Page.objects.all
return render(request, "core/page.html", context) class PageView(DetailView):
p = Page.get_page_by_full_name(page_name) model = Page
if p is not None:
context['view_page'] = True def get_object(self):
if request.user.has_perm('can_view', p): self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
context['title'] = p.title return self.page
context['page'] = p
context['tests'] = "PAGE_FOUND : "+p.title def get_context_data(self, **kwargs):
context = super(PageView, self).get_context_data(**kwargs)
if "page" in context.keys():
context['tests'] = "PAGE_FOUND : "+context['page'].title
else: else:
context['title'] = "Access denied"
context['tests'] = "PAGE_FOUND_BUT_DENIED"
context['page'] = Page(title="Denied", content="You have no access to this page")
else:
context['title'] = "This page does not exist"
context['new_page'] = page_name
context['tests'] = "PAGE_NOT_FOUND" context['tests'] = "PAGE_NOT_FOUND"
return render(request, "core/page.html", context) context['new_page'] = self.kwargs['page_name']
return context
def page_edit(request, page_name=None): class PagePropView(UpdateView):
""" model = Page
page_edit view, able to create a page, save modifications, and display the page ModelForm fields = ['parent', 'name', 'owner_group', 'edit_group', 'view_group', ]
""" template_name_suffix = '_prop'
context = {'title': 'Edit a page',
'page_name': page_name} def __init__(self, *args, **kwargs):
super(PagePropView, self).__init__(*args, **kwargs)
def get_object(self):
page_name = self.kwargs['page_name']
p = Page.get_page_by_full_name(page_name) p = Page.get_page_by_full_name(page_name)
# New page
if p == None: if p == None:
parent_name = '/'.join(page_name.split('/')[:-1]) parent_name = '/'.join(page_name.split('/')[:-1])
name = page_name.split('/')[-1] name = page_name.split('/')[-1]
@ -45,50 +47,33 @@ def page_edit(request, page_name=None):
else: else:
parent = Page.get_page_by_full_name(parent_name) parent = Page.get_page_by_full_name(parent_name)
p = Page(name=name, parent=parent) p = Page(name=name, parent=parent)
# Saving page self.page = p
if request.method == 'POST': return self.page
f = PageEditForm(request.POST, instance=p)
if f.is_valid():
f.save()
context['tests'] = "PAGE_SAVED"
else:
context['tests'] = "PAGE_NOT_SAVED"
# Default: display the edit form without change
else:
context['tests'] = "POST_NOT_RECEIVED"
f = PageEditForm(instance=p)
context['page'] = p
context['page_edit'] = f.as_p()
return render(request, 'core/page.html', context)
def page_prop(request, page_name=None): def get_context_data(self, **kwargs):
""" context = super(PagePropView, self).get_context_data(**kwargs)
page_prop view, able to change a page's properties if "page" in context.keys():
""" context['tests'] = "PAGE_FOUND : "+context['page'].title
context = {'title': 'Page properties',
'page_name': page_name}
p = Page.get_page_by_full_name(page_name)
# New page
if p == None:
parent_name = '/'.join(page_name.split('/')[:-1])
name = page_name.split('/')[-1]
if parent_name == "":
p = Page(name=name)
else: else:
parent = Page.get_page_by_full_name(parent_name) context['tests'] = "PAGE_NOT_FOUND"
p = Page(name=name, parent=parent) context['new_page'] = self.kwargs['page_name']
# Saving page return context
if request.method == 'POST':
f = PagePropForm(request.POST, instance=p) class PageEditView(UpdateView):
if f.is_valid(): model = Page
f.save() fields = ['title', 'content',]
context['tests'] = "PAGE_SAVED" template_name_suffix = '_edit'
def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
return self.page
def get_context_data(self, **kwargs):
context = super(PageEditView, self).get_context_data(**kwargs)
if "page" in context.keys():
context['tests'] = "PAGE_FOUND : "+context['page'].title
else: else:
context['tests'] = "PAGE_NOT_SAVED" context['tests'] = "PAGE_NOT_FOUND"
# Default: display the edit form without change context['new_page'] = self.kwargs['page_name']
else: return context
context['tests'] = "POST_NOT_RECEIVED"
f = PagePropForm(instance=p)
context['page'] = p
context['page_prop'] = f.as_p()
return render(request, 'core/page.html', context)

View File

@ -2,10 +2,6 @@ from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse from django.http import HttpResponse
from django.db import models from django.db import models
import logging
logging.basicConfig(level=logging.DEBUG)
def index(request, context=None): def index(request, context=None):
if context == None: if context == None:
return render(request, "core/index.html", {'title': 'Bienvenue!'}) return render(request, "core/index.html", {'title': 'Bienvenue!'})