Commit a39d672e authored by Bouke Haarsma's avatar Bouke Haarsma Committed by Claude Paroz
Browse files

Fixed #21386 -- Removed admindocs dependence on sites framework

* Removed ADMIN_FOR setting and warn warning
* Group view functions by namespace instead of site
* Added a test verifying namespaces are listed

Thanks to Claude Paroz for reviewing and ideas for improvement.
parent f1b3ab9c
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -15,15 +15,12 @@
{% block content %}
<h1>{% blocktrans %}Template: "{{ name }}"{% endblocktrans %}</h1>

{% regroup templates|dictsort:"site_id" by site as templates_by_site %}
{% for group in templates_by_site %}
    <h2>{% blocktrans with group.grouper as grouper %}Search path for template "{{ name }}" on {{ grouper }}:{% endblocktrans %}</h2>
<h2>{% blocktrans %}Search path for template "{{ name }}":{% endblocktrans %}</h2>
<ol>
    {% for template in group.list|dictsort:"order" %}
{% for template in templates|dictsort:"order" %}
    <li><code>{{ template.file }}</code>{% if not template.exists %} <em>{% trans '(does not exist)' %}</em>{% endif %}</li>
{% endfor %}
</ol>
{% endfor %}

<p class="small"><a href="{% url 'django-admindocs-docroot' %}">&lsaquo; {% trans 'Back to Documentation' %}</a></p>
{% endblock %}
+21 −10
Original line number Diff line number Diff line
@@ -15,14 +15,17 @@

<h1>{% trans 'View documentation' %}</h1>

{% regroup views|dictsort:"site_id" by site as views_by_site %}
{% regroup views|dictsort:'namespace' by namespace as views_by_ns %}

<div id="content-related" class="sidebar">
<div class="module">
<h2>{% trans 'Jump to site' %}</h2>
<h2>{% trans 'Jump to namespace' %}</h2>
<ul>
    {% for site_views in views_by_site %}
    <li><a href="#site{{ site_views.grouper.id }}">{{ site_views.grouper.name }}</a></li>
{% for ns_views in views_by_ns %}
    <li><a href="#ns|{{ ns_views.grouper }}">
    {% if ns_views.grouper %}{{ ns_views.grouper }}
    {% else %}{% trans "Empty namespace" %}{% endif %}
    </a></li>
{% endfor %}
</ul>
</div>
@@ -30,14 +33,22 @@

<div id="content-main">

{% for site_views in views_by_site %}
{% for ns_views in views_by_ns %}
<div class="module">
<h2 id="site{{ site_views.grouper.id }}">{% blocktrans with site_views.grouper.name as name %}Views by URL on {{ name }}{% endblocktrans %}</h2>

{% for view in site_views.list|dictsort:"url" %}
<h2 id="ns|{{ ns_views.grouper }}">
{% if ns_views.grouper %}
    {% blocktrans with ns_views.grouper as name %}Views by namespace {{ name }}{% endblocktrans %}
{% else %}
    {% blocktrans %}Views by empty namespace{% endblocktrans %}
{% endif %}
</h2>

{% for view in ns_views.list|dictsort:"url" %}
{% ifchanged %}
<h3><a href="{% url 'django-admindocs-views-detail' view=view.full_name %}">{{ view.url }}</a></h3>
<p class="small quiet">{% blocktrans with view.full_name as name %}View function: {{ name }}{% endblocktrans %}</p>
<p class="small quiet">{% blocktrans with view.full_name as full_name and view.url_name as url_name %}
    View function: <code>{{ full_name }}</code>. Name: <code>{{ url_name }}</code>.
{% endblocktrans %}</p>
<p>{{ view.title }}</p>
<hr />
{% endifchanged %}
+31 −43
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ from importlib import import_module
import inspect
import os
import re
import warnings

from django import template
from django.conf import settings
@@ -13,7 +14,6 @@ from django.core.exceptions import ViewDoesNotExist
from django.http import Http404
from django.core import urlresolvers
from django.contrib.admindocs import utils
from django.contrib.sites.models import Site
from django.utils.decorators import method_decorator
from django.utils._os import upath
from django.utils import six
@@ -23,10 +23,10 @@ from django.views.generic import TemplateView
# Exclude methods starting with these strings from documentation
MODEL_METHODS_EXCLUDE = ('_', 'add_', 'delete', 'save', 'set_')


class GenericSite(object):
    domain = 'example.com'
    name = 'my site'
if getattr(settings, 'ADMIN_FOR', None):
    warnings.warn('The ADMIN_FOR setting has been removed, you can remove '
                  'this setting from your configuration.', DeprecationWarning,
                  stacklevel=2)


