PageRenderTime 37ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/django/core/management/commands/runserver.py

https://gitlab.com/Guy1394/django
Python | 189 lines | 185 code | 4 blank | 0 comment | 3 complexity | 982970fa02324bb752e647c474abc731 MD5 | raw file
  1. from __future__ import unicode_literals
  2. import errno
  3. import os
  4. import re
  5. import socket
  6. import sys
  7. from datetime import datetime
  8. from django.conf import settings
  9. from django.core.exceptions import ImproperlyConfigured
  10. from django.core.management.base import BaseCommand, CommandError
  11. from django.core.servers.basehttp import get_internal_wsgi_application, run
  12. from django.db import DEFAULT_DB_ALIAS, connections
  13. from django.db.migrations.exceptions import MigrationSchemaMissing
  14. from django.db.migrations.executor import MigrationExecutor
  15. from django.utils import autoreload, six
  16. from django.utils.encoding import force_text, get_system_encoding
  17. naiveip_re = re.compile(r"""^(?:
  18. (?P<addr>
  19. (?P<ipv4>\d{1,3}(?:\.\d{1,3}){3}) | # IPv4 address
  20. (?P<ipv6>\[[a-fA-F0-9:]+\]) | # IPv6 address
  21. (?P<fqdn>[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*) # FQDN
  22. ):)?(?P<port>\d+)$""", re.X)
  23. class Command(BaseCommand):
  24. help = "Starts a lightweight Web server for development."
  25. # Validation is called explicitly each time the server is reloaded.
  26. requires_system_checks = False
  27. leave_locale_alone = True
  28. default_port = '8000'
  29. def add_arguments(self, parser):
  30. parser.add_argument('addrport', nargs='?',
  31. help='Optional port number, or ipaddr:port')
  32. parser.add_argument('--ipv6', '-6', action='store_true', dest='use_ipv6', default=False,
  33. help='Tells Django to use an IPv6 address.')
  34. parser.add_argument('--nothreading', action='store_false', dest='use_threading', default=True,
  35. help='Tells Django to NOT use threading.')
  36. parser.add_argument('--noreload', action='store_false', dest='use_reloader', default=True,
  37. help='Tells Django to NOT use the auto-reloader.')
  38. def execute(self, *args, **options):
  39. if options.get('no_color'):
  40. # We rely on the environment because it's currently the only
  41. # way to reach WSGIRequestHandler. This seems an acceptable
  42. # compromise considering `runserver` runs indefinitely.
  43. os.environ[str("DJANGO_COLORS")] = str("nocolor")
  44. super(Command, self).execute(*args, **options)
  45. def get_handler(self, *args, **options):
  46. """
  47. Returns the default WSGI handler for the runner.
  48. """
  49. return get_internal_wsgi_application()
  50. def handle(self, *args, **options):
  51. from django.conf import settings
  52. if not settings.DEBUG and not settings.ALLOWED_HOSTS:
  53. raise CommandError('You must set settings.ALLOWED_HOSTS if DEBUG is False.')
  54. self.use_ipv6 = options.get('use_ipv6')
  55. if self.use_ipv6 and not socket.has_ipv6:
  56. raise CommandError('Your Python does not support IPv6.')
  57. self._raw_ipv6 = False
  58. if not options.get('addrport'):
  59. self.addr = ''
  60. self.port = self.default_port
  61. else:
  62. m = re.match(naiveip_re, options['addrport'])
  63. if m is None:
  64. raise CommandError('"%s" is not a valid port number '
  65. 'or address:port pair.' % options['addrport'])
  66. self.addr, _ipv4, _ipv6, _fqdn, self.port = m.groups()
  67. if not self.port.isdigit():
  68. raise CommandError("%r is not a valid port number." % self.port)
  69. if self.addr:
  70. if _ipv6:
  71. self.addr = self.addr[1:-1]
  72. self.use_ipv6 = True
  73. self._raw_ipv6 = True
  74. elif self.use_ipv6 and not _fqdn:
  75. raise CommandError('"%s" is not a valid IPv6 address.' % self.addr)
  76. if not self.addr:
  77. self.addr = '::1' if self.use_ipv6 else '127.0.0.1'
  78. self._raw_ipv6 = bool(self.use_ipv6)
  79. self.run(**options)
  80. def run(self, **options):
  81. """
  82. Runs the server, using the autoreloader if needed
  83. """
  84. use_reloader = options.get('use_reloader')
  85. if use_reloader:
  86. autoreload.main(self.inner_run, None, options)
  87. else:
  88. self.inner_run(None, **options)
  89. def inner_run(self, *args, **options):
  90. # If an exception was silenced in ManagementUtility.execute in order
  91. # to be raised in the child process, raise it now.
  92. autoreload.raise_last_exception()
  93. threading = options.get('use_threading')
  94. shutdown_message = options.get('shutdown_message', '')
  95. quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C'
  96. self.stdout.write("Performing system checks...\n\n")
  97. self.check(display_num_errors=True)
  98. self.check_migrations()
  99. now = datetime.now().strftime('%B %d, %Y - %X')
  100. if six.PY2:
  101. now = now.decode(get_system_encoding())
  102. self.stdout.write(now)
  103. self.stdout.write((
  104. "Django version %(version)s, using settings %(settings)r\n"
  105. "Starting development server at http://%(addr)s:%(port)s/\n"
  106. "Quit the server with %(quit_command)s.\n"
  107. ) % {
  108. "version": self.get_version(),
  109. "settings": settings.SETTINGS_MODULE,
  110. "addr": '[%s]' % self.addr if self._raw_ipv6 else self.addr,
  111. "port": self.port,
  112. "quit_command": quit_command,
  113. })
  114. try:
  115. handler = self.get_handler(*args, **options)
  116. run(self.addr, int(self.port), handler,
  117. ipv6=self.use_ipv6, threading=threading)
  118. except socket.error as e:
  119. # Use helpful error messages instead of ugly tracebacks.
  120. ERRORS = {
  121. errno.EACCES: "You don't have permission to access that port.",
  122. errno.EADDRINUSE: "That port is already in use.",
  123. errno.EADDRNOTAVAIL: "That IP address can't be assigned to.",
  124. }
  125. try:
  126. error_text = ERRORS[e.errno]
  127. except KeyError:
  128. error_text = force_text(e)
  129. self.stderr.write("Error: %s" % error_text)
  130. # Need to use an OS exit because sys.exit doesn't work in a thread
  131. os._exit(1)
  132. except KeyboardInterrupt:
  133. if shutdown_message:
  134. self.stdout.write(shutdown_message)
  135. sys.exit(0)
  136. def check_migrations(self):
  137. """
  138. Checks to see if the set of migrations on disk matches the
  139. migrations in the database. Prints a warning if they don't match.
  140. """
  141. try:
  142. executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
  143. except ImproperlyConfigured:
  144. # No databases are configured (or the dummy one)
  145. return
  146. except MigrationSchemaMissing:
  147. self.stdout.write(self.style.NOTICE(
  148. "\nNot checking migrations as it is not possible to access/create the django_migrations table."
  149. ))
  150. return
  151. plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
  152. if plan:
  153. apps_waiting_migration = sorted(set(migration.app_label for migration, backwards in plan))
  154. self.stdout.write(
  155. self.style.NOTICE(
  156. "\nYou have %(unpplied_migration_count)s unapplied migration(s). "
  157. "Your project may not work properly until you apply the "
  158. "migrations for app(s): %(apps_waiting_migration)s." % {
  159. "unpplied_migration_count": len(plan),
  160. "apps_waiting_migration": ", ".join(apps_waiting_migration),
  161. }
  162. )
  163. )
  164. self.stdout.write(self.style.NOTICE("Run 'python manage.py migrate' to apply them.\n"))
  165. # Kept for backward compatibility
  166. BaseRunserverCommand = Command