Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

from optparse import make_option 

import os 

import re 

import sys 

import socket 

 

from django.core.management.base import BaseCommand, CommandError 

from django.core.servers.basehttp import AdminMediaHandler, run, WSGIServerException, get_internal_wsgi_application 

from django.utils import autoreload 

 

naiveip_re = re.compile(r"""^(?: 

(?P<addr> 

    (?P<ipv4>\d{1,3}(?:\.\d{1,3}){3}) |         # IPv4 address 

    (?P<ipv6>\[[a-fA-F0-9:]+\]) |               # IPv6 address 

    (?P<fqdn>[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*) # FQDN 

):)?(?P<port>\d+)$""", re.X) 

DEFAULT_PORT = "8000" 

 

 

class BaseRunserverCommand(BaseCommand): 

    option_list = BaseCommand.option_list + ( 

        make_option('--ipv6', '-6', action='store_true', dest='use_ipv6', default=False, 

            help='Tells Django to use a IPv6 address.'), 

        make_option('--nothreading', action='store_false', dest='use_threading', default=True, 

            help='Tells Django to NOT use threading.'), 

        make_option('--noreload', action='store_false', dest='use_reloader', default=True, 

            help='Tells Django to NOT use the auto-reloader.'), 

    ) 

    help = "Starts a lightweight Web server for development." 

    args = '[optional port number, or ipaddr:port]' 

 

    # Validation is called explicitly each time the server is reloaded. 

    requires_model_validation = False 

 

    def get_handler(self, *args, **options): 

        """ 

        Returns the default WSGI handler for the runner. 

        """ 

        return get_internal_wsgi_application() 

 

    def handle(self, addrport='', *args, **options): 

        self.use_ipv6 = options.get('use_ipv6') 

        if self.use_ipv6 and not socket.has_ipv6: 

            raise CommandError('Your Python does not support IPv6.') 

        if args: 

            raise CommandError('Usage is runserver %s' % self.args) 

        self._raw_ipv6 = False 

        if not addrport: 

            self.addr = '' 

            self.port = DEFAULT_PORT 

        else: 

            m = re.match(naiveip_re, addrport) 

            if m is None: 

                raise CommandError('"%s" is not a valid port number ' 

                                   'or address:port pair.' % addrport) 

            self.addr, _ipv4, _ipv6, _fqdn, self.port = m.groups() 

            if not self.port.isdigit(): 

                raise CommandError("%r is not a valid port number." % self.port) 

            if self.addr: 

                if _ipv6: 

                    self.addr = self.addr[1:-1] 

                    self.use_ipv6 = True 

                    self._raw_ipv6 = True 

                elif self.use_ipv6 and not _fqdn: 

                    raise CommandError('"%s" is not a valid IPv6 address.' % self.addr) 

        if not self.addr: 

            self.addr = self.use_ipv6 and '::1' or '127.0.0.1' 

            self._raw_ipv6 = bool(self.use_ipv6) 

        self.run(*args, **options) 

 

    def run(self, *args, **options): 

        """ 

        Runs the server, using the autoreloader if needed 

        """ 

        use_reloader = options.get('use_reloader', True) 

 

        if use_reloader: 

            autoreload.main(self.inner_run, args, options) 

        else: 

            self.inner_run(*args, **options) 

 

    def inner_run(self, *args, **options): 

        from django.conf import settings 

        from django.utils import translation 

 

        threading = options.get('use_threading', False) 

        shutdown_message = options.get('shutdown_message', '') 

        quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C' 

 

        self.stdout.write("Validating models...\n\n") 

        self.validate(display_num_errors=True) 

        self.stdout.write(( 

            "Django version %(version)s, using settings %(settings)r\n" 

            "Development server is running at http://%(addr)s:%(port)s/\n" 

            "Quit the server with %(quit_command)s.\n" 

        ) % { 

            "version": self.get_version(), 

            "settings": settings.SETTINGS_MODULE, 

            "addr": self._raw_ipv6 and '[%s]' % self.addr or self.addr, 

            "port": self.port, 

            "quit_command": quit_command, 

        }) 

        # django.core.management.base forces the locale to en-us. We should 

        # set it up correctly for the first request (particularly important 

        # in the "--noreload" case). 

        translation.activate(settings.LANGUAGE_CODE) 

 

        try: 

            handler = self.get_handler(*args, **options) 

            run(self.addr, int(self.port), handler, 

                ipv6=self.use_ipv6, threading=threading) 

        except WSGIServerException, e: 

            # Use helpful error messages instead of ugly tracebacks. 

            ERRORS = { 

                13: "You don't have permission to access that port.", 

                98: "That port is already in use.", 

                99: "That IP address can't be assigned-to.", 

            } 

            try: 

                error_text = ERRORS[e.args[0].args[0]] 

            except (AttributeError, KeyError): 

                error_text = str(e) 

            sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n') 

            # Need to use an OS exit because sys.exit doesn't work in a thread 

            os._exit(1) 

        except KeyboardInterrupt: 

            if shutdown_message: 

                self.stdout.write("%s\n" % shutdown_message) 

            sys.exit(0) 

 

class Command(BaseRunserverCommand): 

    option_list = BaseRunserverCommand.option_list + ( 

        make_option('--adminmedia', dest='admin_media_path', default='', 

            help='Specifies the directory from which to serve admin media.'), 

    ) 

 

    def get_handler(self, *args, **options): 

        """ 

        Serves admin media like old-school (deprecation pending). 

        """ 

        handler = super(Command, self).get_handler(*args, **options) 

        return AdminMediaHandler(handler, options.get('admin_media_path', ''))