You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Heroku部署Django DRF遇媒体类型错误及PostgreSQL连接问题

Django DRF + PostgreSQL Heroku部署全指南(附问题排查)

你的问题复盘

我最近把纯API的Django项目用Gunicorn部署到Heroku后,遇到两个棘手问题:

  1. 调用<Heroku域名>/api/login接口时,明明前端已经设置了content-type: application/json并提交JSON数据,却返回错误:"detail": "Unsupported media type \"application/x-www-form-urlencoded\" in request.",但本地完全正常。
  2. 数据库连接失败,日志显示尝试连接localhost的5432端口,返回503/500错误,只有手动执行heroku pg:psql postgresql-shaped-60432 --app <应用名>才好像能暂时解决,但每次部署都要手动操作太麻烦。

当前我的配置:

  • 视图里已在非文件上传接口设置parser_classes = [JSONParser],文件上传用FileUploadParser
  • 前端请求头配置:
    const token_config = {
      headers: {
        'content-type': 'application/json',
        accept: 'application/json',
        'Authorization': 'Bearer ${token}',
        //withCredentials : true,
      },
    };
    
  • requirements.txt内容:
    Django==3.1.1
    django-allauth==0.42.0
    django-cors-headers==3.5.0
    django-environ==0.4.5
    django-rest-auth==0.9.5
    django-sslserver==0.20
    djangorestframework==3.11.1
    djangorestframework-simplejwt==4.1.3
    gunicorn==20.0.4
    image==1.5.27
    importlib-metadata==1.7.0
    oauthlib==3.1.0
    Pillow==7.2.0
    psycopg2-binary==2.8.2
    PyJWT==1.7.1
    

核心疑问解答+分步解决方案

一、settings.py怎么配置才能和本地表现一致?

这是解决两个问题的核心,重点关注以下几个部分:

1. 跨域与DRF解析器配置

媒体类型错误的根源大概率是请求头没有被正确接收或者DRF全局解析器配置缺失:

  • 首先确保CORS中间件在settings.py的MIDDLEWARE里顺序正确(必须放在django.middleware.common.CommonMiddleware之前):
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 其他中间件...
    ]
    
  • 全局配置DRF的解析器,避免单个视图配置遗漏:在settings.py末尾添加:
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            # 如果需要支持表单提交,可保留FormParser,但你的场景只需要JSON
            # 'rest_framework.parsers.FormParser',
        ],
        # 其他DRF配置,比如权限类、认证类...
    }
    
  • 检查前端请求的小坑:你写的'Authorization': 'Bearer ${token}'用了单引号,模板字符串变量替换必须用反引号包裹整个字符串,否则${token}会被当成字面量,修正为:
    const token_config = {
      headers: {
        'content-type': 'application/json',
        accept: 'application/json',
        'Authorization': `Bearer ${token}`, // 这里用反引号
      },
    };
    

2. 数据库配置(彻底解决连接localhost问题)

Heroku的PostgreSQL是托管服务,绝对不能硬编码localhost,必须用环境变量读取:

  • 用django-environ加载Heroku的DATABASE_URL环境变量(你已经安装了django-environ,直接用):
    import environ
    import os
    
    env = environ.Env(
        DEBUG=(bool, False)
    )
    # 读取本地.env文件(开发环境用),Heroku上会自动忽略,因为环境变量已设置
    environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
    
    # 数据库配置
    DATABASES = {
        'default': env.db(),
    }
    # 保持数据库连接,避免频繁断开
    DATABASES['default']['CONN_MAX_AGE'] = 500
    
  • 确保ALLOWED_HOSTS包含你的Heroku域名:
    ALLOWED_HOSTS = ['<你的应用名>.herokuapp.com', 'localhost', '127.0.0.1']
    
  • 生产环境必须关闭DEBUG:
    DEBUG = env('DEBUG') # 本地.env里设DEBUG=True,Heroku上用heroku config:set DEBUG=False设置
    

二、部署后需要手动启动数据库吗?绝对不需要!

你遇到的数据库连接错误,根本原因是settings.py里数据库配置还是指向localhost,不是因为需要手动启动数据库。正确的流程是:

  1. 部署前先在Heroku添加PostgreSQL插件(如果还没加):
    heroku addons:create heroku-postgresql:hobby-dev --app <你的应用名>
    
  2. 部署后执行数据库迁移(创建表结构):
    heroku run python manage.py migrate --app <你的应用名>
    
  3. 不需要手动进psql,除非你要手动操作数据库。如果还是出现连接错误,检查:
    • 有没有运行heroku config:set SECRET_KEY=<你的密钥>?Heroku上必须设置SECRET_KEY,不能用本地的。
    • 查看Heroku的环境变量:heroku config --app <你的应用名>,确认DATABASE_URL存在。

完整的Heroku部署流程(走一遍避免遗漏)

  1. 项目根目录创建Procfile(无后缀),内容:
    web: gunicorn <你的项目名>.wsgi --log-file -
    
    比如你的项目名叫myapi,那就是web: gunicorn myapi.wsgi --log-file -
  2. 本地创建.env文件(加入.gitignore,不要提交到Git),内容:
    DEBUG=True
    SECRET_KEY=你的本地密钥
    DATABASE_URL=postgres://localhost:5432/你的本地数据库名
    
  3. 提交代码到Git:
    git add .
    git commit -m "Prepare for Heroku deployment"
    
  4. 推送代码到Heroku:
    git push heroku main
    
  5. 设置Heroku环境变量:
    heroku config:set DEBUG=False SECRET_KEY=你的生产环境密钥 --app <你的应用名>
    
  6. 执行迁移:
    heroku run python manage.py migrate --app <你的应用名>
    
  7. 查看日志排查问题:
    heroku logs --tail --app <你的应用名>
    

内容的提问来源于stack exchange,提问作者ninja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:57:38