kopia lustrzana https://github.com/wagtail/wagtail
				
				
				
			Add snippet history view
							rodzic
							
								
									9b28fdba87
								
							
						
					
					
						commit
						07141d6ced
					
				|  | @ -9,6 +9,7 @@ | |||
|         <span class="avatar small" data-wagtail-tooltip="{{ latest_log_entry.user_display_name }}"><img src="{% avatar_url latest_log_entry.user size=25 %}" alt="" /></span> | ||||
|         {% trans "Last updated" %} | ||||
|         {% include "wagtailadmin/shared/last_updated.html" with last_updated=latest_log_entry.timestamp time_prefix="at" %} | ||||
|         - <a href="{% url 'wagtailsnippets:history' model_opts.app_label model_opts.model_name instance.pk|admin_urlquote %}">History</a> | ||||
|     {% endif %} | ||||
| 
 | ||||
|     <div class="row row-flush"> | ||||
|  |  | |||
|  | @ -1,8 +1,10 @@ | |||
| import datetime | ||||
| import json | ||||
| 
 | ||||
| from django.contrib.admin.utils import quote | ||||
| from django.contrib.auth import get_user_model | ||||
| from django.contrib.auth.models import AnonymousUser, Permission | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.core import checks | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.core.files.base import ContentFile | ||||
|  | @ -12,6 +14,7 @@ from django.http import HttpRequest, HttpResponse | |||
| from django.test import RequestFactory, TestCase | ||||
| from django.test.utils import override_settings | ||||
| from django.urls import reverse | ||||
| from django.utils.timezone import make_aware | ||||
| from taggit.models import Tag | ||||
| 
 | ||||
| from wagtail.admin.admin_url_finder import AdminURLFinder | ||||
|  | @ -19,7 +22,7 @@ from wagtail.admin.edit_handlers import FieldPanel | |||
| from wagtail.admin.forms import WagtailAdminModelForm | ||||
| from wagtail.core import hooks | ||||
| from wagtail.core.blocks.field_block import FieldBlockAdapter | ||||
| from wagtail.core.models import Locale, Page | ||||
| from wagtail.core.models import Locale, ModelLogEntry, Page | ||||
| from wagtail.snippets.action_menu import ActionMenuItem, get_base_snippet_action_menu_items | ||||
| from wagtail.snippets.blocks import SnippetChooserBlock | ||||
| from wagtail.snippets.edit_handlers import SnippetChooserPanel | ||||
|  | @ -1054,6 +1057,32 @@ class TestUsedBy(TestCase): | |||
|         self.assertEqual(type(advert.get_usage()[0]), Page) | ||||
| 
 | ||||
| 
 | ||||
| class TestSnippetHistory(TestCase, WagtailTestUtils): | ||||
|     fixtures = ['test.json'] | ||||
| 
 | ||||
|     def get(self, params={}): | ||||
|         snippet = self.test_snippet | ||||
|         args = (snippet._meta.app_label, snippet._meta.model_name, quote(snippet.pk)) | ||||
|         return self.client.get(reverse('wagtailsnippets:history', args=args), params) | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         self.user = self.login() | ||||
|         self.test_snippet = Advert.objects.get(pk=1) | ||||
|         ModelLogEntry.objects.create( | ||||
|             content_type=ContentType.objects.get_for_model(Advert), | ||||
|             label="Test Advert", | ||||
|             action='wagtail.create', | ||||
|             timestamp=make_aware(datetime.datetime(2021, 9, 30, 10, 1, 0)), | ||||
|             object_id='1', | ||||
|         ) | ||||
| 
 | ||||
|     def test_simple(self): | ||||
|         response = self.get() | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|         self.assertContains(response, '<td>Created</td>', html=True) | ||||
|         self.assertContains(response, '<div class="human-readable-date" title="Sept. 30, 2021, 10:01 a.m.">') | ||||
| 
 | ||||
| 
 | ||||
| class TestSnippetChoose(TestCase, WagtailTestUtils): | ||||
|     fixtures = ['test.json'] | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ urlpatterns = [ | |||
|     path('<slug:app_label>/<slug:model_name>/multiple/delete/', snippets.delete, name='delete-multiple'), | ||||
|     path('<slug:app_label>/<slug:model_name>/delete/<str:pk>/', snippets.delete, name='delete'), | ||||
|     path('<slug:app_label>/<slug:model_name>/usage/<str:pk>/', snippets.usage, name='usage'), | ||||
|     path('<slug:app_label>/<slug:model_name>/history/<str:pk>/', snippets.HistoryView.as_view(), name='history'), | ||||
| 
 | ||||
|     # legacy URLs that could potentially collide if the pk matches one of the reserved names above | ||||
|     # ('add', 'edit' etc) - redirect to the unambiguous version | ||||
|  |  | |||
|  | @ -12,12 +12,14 @@ from django.template.response import TemplateResponse | |||
| from django.urls import reverse | ||||
| from django.utils.text import capfirst | ||||
| from django.utils.translation import gettext as _ | ||||
| from django.utils.translation import ngettext | ||||
| from django.utils.translation import gettext_lazy, ngettext | ||||
| from django.views.generic import TemplateView | ||||
| 
 | ||||
| from wagtail.admin import messages | ||||
| from wagtail.admin.edit_handlers import ObjectList, extract_panel_definitions_from_model_class | ||||
| from wagtail.admin.forms.search import SearchForm | ||||
| from wagtail.admin.ui.tables import Column, DateColumn, UserColumn | ||||
| from wagtail.admin.views.generic.models import IndexView | ||||
| from wagtail.core import hooks | ||||
| from wagtail.core.log_actions import log | ||||
| from wagtail.core.log_actions import registry as log_registry | ||||
|  | @ -441,3 +443,32 @@ def redirect_to_delete(request, app_label, model_name, pk): | |||
| 
 | ||||
| def redirect_to_usage(request, app_label, model_name, pk): | ||||
|     return redirect('wagtailsnippets:usage', app_label, model_name, pk, permanent=True) | ||||
| 
 | ||||
| 
 | ||||
| class HistoryView(IndexView): | ||||
|     template_name = 'wagtailadmin/generic/index.html' | ||||
|     page_title = gettext_lazy('Snippet history') | ||||
|     header_icon = 'history' | ||||
|     paginate_by = 50 | ||||
|     columns = [ | ||||
|         Column('message', label=gettext_lazy("Action")), | ||||
|         UserColumn('user', blank_display_name='system'), | ||||
|         DateColumn('timestamp', label=gettext_lazy("Date")), | ||||
|     ] | ||||
| 
 | ||||
|     def dispatch(self, request, app_label, model_name, pk): | ||||
|         self.app_label = app_label | ||||
|         self.model_name = model_name | ||||
|         self.model = get_snippet_model_from_url_params(app_label, model_name) | ||||
|         self.object = get_object_or_404(self.model, pk=unquote(pk)) | ||||
| 
 | ||||
|         return super().dispatch(request) | ||||
| 
 | ||||
|     def get_page_subtitle(self): | ||||
|         return str(self.object) | ||||
| 
 | ||||
|     def get_index_url(self): | ||||
|         return reverse('wagtailsnippets:history', args=(self.app_label, self.model_name, quote(self.object.pk))) | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         return log_registry.get_logs_for_instance(self.object).prefetch_related('user__wagtail_userprofile') | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Matt Westcott
						Matt Westcott