← Назад к вопросам

Что происходит когда запускаем Django на определенном порту?

1.7 Middle🔥 101 комментариев
#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что происходит при запуске Django на определённом порту

Команда и процесс

# Стандартная команда
python manage.py runserver 8000

# Или с явным адресом
python manage.py runserver 0.0.0.0:8000

# Или с другим портом
python manage.py runserver 127.0.0.1:5000

Что происходит: пошагово

Шаг 1: Django заводит и инициализирует приложение

# manage.py запускает:
if __name__ == "__main__":
    from django.core.management import execute_from_command_line
    # Парсит аргументы: runserver 8000
    execute_from_command_line(sys.argv)

Шаг 2: Загрузка конфигурации

# Django загружает settings.py
import django
django.setup()  # Инициализирует:

# - Приложения (INSTALLED_APPS)
# - Базу данных
# - Кэш
# - Статические файлы
# - Middleware
# - URL routing
# - etc.

Шаг 3: Запуск development сервера

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

from django.core.wsgi import get_wsgi_application

class Command(BaseCommand):
    def handle(self, *args, **options):
        # Запускает встроенный WSGI сервер (Werkzeug)
        self.wsgi_application = get_wsgi_application()
        
        # Слушает на порту 8000
        server = self.get_server(
            host='0.0.0.0',  # или другой адрес
            port=8000
        )
        
        server.serve_forever()

Детальный процесс

1. Парсинг аргументов

# runserver 8000 → парсится как:
command = "runserver"
args = ["8000"]  # На порту 8000
options = {
    "addrport": "0.0.0.0:8000",
    "use_reloader": True,  # Auto-reload при изменении кода
    "use_threading": False,  # Single-threaded (или многопоточный)
}

2. Привязка к порту (socket binding)

import socket

# Django создаёт socket и привязывает его
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Привязывает к адресу и порту
try:
    sock.bind(("0.0.0.0", 8000))
    sock.listen(5)  # Очередь входящих соединений: 5
    print("Django version 4.2, using settings 'myproject.settings'")
    print("Starting development server at http://127.0.0.1:8000/")
except OSError as e:
    if "Address already in use" in str(e):
        print("Error: Port 8000 already in use!")
        # Нужно использовать другой порт или kill процесс

3. Запуск event loop

# Werkzeug (встроенный dev сервер) запускает loop:

while True:
    # 1. Принимает соединение
    client_socket, client_address = sock.accept()
    print(f"Connection from {client_address}")
    
    # 2. Читает HTTP запрос
    request_data = client_socket.recv(4096)  # До 4KB
    request = parse_http_request(request_data)
    
    # 3. Обрабатывает через Django WSGI
    environ = {
        'REQUEST_METHOD': 'GET',
        'PATH_INFO': '/admin/',
        'SERVER_NAME': 'localhost',
        'SERVER_PORT': '8000',
        # ... другие переменные
    }
    
    # Передаёт в Django приложение
    response = wsgi_app(environ, start_response)
    
    # 4. Отправляет ответ
    client_socket.send(response)
    client_socket.close()

Auto-reload механизм

# Django по умолчанию наблюдает за файлами
# и перезагружает сервер при изменении

watcher = FileSystemEventHandler()

for file in project_files:
    if file.endswith('.py'):
        watcher.watch(file)
        
        if file.modified():
            print(f"Detected change in {file}")
            print("Restarting server...")
            # Убивает текущий процесс
            # Запускает новый
            os.execv(sys.executable, [sys.executable] + sys.argv)

Что видит пользователь

$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
April 23, 2024 - 15:30:45
Django version 4.2, using settings 'myproject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

GET /admin/ HTTP/1.1
[23/Apr/2024 15:30:50] "GET /admin/ HTTP/1.1" 200 5023

Многопоточность

Default (single-threaded):

# Один поток обрабатывает запросы
# Если запрос долгий (5 сек), следующий ждёт

Client 1: GET /api/slow-operation/  (занимает 5 сек)
Client 2: GET /api/fast-operation/   (ждёт 5 сек + обработка)

С многопоточностью:

