Add complete revision and history handling in the wiki

This commit is contained in:
Skia 2015-12-02 11:09:50 +01:00
parent 80926dd4ac
commit 92f68f5b42
8 changed files with 169 additions and 36 deletions

View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('core', '0012_auto_20151127_1504'),
]
operations = [
migrations.CreateModel(
name='PageRev',
fields=[
('id', models.AutoField(primary_key=True, auto_created=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, blank=True, verbose_name='page title')),
('content', models.TextField(blank=True, verbose_name='page content')),
('date', models.DateTimeField(auto_now=True, verbose_name='date')),
('author', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='page_rev')),
],
options={
'ordering': ['date'],
},
),
migrations.RemoveField(
model_name='page',
name='content',
),
migrations.RemoveField(
model_name='page',
name='title',
),
migrations.AddField(
model_name='pagerev',
name='page',
field=models.ForeignKey(to='core.Page', related_name='revisions'),
),
]

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0013_auto_20151202_0814'),
]
operations = [
migrations.RemoveField(
model_name='page',
name='revision',
),
]

View File

@ -151,10 +151,6 @@ class Page(GroupManagedObject, models.Model):
query, but don't rely on it when playing with a Page object, use get_full_name() instead!
"""
name = models.CharField(_('page name'), max_length=30, blank=False)
# TODO: move title and content to PageRev class with a OneToOne field
title = models.CharField(_("page title"), max_length=255, blank=True)
content = models.TextField(_("page content"), blank=True)
revision = models.PositiveIntegerField(_("current revision"), default=1)
is_locked = models.BooleanField(_("page mutex"), default=False)
parent = models.ForeignKey('self', related_name="children", null=True, blank=True, on_delete=models.SET_NULL)
# Attention: this field may not be valid until you call save(). It's made for fast query, but don't rely on it when
@ -237,4 +233,23 @@ class Page(GroupManagedObject, models.Model):
def get_display_name(self):
return self.get_full_name()
class PageRev(models.Model):
title = models.CharField(_("page title"), max_length=255, blank=True)
content = models.TextField(_("page content"), blank=True)
date = models.DateTimeField(_('date'), auto_now=True)
author = models.ForeignKey(User, related_name='page_rev')
page = models.ForeignKey(Page, related_name='revisions')
class Meta:
ordering = ['date',]
def get_absolute_url(self):
"""
This is needed for black magic powered UpdateView's children
"""
return reverse('core:page', kwargs={'page_name': self.page.full_name})
def __str__(self):
return str(self.__dict__)

View File

@ -7,9 +7,16 @@
<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>
<p>You're seeing the page <strong>{{ page.get_display_name }}</strong> -
<a href="{% url 'core:page_hist' page.get_full_name %}">History</a></p>
{% if rev %}
<h4>This may not be the last update, you are seeing revision {{ rev.id }}!</h4>
<h3>{{ rev.title }}</h3>
<p>{{ rev.content }}</p>
{% else %}
<h3>{{ page.revisions.last.title }}</h3>
<p>{{ page.revisions.last.content }}</p>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends "core/page.html" %}
{% block page %}
<h3>Page history</h3>
<p><a href="{% url 'core:page' page.get_full_name %}">Back to page</a></p>
<p>You're seeing the history of page <strong>{{ page.get_display_name }}</strong></p>
<ul>
<li><a href="{% url 'core:page' page_name=page.get_full_name %}">
last - {{ page.revisions.last.author }} - {{ page.revisions.last.date }}</a></li>
{% for r in page.revisions.all|dictsortreversed:'date'|slice:'1:' %}
<li><a href="{% url 'core:page_rev' page_name=page.get_full_name rev=r.id %}">
{{ r.author }} - {{ r.date }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -24,9 +24,12 @@ urlpatterns = [
url(r'^user/(?P<user_id>[0-9]+)/$', UserView.as_view(), name='user_profile'),
url(r'^user/(?P<user_id>[0-9]+)/edit$', UserUpdateProfileView.as_view(), name='user_edit'),
url(r'^user/(?P<user_id>[0-9]+)/groups$', UserUpdateGroupsView.as_view(), name='user_groups'),
url(r'^page/$', PageListView.as_view(), name='page_list'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/$', PageView.as_view(), name='page'),
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$', PagePropView.as_view(), name='page_prop'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/hist$', PageHistView.as_view(), name='page_hist'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/rev/(?P<rev>[0-9]+)/', PageRevView.as_view(), name='page_rev'),
url(r'^page/(?P<page_name>[a-z0-9/]*)/$', PageView.as_view(), name='page'),
]

View File

@ -5,7 +5,7 @@ from django.views.generic.edit import UpdateView
from django.contrib.auth.decorators import login_required, permission_required
from django.utils.decorators import method_decorator
from core.models import Page
from core.models import Page, PageRev
from core.views.forms import PagePropForm
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin
@ -16,21 +16,6 @@ class PageListView(ListView):
context = super(PageListView, self).get_context_data(**kwargs)
return context
# Define some right management callable for user_passes_test
def user_can_view(as_view):
def guy(*arg, **kwargs):
res = self.as_view(*arg, **kwargs)
user = self.request.user
obj = self.page
for g in obj.view_group.all():
if g in user.groups.all():
print("Allowed")
return res
print("Not allowed")
return res
return guy
class PageView(CanViewMixin, DetailView):
model = Page
@ -40,10 +25,37 @@ class PageView(CanViewMixin, DetailView):
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
if "page" not in context.keys():
context['new_page'] = self.kwargs['page_name']
return context
class PageHistView(CanViewMixin, DetailView):
model = Page
template_name_suffix = '_hist'
def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
return self.page
class PageRevView(CanViewMixin, DetailView):
model = Page
template_name = 'core/page_detail.html'
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(PageRevView, self).get_context_data(**kwargs)
if self.page is not None:
context['page'] = self.page
try:
rev = self.page.revisions.get(id=self.kwargs['rev'])
context['rev'] = rev
except:
# By passing, the template will just display the normal page without taking revision into account
pass
else:
context['tests'] = "PAGE_NOT_FOUND"
context['new_page'] = self.kwargs['page_name']
return context
@ -69,28 +81,46 @@ class PagePropView(CanEditPropMixin, UpdateView):
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:
context['tests'] = "PAGE_NOT_FOUND"
if "page" not in context.keys():
context['new_page'] = self.kwargs['page_name']
return context
class PageEditView(CanEditMixin, UpdateView):
model = Page
model = PageRev
fields = ['title', 'content',]
template_name_suffix = '_edit'
def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
return self.page
if self.page is not None:
# First edit
if self.page.revisions.all() is None:
rev = PageRev(author=request.user)
rev.save()
self.page.revisions.add(rev)
return self.page.revisions.all().last()
return None
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
if self.page is not None:
context['page'] = self.page
else:
context['tests'] = "PAGE_NOT_FOUND"
context['new_page'] = self.kwargs['page_name']
return context
def form_valid(self, form):
form.instance.author = self.request.user
form.instance.page = self.page
rev = form.instance
new_rev = PageRev(title=rev.title,
content=rev.content,
)
new_rev.author = self.request.user
new_rev.page = self.page
print(form.instance)
new_rev.save()
form.instance = new_rev
print(form.instance)
return super(PageEditView, self).form_valid(form)