From 92f68f5b429b5781623a84b19a0f3ee87e4ca9d7 Mon Sep 17 00:00:00 2001 From: Skia Date: Wed, 2 Dec 2015 11:09:50 +0100 Subject: [PATCH] Add complete revision and history handling in the wiki --- core/migrations/0013_auto_20151202_0814.py | 41 +++++++++ core/migrations/0014_remove_page_revision.py | 18 ++++ core/models.py | 23 ++++- core/templates/core/page_detail.html | 13 ++- core/templates/core/page_hist.html | 19 ++++ .../{page_edit.html => pagerev_edit.html} | 0 core/urls.py | 5 +- core/views/page.py | 86 +++++++++++++------ 8 files changed, 169 insertions(+), 36 deletions(-) create mode 100644 core/migrations/0013_auto_20151202_0814.py create mode 100644 core/migrations/0014_remove_page_revision.py create mode 100644 core/templates/core/page_hist.html rename core/templates/core/{page_edit.html => pagerev_edit.html} (100%) diff --git a/core/migrations/0013_auto_20151202_0814.py b/core/migrations/0013_auto_20151202_0814.py new file mode 100644 index 00000000..b5670397 --- /dev/null +++ b/core/migrations/0013_auto_20151202_0814.py @@ -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'), + ), + ] diff --git a/core/migrations/0014_remove_page_revision.py b/core/migrations/0014_remove_page_revision.py new file mode 100644 index 00000000..55111edb --- /dev/null +++ b/core/migrations/0014_remove_page_revision.py @@ -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', + ), + ] diff --git a/core/models.py b/core/models.py index 9b23bbe9..ec4b5a7f 100644 --- a/core/models.py +++ b/core/models.py @@ -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__) + diff --git a/core/templates/core/page_detail.html b/core/templates/core/page_detail.html index e8089973..8255312b 100644 --- a/core/templates/core/page_detail.html +++ b/core/templates/core/page_detail.html @@ -7,9 +7,16 @@

Edit

Prop

{% endif %} -

You're seeing the page {{ page.get_display_name }}

-

{{ page.title }}

-

{{ page.content }}

+

You're seeing the page {{ page.get_display_name }} - + History

+ {% if rev %} +

This may not be the last update, you are seeing revision {{ rev.id }}!

+

{{ rev.title }}

+

{{ rev.content }}

+ {% else %} +

{{ page.revisions.last.title }}

+

{{ page.revisions.last.content }}

+ {% endif %} {% endblock %} diff --git a/core/templates/core/page_hist.html b/core/templates/core/page_hist.html new file mode 100644 index 00000000..746d6115 --- /dev/null +++ b/core/templates/core/page_hist.html @@ -0,0 +1,19 @@ +{% extends "core/page.html" %} + +{% block page %} +

Page history

+

Back to page

+

You're seeing the history of page {{ page.get_display_name }}

+ +{% endblock %} + + + + diff --git a/core/templates/core/page_edit.html b/core/templates/core/pagerev_edit.html similarity index 100% rename from core/templates/core/page_edit.html rename to core/templates/core/pagerev_edit.html diff --git a/core/urls.py b/core/urls.py index 460640b6..280bf7e1 100644 --- a/core/urls.py +++ b/core/urls.py @@ -24,9 +24,12 @@ urlpatterns = [ url(r'^user/(?P[0-9]+)/$', UserView.as_view(), name='user_profile'), url(r'^user/(?P[0-9]+)/edit$', UserUpdateProfileView.as_view(), name='user_edit'), url(r'^user/(?P[0-9]+)/groups$', UserUpdateGroupsView.as_view(), name='user_groups'), + url(r'^page/$', PageListView.as_view(), name='page_list'), - url(r'^page/(?P[a-z0-9/]*)/$', PageView.as_view(), name='page'), url(r'^page/(?P[a-z0-9/]*)/edit$', PageEditView.as_view(), name='page_edit'), url(r'^page/(?P[a-z0-9/]*)/prop$', PagePropView.as_view(), name='page_prop'), + url(r'^page/(?P[a-z0-9/]*)/hist$', PageHistView.as_view(), name='page_hist'), + url(r'^page/(?P[a-z0-9/]*)/rev/(?P[0-9]+)/', PageRevView.as_view(), name='page_rev'), + url(r'^page/(?P[a-z0-9/]*)/$', PageView.as_view(), name='page'), ] diff --git a/core/views/page.py b/core/views/page.py index f32907ac..dd48c2da 100644 --- a/core/views/page.py +++ b/core/views/page.py @@ -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) +