python manage.py runserver --nothreading  # Отключить threading
python manage.py runserver --nothreading  # Медленнее для нескольких клиентов

Обработка HTTP запроса в Django

# Django WSGI приложение:
from django.core.wsgi import get_wsgi_application

application = get_wsgi_application()

# Получает environ (переменные окружения от сервера)
# и start_response (callback для отправки заголовков)

def django_app(environ, start_response):
    # 1. Создаёт WSGIRequest
    request = WSGIRequest(environ)
    
    # 2. Проходит через middleware
    for middleware in MIDDLEWARE:
        request = middleware.process_request(request)
    
    # 3. Маршрутизирует запрос (URL routing)
    view_function = resolve(request.path)
    
    # 4. Вызывает view
    response = view_function(request)
    
    # 5. Проходит ответ через middleware
    for middleware in reversed(MIDDLEWARE):
        response = middleware.process_response(request, response)
    
    # 6. Отправляет ответ
    start_response(
        '200 OK',
        [
            ('Content-Type', 'text/html'),
            ('Content-Length', str(len(response)))
        ]
    )
    return [response]

Проблемы и их решение

1. Port already in use

# ❌ Ошибка
$ python manage.py runserver 8000
Error: "Address already in use"

# ✅ Решение 1: Другой порт
python manage.py runserver 8001

# ✅ Решение 2: Force reuse
python manage.py runserver --force-color 8000

# ✅ Решение 3: Kill процесс
kill -9 $(lsof -t -i:8000)  # Unix/Linux/Mac
netstat -ano | findstr :8000  # Windows
taskkill /PID <PID> /F

**2. Connection refused

# ❌ Проблема
ERROR: [Errno 98] Address already in use

# Причина: Другой процесс занимает порт
kill -9 $(lsof -t -i:8000)
python manage.py runserver

**3. Port denied (permission denied)

# ❌ Проблема
ERROR: [Errno 13] Permission denied

# Причина: Попытка использовать привилегированный порт (< 1024)
# ✅ Решение: Использовать порт > 1024
python manage.py runserver 8000

# Или с sudo (не рекомендуется в разработке)
sudo python manage.py runserver 80

WSGI Application

# myproject/wsgi.py
import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

application = get_wsgi_application()

# Это что вызывает сервер (в production: Gunicorn, uWSGI, etc.)
# application(environ, start_response) → response

Production vs Development

# Development (manage.py runserver)
services = {
    "Server": "Werkzeug (встроенный)",
    "Worker Count": 1,
    "Threading": "Опционально",
    "Static Files": "Автоматически по /static/",
    "Auto Reload": "Есть",
    "Performance": "Медленно",
    "Security": "Низкая",
    "Use Cases": "Разработка"
}

# Production (Gunicorn + Nginx)
services = {
    "Server": "Gunicorn (application server)",
    "Reverse Proxy": "Nginx (web server)",
    "Worker Count": "4-8+ (multi-worker)",
    "Threading": "Многопоточность / async",
    "Static Files": "Nginx отдает статику",
    "Auto Reload": "Нет",
    "Performance": "Быстро (10x+)",
    "Security": "Высокая",
    "Use Cases": "Production"
}

Запуск в Production

# Gunicorn (Application Server)
gunicorn myproject.wsgi:application \
    --workers 4 \
    --bind 127.0.0.1:8000 \
    --timeout 30 \
    --access-logfile - \
    --error-logfile -

# uWSGI (Alternative)
uwsgi --http :8000 \
    --wsgi-file myproject/wsgi.py \
    --callable application \
    --processes 4 \
    --threads 2

Заключение

Когда запускаем python manage.py runserver 8000:

  1. Django инициализируется — загружаются settings, БД, приложения
  2. Создаётся WSGI приложение — Django app готово обрабатывать запросы
  3. Запускается Werkzeug dev сервер — слушает на 0.0.0.0:8000
  4. Принимает HTTP запросы — парсит, маршрутизирует, обрабатывает
  5. Auto-reload — перезагружает при изменении файлов
  6. Отправляет ответы — HTML, JSON, редиректы и т.д.

Важно: Dev сервер медленный и небезопасный. Для production используй Gunicorn + Nginx.