Skip to content

Commit

Permalink
Added 'django-admin.py validate', which validates all installed model…
Browse files Browse the repository at this point in the history
…s. Validation only handles common errors at this point, but we'll be improving it each time we think of a potential model syntax problem. Also changed the development Web server to validate automatically at server start.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@503 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
adrianholovaty committed Aug 15, 2005
1 parent 4a71598 commit 8f9e5b6
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
7 changes: 4 additions & 3 deletions django/bin/django-admin.py
Expand Up @@ -7,7 +7,9 @@
'adminindex': management.get_admin_index,
'createsuperuser': management.createsuperuser,
# 'dbcheck': management.database_check,
'init': management.init,
'inspectdb': management.inspectdb,
'install': management.install,
'runserver': management.runserver,
'sql': management.get_sql_create,
'sqlall': management.get_sql_all,
Expand All @@ -18,8 +20,7 @@
'sqlsequencereset': management.get_sql_sequence_reset,
'startapp': management.startapp,
'startproject': management.startproject,
'init': management.init,
'install': management.install,
'validate': management.validate,
}

NO_SQL_TRANSACTION = ('adminindex', 'dbcheck', 'install', 'sqlindexes')
Expand Down Expand Up @@ -65,7 +66,7 @@ def main():
print_error("An action is required.", sys.argv[0])
if not ACTION_MAPPING.has_key(action):
print_error("Your action, %r, was invalid." % action, sys.argv[0])
if action in ('createsuperuser', 'init'):
if action in ('createsuperuser', 'init', 'validate'):
ACTION_MAPPING[action]()
elif action == 'inspectdb':
try:
Expand Down
56 changes: 55 additions & 1 deletion django/core/management.py
Expand Up @@ -483,6 +483,58 @@ def table2model(table_name):
inspectdb.help_doc = "Introspects the database tables in the given database and outputs a Django model module."
inspectdb.args = "[dbname]"

class ModelErrorCollection:
def __init__(self, outfile=sys.stdout):
self.errors = []
self.outfile = outfile

def add(self, opts, error):
self.errors.append((opts, error))
self.outfile.write("%s.%s: %s\n" % (opts.module_name, opts.object_name, error))

def validate():
"Validates all installed models."
from django.core import meta
e = ModelErrorCollection()
module_list = meta.get_installed_model_modules()
for module in module_list:
for mod in module._MODELS:
opts = mod._meta

# Do field-specific validation.
for f in opts.fields:
if isinstance(f, meta.CharField) and f.maxlength in (None, 0):
e.add(opts, '"%s" field: CharFields require a "maxlength" attribute.' % f.name)

# Check admin attribute.
if opts.admin is not None and not isinstance(opts.admin, meta.Admin):
e.add(opts, '"admin" attribute, if given, must be set to a meta.Admin() instance.')

# Check ordering attribute.
if opts.ordering:
for field_name in opts.ordering:
if field_name == '?': continue
if field_name.startswith('-'):
field_name = field_name[1:]
try:
opts.get_field(field_name, many_to_many=False)
except meta.FieldDoesNotExist:
e.add(opts, '"ordering" refers to "%s", a field that doesn\'t exist.' % field_name)

# Check core=True, if needed.
for rel_opts, rel_field in opts.get_inline_related_objects():
try:
for f in rel_opts.fields:
if f.core:
raise StopIteration
e.add(rel_opts, "At least one field in %s should have core=True, because it's being edited inline by %s.%s." % (rel_opts.object_name, opts.module_name, opts.object_name))
except StopIteration:
pass

num_errors = len(e.errors)
print '%s error%s found.' % (num_errors, num_errors != 1 and 's' or '')
validate.args = ''

def runserver(port):
"Starts a lightweight Web server for development."
from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException
Expand All @@ -492,7 +544,9 @@ def runserver(port):
sys.exit(1)
def inner_run():
from django.conf.settings import SETTINGS_MODULE
print "Starting server on port %s with settings module %r." % (port, SETTINGS_MODULE)
print "Validating models..."
validate()
print "\nStarting server on port %s with settings module %r." % (port, SETTINGS_MODULE)
print "Go to http://127.0.0.1:%s/ for Django." % port
print "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)."
try:
Expand Down

0 comments on commit 8f9e5b6

Please sign in to comment.