mirror of
https://github.com/django/django.git
synced 2025-07-05 18:29:11 +00:00
magic-removal: made a few tweaks to admin documentation views to better handle
new-style relation descriptors and deal with non-named groups in urlpatterns. git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2554 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
0cfe7fe53e
commit
90d5426adc
@ -82,13 +82,13 @@ ROLES = {
|
|||||||
|
|
||||||
def create_reference_role(rolename, urlbase):
|
def create_reference_role(rolename, urlbase):
|
||||||
def _role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
def _role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
node = docutils.nodes.reference(rawtext, text, refuri=(urlbase % (inliner.document.settings.link_base, text)), **options)
|
node = docutils.nodes.reference(rawtext, text, refuri=(urlbase % (inliner.document.settings.link_base, text.lower())), **options)
|
||||||
return [node], []
|
return [node], []
|
||||||
docutils.parsers.rst.roles.register_canonical_role(rolename, _role)
|
docutils.parsers.rst.roles.register_canonical_role(rolename, _role)
|
||||||
|
|
||||||
def default_reference_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
def default_reference_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
context = inliner.document.settings.default_reference_context
|
context = inliner.document.settings.default_reference_context
|
||||||
node = docutils.nodes.reference(rawtext, text, refuri=(ROLES[context] % (inliner.document.settings.link_base, text)), **options)
|
node = docutils.nodes.reference(rawtext, text, refuri=(ROLES[context] % (inliner.document.settings.link_base, text.lower())), **options)
|
||||||
return [node], []
|
return [node], []
|
||||||
|
|
||||||
if docutils_is_available:
|
if docutils_is_available:
|
||||||
|
@ -93,9 +93,13 @@ def view_index(request):
|
|||||||
if not utils.docutils_is_available:
|
if not utils.docutils_is_available:
|
||||||
return missing_docutils_page(request)
|
return missing_docutils_page(request)
|
||||||
|
|
||||||
views = []
|
if settings.ADMIN_FOR:
|
||||||
for site_settings_module in settings.ADMIN_FOR:
|
settings_modules = [__import__(m, '', '', ['']) for m in settings.ADMIN_FOR]
|
||||||
settings_mod = __import__(site_settings_module, '', '', [''])
|
else:
|
||||||
|
settings_modules = [settings]
|
||||||
|
|
||||||
|
views = []
|
||||||
|
for settings_mod in settings_modules:
|
||||||
urlconf = __import__(settings_mod.ROOT_URLCONF, '', '', [''])
|
urlconf = __import__(settings_mod.ROOT_URLCONF, '', '', [''])
|
||||||
view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
|
view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
|
||||||
for (func, regex) in view_functions:
|
for (func, regex) in view_functions:
|
||||||
@ -163,10 +167,19 @@ def model_detail(request, app_label, model_name):
|
|||||||
# Gather fields/field descriptions.
|
# Gather fields/field descriptions.
|
||||||
fields = []
|
fields = []
|
||||||
for field in opts.fields:
|
for field in opts.fields:
|
||||||
|
# ForeignKey is a special case since the field will actually be a
|
||||||
|
# descriptor that returns the other object
|
||||||
|
if isinstance(field, models.ForeignKey):
|
||||||
|
data_type = related_object_name = field.rel.to.__name__
|
||||||
|
app_label = field.rel.to._meta.app_label
|
||||||
|
verbose = utils.parse_rst(("the related `%s.%s` object" % (app_label, data_type)), 'model', 'model:' + data_type)
|
||||||
|
else:
|
||||||
|
data_type = get_readable_field_data_type(field)
|
||||||
|
verbose = field.verbose_name
|
||||||
fields.append({
|
fields.append({
|
||||||
'name': field.name,
|
'name': field.name,
|
||||||
'data_type': get_readable_field_data_type(field),
|
'data_type': data_type,
|
||||||
'verbose': field.verbose_name,
|
'verbose': verbose,
|
||||||
'help': field.help_text,
|
'help': field.help_text,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -187,6 +200,19 @@ def model_detail(request, app_label, model_name):
|
|||||||
'data_type': get_return_data_type(func_name),
|
'data_type': get_return_data_type(func_name),
|
||||||
'verbose': verbose,
|
'verbose': verbose,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Gather related objects
|
||||||
|
for rel in opts.get_all_related_objects():
|
||||||
|
verbose = "related `%s.%s` objects" % (rel.opts.app_label, rel.opts.object_name)
|
||||||
|
accessor = rel.get_accessor_name()
|
||||||
|
fields.append({
|
||||||
|
'name' : "%s.all" % accessor,
|
||||||
|
'verbose' : utils.parse_rst("all " + verbose , 'model', 'model:' + opts.module_name),
|
||||||
|
})
|
||||||
|
fields.append({
|
||||||
|
'name' : "%s.count" % accessor,
|
||||||
|
'verbose' : utils.parse_rst("number of " + verbose , 'model', 'model:' + opts.module_name),
|
||||||
|
})
|
||||||
|
|
||||||
return render_to_response('admin_doc/model_detail', {
|
return render_to_response('admin_doc/model_detail', {
|
||||||
'name': '%s.%s' % (opts.app_label, opts.object_name),
|
'name': '%s.%s' % (opts.app_label, opts.object_name),
|
||||||
@ -277,9 +303,6 @@ DATA_TYPE_MAPPING = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_readable_field_data_type(field):
|
def get_readable_field_data_type(field):
|
||||||
# ForeignKey is a special case. Use the field type of the relation.
|
|
||||||
if field.get_internal_type() == 'ForeignKey':
|
|
||||||
field = field.rel.get_related_field()
|
|
||||||
return DATA_TYPE_MAPPING[field.get_internal_type()] % field.__dict__
|
return DATA_TYPE_MAPPING[field.get_internal_type()] % field.__dict__
|
||||||
|
|
||||||
def extract_views_from_urlpatterns(urlpatterns, base=''):
|
def extract_views_from_urlpatterns(urlpatterns, base=''):
|
||||||
@ -301,15 +324,23 @@ def extract_views_from_urlpatterns(urlpatterns, base=''):
|
|||||||
raise TypeError, "%s does not appear to be a urlpattern object" % p
|
raise TypeError, "%s does not appear to be a urlpattern object" % p
|
||||||
return views
|
return views
|
||||||
|
|
||||||
# Clean up urlpattern regexes into something somewhat readable by Mere Humans:
|
|
||||||
# turns something like "^(?P<sport_slug>\w+)/athletes/(?P<athlete_slug>\w+)/$"
|
|
||||||
# into "<sport_slug>/athletes/<athlete_slug>/"
|
|
||||||
|
|
||||||
named_group_matcher = re.compile(r'\(\?P(<\w+>).+?\)')
|
named_group_matcher = re.compile(r'\(\?P(<\w+>).+?\)')
|
||||||
|
non_named_group_matcher = re.compile(r'\(.*?\)')
|
||||||
|
|
||||||
def simplify_regex(pattern):
|
def simplify_regex(pattern):
|
||||||
|
"""
|
||||||
|
Clean up urlpattern regexes into something somewhat readable by Mere Humans:
|
||||||
|
turns something like "^(?P<sport_slug>\w+)/athletes/(?P<athlete_slug>\w+)/$"
|
||||||
|
into "<sport_slug>/athletes/<athlete_slug>/"
|
||||||
|
"""
|
||||||
|
# handle named groups first
|
||||||
pattern = named_group_matcher.sub(lambda m: m.group(1), pattern)
|
pattern = named_group_matcher.sub(lambda m: m.group(1), pattern)
|
||||||
pattern = pattern.replace('^', '').replace('$', '').replace('?', '').replace('//', '/')
|
|
||||||
|
# handle non-named groups
|
||||||
|
pattern = non_named_group_matcher.sub("<var>", pattern)
|
||||||
|
|
||||||
|
# clean up any outstanding regex-y characters.
|
||||||
|
pattern = pattern.replace('^', '').replace('$', '').replace('?', '').replace('//', '/').replace('\\', '')
|
||||||
if not pattern.startswith('/'):
|
if not pattern.startswith('/'):
|
||||||
pattern = '/' + pattern
|
pattern = '/' + pattern
|
||||||
return pattern
|
return pattern
|
||||||
|
Loading…
x
Reference in New Issue
Block a user