185 |
185 |
186 # Get the model class. |
186 # Get the model class. |
187 try: |
187 try: |
188 app_mod = models.get_app(app_label) |
188 app_mod = models.get_app(app_label) |
189 except ImproperlyConfigured: |
189 except ImproperlyConfigured: |
190 raise Http404, _("App %r not found") % app_label |
190 raise Http404(_("App %r not found") % app_label) |
191 model = None |
191 model = None |
192 for m in models.get_models(app_mod): |
192 for m in models.get_models(app_mod): |
193 if m._meta.object_name.lower() == model_name: |
193 if m._meta.object_name.lower() == model_name: |
194 model = m |
194 model = m |
195 break |
195 break |
196 if model is None: |
196 if model is None: |
197 raise Http404, _("Model %(model_name)r not found in app %(app_label)r") % {'model_name': model_name, 'app_label': app_label} |
197 raise Http404(_("Model %(model_name)r not found in app %(app_label)r") % {'model_name': model_name, 'app_label': app_label}) |
198 |
198 |
199 opts = model._meta |
199 opts = model._meta |
200 |
200 |
201 # Gather fields/field descriptions. |
201 # Gather fields/field descriptions. |
202 fields = [] |
202 fields = [] |
307 """Display an error message for people without docutils""" |
307 """Display an error message for people without docutils""" |
308 return render_to_response('admin_doc/missing_docutils.html') |
308 return render_to_response('admin_doc/missing_docutils.html') |
309 |
309 |
310 def load_all_installed_template_libraries(): |
310 def load_all_installed_template_libraries(): |
311 # Load/register all template tag libraries from installed apps. |
311 # Load/register all template tag libraries from installed apps. |
312 for e in templatetags.__path__: |
312 for module_name in template.get_templatetags_modules(): |
313 libraries = [os.path.splitext(p)[0] for p in os.listdir(e) if p.endswith('.py') and p[0].isalpha()] |
313 mod = import_module(module_name) |
|
314 libraries = [ |
|
315 os.path.splitext(p)[0] |
|
316 for p in os.listdir(os.path.dirname(mod.__file__)) |
|
317 if p.endswith('.py') and p[0].isalpha() |
|
318 ] |
314 for library_name in libraries: |
319 for library_name in libraries: |
315 try: |
320 try: |
316 lib = template.get_library("django.templatetags.%s" % library_name.split('.')[-1]) |
321 lib = template.get_library(library_name) |
317 except template.InvalidTemplateLibrary: |
322 except template.InvalidTemplateLibrary, e: |
318 pass |
323 pass |
319 |
324 |
320 def get_return_data_type(func_name): |
325 def get_return_data_type(func_name): |
321 """Return a somewhat-helpful data type given a function name""" |
326 """Return a somewhat-helpful data type given a function name""" |
322 if func_name.startswith('get_'): |
327 if func_name.startswith('get_'): |
324 return 'List' |
329 return 'List' |
325 elif func_name.endswith('_count'): |
330 elif func_name.endswith('_count'): |
326 return 'Integer' |
331 return 'Integer' |
327 return '' |
332 return '' |
328 |
333 |
329 # Maps Field objects to their human-readable data types, as strings. |
|
330 # Column-type strings can contain format strings; they'll be interpolated |
|
331 # against the values of Field.__dict__ before being output. |
|
332 # If a column type is set to None, it won't be included in the output. |
|
333 DATA_TYPE_MAPPING = { |
|
334 'AutoField' : _('Integer'), |
|
335 'BooleanField' : _('Boolean (Either True or False)'), |
|
336 'CharField' : _('String (up to %(max_length)s)'), |
|
337 'CommaSeparatedIntegerField': _('Comma-separated integers'), |
|
338 'DateField' : _('Date (without time)'), |
|
339 'DateTimeField' : _('Date (with time)'), |
|
340 'DecimalField' : _('Decimal number'), |
|
341 'EmailField' : _('E-mail address'), |
|
342 'FileField' : _('File path'), |
|
343 'FilePathField' : _('File path'), |
|
344 'FloatField' : _('Floating point number'), |
|
345 'ForeignKey' : _('Integer'), |
|
346 'ImageField' : _('File path'), |
|
347 'IntegerField' : _('Integer'), |
|
348 'IPAddressField' : _('IP address'), |
|
349 'ManyToManyField' : '', |
|
350 'NullBooleanField' : _('Boolean (Either True, False or None)'), |
|
351 'OneToOneField' : _('Relation to parent model'), |
|
352 'PhoneNumberField' : _('Phone number'), |
|
353 'PositiveIntegerField' : _('Integer'), |
|
354 'PositiveSmallIntegerField' : _('Integer'), |
|
355 'SlugField' : _('String (up to %(max_length)s)'), |
|
356 'SmallIntegerField' : _('Integer'), |
|
357 'TextField' : _('Text'), |
|
358 'TimeField' : _('Time'), |
|
359 'URLField' : _('URL'), |
|
360 'USStateField' : _('U.S. state (two uppercase letters)'), |
|
361 'XMLField' : _('XML text'), |
|
362 } |
|
363 |
|
364 def get_readable_field_data_type(field): |
334 def get_readable_field_data_type(field): |
365 return DATA_TYPE_MAPPING[field.get_internal_type()] % field.__dict__ |
335 """Returns the description for a given field type, if it exists, |
|
336 Fields' descriptions can contain format strings, which will be interpolated |
|
337 against the values of field.__dict__ before being output.""" |
|
338 |
|
339 return field.description % field.__dict__ |
366 |
340 |
367 def extract_views_from_urlpatterns(urlpatterns, base=''): |
341 def extract_views_from_urlpatterns(urlpatterns, base=''): |
368 """ |
342 """ |
369 Return a list of views from a list of urlpatterns. |
343 Return a list of views from a list of urlpatterns. |
370 |
344 |