如何填充Django数据库?POST接口预填数据遇CSRF防护如何解决
Django预填充数据库的首选方案
针对生产/测试环境初始化演示数据的场景,优先推荐直接使用Django原生能力实现,无需绕Web接口即可规避CSRF问题,具体可选方案如下:
方案1:使用Django Fixtures(最适合固定初始化数据的场景)
这是Django官方推荐的轻量数据导入方案,操作步骤:
- 先在本地环境手动创建好需要的3条Player演示数据
- 执行导出命令生成数据文件:
python manage.py dumpdata <你的应用名>.Player --indent 2 > players.json - 将生成的json文件放到项目对应目录下,部署后需要初始化时,直接执行导入命令即可完成数据写入:
python manage.py loaddata players.json
方案2:自定义Django管理命令(最适合有复杂逻辑的初始化场景)
如果需要复用现有表单校验逻辑、或者需要加重复数据判断等扩展能力,推荐自定义管理命令,完全和现有Web端创建逻辑对齐,且不需要启动服务即可运行:
- 在你的应用目录下新建层级目录
management/commands/,目录下新增init_players.py文件,代码示例:
from django.core.management.base import BaseCommand from 你的应用名.models import Player from 你的应用名.forms import PlayerForm class Command(BaseCommand): help = '初始化演示用Player数据' def handle(self, *args, **options): # 定义要插入的初始化数据 init_data = [ {"name": "Alice", "role": "sender"}, {"name": "Bob", "role": "receiver"}, {"name": "Charlie", "role": "eavesdropper"}, ] for item in init_data: # 避免重复插入数据 if Player.objects.filter(name=item['name']).exists(): self.stdout.write(self.style.WARNING(f"Player {item['name']} 已存在,跳过创建")) continue # 复用现有表单校验逻辑,和Web端创建逻辑完全一致 form = PlayerForm(item) if form.is_valid(): Player.objects.create(**form.cleaned_data) self.stdout.write(self.style.SUCCESS(f"成功创建Player: {item['name']}")) else: self.stdout.write(self.style.ERROR(f"创建Player {item['name']}失败: {form.errors}"))
- 部署后需要初始化时,直接执行命令即可:
python manage.py init_players
方案3:坚持走Web接口POST的CSRF解决方法
如果确实需要通过调用Web接口实现,之前Session请求失败是因为没有携带CSRF token和必要的校验头,正确脚本写法如下:
import requests session = requests.Session() # 第一步先GET访问表单页,获取CSRF cookie resp = session.get("http://0.0.0.0:8000/create") csrf_token = resp.cookies.get("csrftoken") # POST请求时携带CSRF头和Referer校验 headers = { "X-CSRFToken": csrf_token, "Referer": "http://0.0.0.0:8000/create" } data = {"name":"Bob", "role":"receiver"} resp = session.post("http://0.0.0.0:8000/create", data=data, headers=headers) print(resp.status_code, resp.text)
注意请求地址需要加
http://前缀,否则会触发协议识别错误。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