class BaseAdminDocsView(TemplateView):
@@ -129,25 +129,16 @@ class ViewIndexView(BaseAdminDocsView):
    template_name = 'admin_doc/view_index.html'

    def get_context_data(self, **kwargs):
        if settings.ADMIN_FOR:
            settings_modules = [import_module(m) for m in settings.ADMIN_FOR]
        else:
            settings_modules = [settings]

        views = []
        for settings_mod in settings_modules:
            urlconf = import_module(settings_mod.ROOT_URLCONF)
        urlconf = import_module(settings.ROOT_URLCONF)
        view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
            if Site._meta.installed:
                site_obj = Site.objects.get(pk=settings_mod.SITE_ID)
            else:
                site_obj = GenericSite()
            for (func, regex) in view_functions:
        for (func, regex, namespace, name) in view_functions:
            views.append({
                'full_name': '%s.%s' % (func.__module__, getattr(func, '__name__', func.__class__.__name__)),
                    'site_id': settings_mod.SITE_ID,
                    'site': site_obj,
                'url': simplify_regex(regex),
                'url_name': ':'.join((namespace or []) + (name and [name] or [])),
                'namespace': ':'.join((namespace or [])),
                'name': name,
            })
        kwargs.update({'views': views})
        return super(ViewIndexView, self).get_context_data(**kwargs)
@@ -292,21 +283,13 @@ class TemplateDetailView(BaseAdminDocsView):
    def get_context_data(self, **kwargs):
        template = self.kwargs['template']
        templates = []
        for site_settings_module in settings.ADMIN_FOR:
            settings_mod = import_module(site_settings_module)
            if Site._meta.installed:
                site_obj = Site.objects.get(pk=settings_mod.SITE_ID)
            else:
                site_obj = GenericSite()
            for dir in settings_mod.TEMPLATE_DIRS:
        for dir in settings.TEMPLATE_DIRS:
            template_file = os.path.join(dir, template)
            templates.append({
                'file': template_file,
                'exists': os.path.exists(template_file),
                'contents': lambda: open(template_file).read() if os.path.exists(template_file) else '',
                    'site_id': settings_mod.SITE_ID,
                    'site': site_obj,
                    'order': list(settings_mod.TEMPLATE_DIRS).index(dir),
                'order': list(settings.TEMPLATE_DIRS).index(dir),
            })
        kwargs.update({
            'name': template,
@@ -356,7 +339,7 @@ def get_readable_field_data_type(field):
    return field.description % field.__dict__


def extract_views_from_urlpatterns(urlpatterns, base=''):
def extract_views_from_urlpatterns(urlpatterns, base='', namespace=None):
    """
    Return a list of views from a list of urlpatterns.

@@ -369,10 +352,15 @@ def extract_views_from_urlpatterns(urlpatterns, base=''):
                patterns = p.url_patterns
            except ImportError:
                continue
            views.extend(extract_views_from_urlpatterns(patterns, base + p.regex.pattern))
            views.extend(extract_views_from_urlpatterns(
                patterns,
                base + p.regex.pattern,
                (namespace or []) + (p.namespace and [p.namespace] or [])
            ))
        elif hasattr(p, 'callback'):
            try:
                views.append((p.callback, base + p.regex.pattern))
                views.append((p.callback, base + p.regex.pattern,
                              namespace, p.name))
            except ViewDoesNotExist:
                continue
        else:
+0 −2
Original line number Diff line number Diff line
@@ -28,8 +28,6 @@ the following:
  ``r'^admin/'`` entry, so that requests to ``/admin/doc/`` don't get
  handled by the latter entry.
* Install the docutils Python module (http://docutils.sf.net/).
* **Optional:** Linking to templates requires the :setting:`ADMIN_FOR`
  setting to be configured.
* **Optional:** Using the admindocs bookmarklets requires
  ``django.contrib.admindocs.middleware.XViewMiddleware`` to be installed.

+0 −19
Original line number Diff line number Diff line
@@ -2097,25 +2097,6 @@ The default value for the X-Frame-Options header used by
:doc:`clickjacking protection </ref/clickjacking/>` documentation.


Admindocs
=========

Settings for :mod:`django.contrib.admindocs`.

.. setting:: ADMIN_FOR

ADMIN_FOR
---------

Default: ``()`` (Empty tuple)

Used for admin-site settings modules, this should be a tuple of settings
modules (in the format ``'foo.bar.baz'``) for which this site is an admin.

The admin site uses this in its automatically-introspected documentation of
models, views and template tags.


Auth
====

Loading