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,94 +1,79 @@
# 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
"""
context = {'title': 'View a Page'}
if page_name == None:
context['page_list'] = Page.objects.all
return render(request, "core/page.html", context)
p = Page.get_page_by_full_name(page_name)
if p is not None:
context['view_page'] = True
if request.user.has_perm('can_view', p):
context['title'] = p.title
context['page'] = p
context['tests'] = "PAGE_FOUND : "+p.title
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"
return render(request, "core/page.html", context)
def page_edit(request, page_name=None): def get_context_data(self, **kwargs):
""" context = super(PageListView, self).get_context_data(**kwargs)
page_edit view, able to create a page, save modifications, and display the page ModelForm return context
"""
context = {'title': 'Edit a page',
'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:
parent = Page.get_page_by_full_name(parent_name)
p = Page(name=name, parent=parent)
# Saving page
if request.method == 'POST':
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): class PageView(DetailView):
""" model = Page
page_prop view, able to change a page's properties
""" def get_object(self):
context = {'title': 'Page properties', self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
'page_name': page_name} return self.page
p = Page.get_page_by_full_name(page_name)
# New page def get_context_data(self, **kwargs):
if p == None: context = super(PageView, self).get_context_data(**kwargs)
parent_name = '/'.join(page_name.split('/')[:-1]) if "page" in context.keys():
name = page_name.split('/')[-1] context['tests'] = "PAGE_FOUND : "+context['page'].title
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 PagePropView(UpdateView):
if f.is_valid(): model = Page
f.save() fields = ['parent', 'name', 'owner_group', 'edit_group', 'view_group', ]
context['tests'] = "PAGE_SAVED" template_name_suffix = '_prop'
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)
if p == None:
parent_name = '/'.join(page_name.split('/')[:-1])
name = page_name.split('/')[-1]
if parent_name == "":
p = Page(name=name)
else:
parent = Page.get_page_by_full_name(parent_name)
p = Page(name=name, parent=parent)
self.page = p
return self.page
def get_context_data(self, **kwargs):
context = super(PagePropView, 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) class PageEditView(UpdateView):
context['page'] = p model = Page
context['page_prop'] = f.as_p() fields = ['title', 'content',]
return render(request, 'core/page.html', context) 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:
context['tests'] = "PAGE_NOT_FOUND"
context['new_page'] = self.kwargs['page_name']
return 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!'})