文章目录
- Cors 跨域问题
- localhost 阶段
- Heroku 部署阶段
- Procfile 启动文件
- Database 数据库相关内容
- localhost 阶段
- Heroku 部署阶段
- settings.py 中 正确的设置方式
- 官方给出的 settings.py
- makemigration & migrate 数据迁移
- requirements.txt & runtime.txt 版本和库
- 总结
Cors 跨域问题
-
跨域资源共享(Cross-Origin Resource Sharing,CORS)问题可能在本地开发阶段和 Heroku 部署阶段都会出现,具体情况如下:
-
本地开发阶段的
CORS
问题:-
当你在本地运行你的前端应用(例如Vue.js或React应用)和后端服务(例如Django或Node.js服务器)在不同的端口上时,就可能会遇到
CORS
问题。浏览器基于安全原因实施了同源策略,这意味着来自一个源(协议、域名和端口都相同)的JavaScript只能获取该源上的资源。如果尝试获取不同源的资源,就会出现CORS
错误。 -
例如,假设你的前端应用运行在
localhost:3000
,而你的后端服务运行在localhost:8000
,那么从前端应用发送到后端服务的请求将被视为跨源请求。
-
-
Heroku部署阶段的CORS问题:
- 在部署到Heroku或其他任何生产环境后,你的前端应用和后端服务可能会托管在不同的域上。例如,你的前端应用可能托管在Netlify或Vercel上(例如 https://your-frontend.netlify.app),而你的后端服务则托管在Heroku上(例如 https://your-backend.herokuapp.com)。在这种情况下,你的前端应用向后端服务发送的所有请求都将被视为跨源请求。
- 或者当你的后端代码已经在 heroku 上完成部署,但是前端代码还在
local
,那么前端请求后端依然存在CORS
问题 - 要解决这些问题,你需要配置你的后端服务以允许来自你的前端应用的跨源请求。在Django中,你可以使用
django-cors-headers
包来完成此操作。
-
下面我会分别介绍不同阶段的跨域问题的解决方案
localhost 阶段
-
解决跨域问题的根本思路是使用
CORS header
, 当然在本地开发的时候我们可以不去设置CORS headers
,而是简单的在每个可能发生Cors
问题的函数上面加个修饰符号@csrf_exempt
,如下:
-
这样在调试的时候可以很方便
-
在Django中,
@csrf_exempt
是一个装饰器,可以用于特定的视图函数上,以使得该函数免除CSRF保护。当你使用@csrf_exempt
装饰一个视图函数时,这个函数会被排除在CSRF保护之外。也就是说,对这个函数的POST
请求将不需要携带CSRF token
。 -
以下是如何使用
@csrf_exempt
的例子:from django.views.decorators.csrf import csrf_exempt @csrf_exempt def my_view(request): pass
-
再次强调,虽然这种在本地有用,但是当你真的部署服务器的时候,还是需要解决跨域问题
Heroku 部署阶段
- 这时候还是安安稳稳地去改
header
吧,下面是具体方法:
-
安装
django-cors-headers
库:pip install django-cors-headers
-
将它添加到你的
settings.py
的INSTALLED_APPS
中:INSTALLED_APPS = [ ... 'corsheaders', ... ]
-
在
settings.py
的MIDDLEWARE
中,将CorsMiddleware
添加到顶部:MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ... ]
-
然后你需要在你的设置中添加以下设置:
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ... ]
Procfile 启动文件
-
Procfile
是 Heroku 用来知道如何运行你的应用的一种文件。在这个文件中,你定义了应用的各种进程类型以及这些进程对应的命令。 -
这个文件没有后缀,不要自己加任何后缀,如果你是
macos
请注意不要让系统默认给你加.txt
结尾 -
例如,一个典型的Django应用的
Procfile
可能看起来像这样:web: gunicorn YOUR_PROJECT_NAME.wsgi
-
除此之外,
Procfile
也可以包含release
进程类型,该进程类型是每次部署新版本的应用时运行的进程。例如,你可以使用release
进程来运行数据库迁移,这个我们后面会提到。 -
总的来说,
Procfile
是告诉Heroku如何运行你的应用的重要文件,包括启动哪些进程以及如何启动它们。
Database 数据库相关内容
localhost 阶段
django.db.utils.OperationalError: no such table: nnsh_backend_new_roommember
-
nnsh_backend_new_roommember。这个问题可能是由以下原因引起的:
-
模型没有迁移: 当你在 Django 中创建一个新的模型或者改变现有的模型时,你需要创建一个迁移文件(通过
python manage.py makemigrations
)然后应用这个迁移(通过python manage.py migrate
)。如果你没有应用迁移,数据库表将不会被创建。 -
数据库未同步: 如果你的数据库未与你的代码同步,那么可能会出现这个问题。例如,如果你在开发环境中创建并迁移了数据库,但在生产环境中没有做同样的操作。
-
错误的数据库设置: 在 Django 的 settings.py 文件中,你需要为 DATABASES 设置正确的值,包括数据库引擎,数据库名,用户,密码等。
-
-
于是我尝试:
python manage.py makemigrations python manage.py migrate
-
但是没用,经过一番探索,使用下面的命令:
python manage.py makemigrations YOUR_PROJECT_NAME python manage.py migrate
-
所以修改后的命令是:
python manage.py makemigrations nnsh_backend_new python manage.py migrate
Heroku 部署阶段
在部署阶段,数据库要面对几个重要的问题
settings.py 中 正确的设置方式
- 在部署 Heroku 的时候,官网提供了一份
settings.py
的 模板 供我们参考 - 这个
settings.py
的Dataset
部分的定义如下:
官方给出的 settings.py
-
上面展示的是我修改后的代码,但是
settings.py
给的示例如下:
-
可以看出,官方给出的
settings.py
关于Database
部分并没有给完整的描述,这就造成了一个问题,也就是我一开始将代码部署到 Heroku 的时候,总是报有关于数据库的错误,其中有效的错误信息为:django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
-
这表明 Django 在尝试执行数据库操作时无法找到有效的数据库引擎配置。但是我已经按照官方提供的 setting 去设置我的 Database,于是我想,是不是 heroku 的数据库跟 local 部署有很大差异,需要人为提前设定,并且配置。
-
经过证实,确实如此。当你将包含数据库的Django应用部署到Heroku上时,你需要在Heroku上设置数据库。如果你希望使用 Heroku 的
Postgres
服务,可以在Heroku的app settings
中添加 HerokuPostgres
附加组件。这会自动创建一个新的PostgreSQL
数据库,并将连接信息存储在DATABASE_URL
环境变量中。 -
手动设置这个数据库的方式就是:
Overview->Config Add-ons
-
搜索
heroku postgres
然后添加上就行
-
一旦你添加了数据库,Heroku会自动设置一个环境变量
DATABASE_URL
,其中包含了连接到你新的Heroku Postgres
数据库所需的所有信息。 -
接着在
settings.py
中按照我的方式加上那一行
-
上面的代码的作用是读取环境变量(Heroku会自动设置)中的数据库URL,并用它去配置Django的
DATABASES
设置。
makemigration & migrate 数据迁移
-
到这里还没完,因为我们在 Heroku 上设置了我们的数据库,并且在
settings
中配置了,接下来跟在本地一样,我们同样也要对数据进行迁移,也就是migration
操作 -
这个部分我们需要在整个 application 开始之前完成,而 application 的启动基于我们的
Procfile
文件中的web: gunicorn YOUR_PROJECT_NAME.wsgi
,因此在这个句子之前我们需要率先完成migration
-
所以我们将
Procfile
加上一句话:release: python manage.py makemigrations YOUR_PROJECT_NAME && python manage.py migrate web: gunicorn YOUR_PROJECT_NAME.wsgi
-
一定要注意
YOUR_PROJECT_NAME
的部分一定要用自己的项目的名称,别弄错了哦~
requirements.txt & runtime.txt 版本和库
requirements.txt
文件中预先写好所有的 heroku 部署需要使用的 package 的版本信息runtime.txt
文件则是指定python
使用的版本,因为 heroku 本身支持的python
版本并不多,一定弄清楚 heroku 可以支持的python
版本再下手,详情可以看我另一篇关于 heroku 的文章- 一定注意
requirements.txt
一定要多次检查,保证重要的 package 都写进去了,如果遗漏debug
的时候很费劲,尤其是几个特别重要的:Diango==4.0.1 gunicorn==20.1.0 diango-heroku==0.3.1
总结
- 跨域问题,用
cors header
解决,要对应修改settings.py
中的部分 Procfile
注意没有后缀,是部署的程序启动文件,也可以负责 heroku 端数据库的迁移操作requirments.txt
一定写全,runtime.txt
指定好python
版本settings.py
跟着官网指导的写,但是注意数据库部分的定义;同时记得首先在 heroku 的Overview
中把Postgres
数据库手动设置好,要不然数据库调用失败