diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html b/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html index be391989d..127a02826 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/shared/header.html @@ -16,6 +16,11 @@ {% endif %}
+ {% if usage_count or usage_count == 0 %} +
+ Used {{ usage_count }} Time{% if not usage_count == 1 %}s{% endif %} +
+ {% endif %} {% if add_link %}
{{ add_text }} @@ -23,4 +28,4 @@ {% endif %}
- \ No newline at end of file + diff --git a/wagtail/wagtailadmin/utils.py b/wagtail/wagtailadmin/utils.py new file mode 100644 index 000000000..a252d52aa --- /dev/null +++ b/wagtail/wagtailadmin/utils.py @@ -0,0 +1,36 @@ +from wagtail.wagtailcore.models import Page + + +def usage_count(self): + """The number of times that an selfect has been used""" + count = 0 + relations = self._meta.get_all_related_objects( + include_hidden=True, + include_proxy_eq=True + ) + for relation in relations: + count += relation.model._base_manager.filter( + **{relation.field.name: self.id} + ).count() + return count + + +def used_by(self): + related_objects = [] + result = [] + + relations = self._meta.get_all_related_objects( + include_hidden=True, + include_proxy_eq=True + ) + for relation in relations: + related_objects.extend(list(relation.model._base_manager.filter( + **{relation.field.name: self.id} + ))) + for r in related_objects: + if isinstance(r, Page): + result.append(r) + elif hasattr(r, 'page'): + result.append(r.page) + + return result diff --git a/wagtail/wagtaildocs/admin_urls.py b/wagtail/wagtaildocs/admin_urls.py index 9eaa3a50e..c26826b8c 100644 --- a/wagtail/wagtaildocs/admin_urls.py +++ b/wagtail/wagtaildocs/admin_urls.py @@ -11,4 +11,5 @@ urlpatterns = [ url(r'^chooser/$', chooser.chooser, name='wagtaildocs_chooser'), url(r'^chooser/(\d+)/$', chooser.document_chosen, name='wagtaildocs_document_chosen'), url(r'^chooser/upload/$', chooser.chooser_upload, name='wagtaildocs_chooser_upload'), + url(r'^usage/(\d+)/$', documents.usage, name='wagtaildocs_document_usage'), ] diff --git a/wagtail/wagtaildocs/models.py b/wagtail/wagtaildocs/models.py index a87b9c02b..f75d0ae16 100644 --- a/wagtail/wagtaildocs/models.py +++ b/wagtail/wagtaildocs/models.py @@ -12,6 +12,7 @@ from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import python_2_unicode_compatible from wagtail.wagtailadmin.taggable import TagSearchable +from wagtail.wagtailadmin.utils import usage_count, used_by @python_2_unicode_compatible @@ -51,6 +52,14 @@ class Document(models.Model, TagSearchable): def url(self): return reverse('wagtaildocs_serve', args=[self.id, self.filename]) + @property + def usage_count(self): + return usage_count(self) + + @property + def used_by(self): + return used_by(self) + def is_editable_by_user(self, user): if user.has_perm('wagtaildocs.change_document'): # user has global permission to change documents diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html b/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html index 55734fbbd..f529ee9fa 100644 --- a/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html +++ b/wagtail/wagtaildocs/templates/wagtaildocs/documents/edit.html @@ -13,7 +13,7 @@ {% block content %} {% trans "Editing" as editing_str %} - {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=document.title icon="doc-full-inverse" %} + {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=document.title icon="doc-full-inverse" usage_count=document.usage_count usage_url=usage_url %}
@@ -30,6 +30,6 @@
- +
{% endblock %} diff --git a/wagtail/wagtaildocs/templates/wagtaildocs/documents/usage.html b/wagtail/wagtaildocs/templates/wagtaildocs/documents/usage.html new file mode 100644 index 000000000..8db42fa07 --- /dev/null +++ b/wagtail/wagtaildocs/templates/wagtaildocs/documents/usage.html @@ -0,0 +1,17 @@ +{% extends "wagtailadmin/base.html" %} +{% load i18n %} +{% block titletag %}{% blocktrans with title=document.title %}{{ title }} Usage{% endblocktrans %}{% endblock %} +{% block content %} + + {% include "wagtailadmin/shared/header.html" with title="Usage" %} + +
+ +
+{% endblock %} diff --git a/wagtail/wagtaildocs/views/documents.py b/wagtail/wagtaildocs/views/documents.py index de72ee3b6..0e036aa47 100644 --- a/wagtail/wagtaildocs/views/documents.py +++ b/wagtail/wagtaildocs/views/documents.py @@ -5,6 +5,7 @@ from django.contrib.auth.decorators import permission_required from django.core.exceptions import PermissionDenied from django.utils.translation import ugettext as _ from django.views.decorators.vary import vary_on_headers +from django.core.urlresolvers import reverse from wagtail.wagtailadmin.forms import SearchForm @@ -101,6 +102,9 @@ def edit(request, document_id): if not doc.is_editable_by_user(request.user): raise PermissionDenied + usage_url = reverse('wagtaildocs_document_usage', + args=(doc.id,)) + if request.POST: original_file = doc.file form = DocumentForm(request.POST, request.FILES, instance=doc) @@ -121,6 +125,7 @@ def edit(request, document_id): return render(request, "wagtaildocs/documents/edit.html", { 'document': doc, 'form': form, + 'usage_url': usage_url }) @@ -139,3 +144,12 @@ def delete(request, document_id): return render(request, "wagtaildocs/documents/confirm_delete.html", { 'document': doc, }) + + +@permission_required('wagtailadmin.access_admin') +def usage(request, document_id): + doc = get_object_or_404(Document, id=document_id) + + return render(request, "wagtaildocs/documents/usage.html", { + 'document': doc, + }) diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index db73b048a..cec65173c 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -21,6 +21,7 @@ from unidecode import unidecode from wagtail.wagtailadmin.taggable import TagSearchable from wagtail.wagtailimages.backends import get_image_backend from .utils import validate_image_format +from wagtail.wagtailadmin.utils import usage_count, used_by @python_2_unicode_compatible @@ -48,6 +49,14 @@ class AbstractImage(models.Model, TagSearchable): tags = TaggableManager(help_text=None, blank=True, verbose_name=_('Tags')) + @property + def usage_count(self): + return usage_count(self) + + @property + def used_by(self): + return used_by(self) + indexed_fields = { 'uploaded_by_user_id': { 'type': 'integer', diff --git a/wagtail/wagtailimages/templates/wagtailimages/images/edit.html b/wagtail/wagtailimages/templates/wagtailimages/images/edit.html index f75b4e56e..217ac9a60 100644 --- a/wagtail/wagtailimages/templates/wagtailimages/images/edit.html +++ b/wagtail/wagtailimages/templates/wagtailimages/images/edit.html @@ -13,10 +13,10 @@ {% block content %} {% trans "Editing" as editing_str %} - {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=image.title icon="image" %} - + {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=image.title icon="image" usage_count=image.usage_count usage_url=usage_url %} +
- +
{% csrf_token %} @@ -33,7 +33,7 @@
  • {% trans "Delete image" %}
  • - +
    {% image image max-800x600 %} diff --git a/wagtail/wagtailimages/templates/wagtailimages/images/usage.html b/wagtail/wagtailimages/templates/wagtailimages/images/usage.html new file mode 100644 index 000000000..e99ddc313 --- /dev/null +++ b/wagtail/wagtailimages/templates/wagtailimages/images/usage.html @@ -0,0 +1,17 @@ +{% extends "wagtailadmin/base.html" %} +{% load i18n %} +{% block titletag %}{% blocktrans with title=document.title %}{{ title }} Usage{% endblocktrans %}{% endblock %} +{% block content %} + + {% include "wagtailadmin/shared/header.html" with title="Usage" %} + +
    +
      + {% for u in image.used_by %} +
    • + {{ u.title }} +
    • + {% endfor %} +
    +
    +{% endblock %} diff --git a/wagtail/wagtailimages/urls.py b/wagtail/wagtailimages/urls.py index 4fa4efaf9..af2da0e34 100644 --- a/wagtail/wagtailimages/urls.py +++ b/wagtail/wagtailimages/urls.py @@ -6,6 +6,7 @@ urlpatterns = [ url(r'^(\d+)/$', images.edit, name='wagtailimages_edit_image'), url(r'^(\d+)/delete/$', images.delete, name='wagtailimages_delete_image'), url(r'^add/$', images.add, name='wagtailimages_add_image'), + url(r'^usage/(\d+)/$', images.usage, name='wagtailimages_image_usage'), url(r'^chooser/$', chooser.chooser, name='wagtailimages_chooser'), url(r'^chooser/(\d+)/$', chooser.image_chosen, name='wagtailimages_image_chosen'), diff --git a/wagtail/wagtailimages/views/images.py b/wagtail/wagtailimages/views/images.py index 64f27dbda..31810bff1 100644 --- a/wagtail/wagtailimages/views/images.py +++ b/wagtail/wagtailimages/views/images.py @@ -5,6 +5,7 @@ from django.contrib.auth.decorators import permission_required from django.core.exceptions import PermissionDenied from django.utils.translation import ugettext as _ from django.views.decorators.vary import vary_on_headers +from django.core.urlresolvers import reverse from wagtail.wagtailadmin.forms import SearchForm @@ -80,6 +81,9 @@ def edit(request, image_id): if not image.is_editable_by_user(request.user): raise PermissionDenied + usage_url = reverse('wagtailimages_image_usage', + args=(image.id,)) + if request.POST: original_file = image.file form = ImageForm(request.POST, request.FILES, instance=image) @@ -101,6 +105,7 @@ def edit(request, image_id): return render(request, "wagtailimages/images/edit.html", { 'image': image, 'form': form, + 'usage_url': usage_url }) @@ -141,3 +146,14 @@ def add(request): return render(request, "wagtailimages/images/add.html", { 'form': form, }) + + +@permission_required('wagtailadmin.access_admin') +def usage(request, image_id): + image = get_object_or_404(get_image_model(), id=image_id) + + print dir(image) + + return render(request, "wagtailimages/images/usage.html", { + 'image': image, + }) diff --git a/wagtail/wagtailsnippets/models.py b/wagtail/wagtailsnippets/models.py index 8af626655..1a171eacb 100644 --- a/wagtail/wagtailsnippets/models.py +++ b/wagtail/wagtailsnippets/models.py @@ -1,4 +1,5 @@ from django.contrib.contenttypes.models import ContentType +from wagtail.wagtailadmin.utils import usage_count, used_by SNIPPET_MODELS = [] @@ -18,5 +19,7 @@ def get_snippet_content_types(): def register_snippet(model): if model not in SNIPPET_MODELS: + model.usage_count = usage_count + model.used_by = used_by SNIPPET_MODELS.append(model) SNIPPET_MODELS.sort(key=lambda x: x._meta.verbose_name) diff --git a/wagtail/wagtailsnippets/templates/wagtailsnippets/snippets/edit.html b/wagtail/wagtailsnippets/templates/wagtailsnippets/snippets/edit.html index 95d3d3dc5..f727aad2f 100644 --- a/wagtail/wagtailsnippets/templates/wagtailsnippets/snippets/edit.html +++ b/wagtail/wagtailsnippets/templates/wagtailsnippets/snippets/edit.html @@ -4,12 +4,12 @@ {% block bodyclass %}menu-snippets{% endblock %} {% block content %} {% trans "Editing" as editing_str %} - {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=instance icon="snippet" %} + {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=instance icon="snippet" usage_count=instance.usage_count usage_url=usage_url %}
    {% csrf_token %} {{ edit_handler.render_form_content }} - +