在Django应用程序中,我想使用fetch / post API将JSON保存到数据库中。两个问题:(1)我遇到CSRF验证问题,(2)我不确定是否一般使用POST来修改数据库。
我有一个模型“Job”,其中一个字段应该包含JSON。
class Job(models.Model):
job_id = models.IntegerField()
setup_json = models.CharField(max_length=100000, blank=True, null=True)
JSON通过页面上的用户交互生成。当按下“保存”按钮时,我想将JSON写入正确作业的setup_json
字段。
我不想使用表单,因为JSON存储在JavaScript中而不是在页面的任何地方写入。所以我直接使用CSRF令牌from the template,如下所示:
{% csrf_token %}
<script type="text/javascript">
const csrftoken = document.getElementsByName("csrfmiddlewaretoken")[0].value;
</script>
(注意:在我的“settings.py”文件中,我添加了行CSRF_USE_SESSIONS = True
以使用此技术。)
然后我有我的保存按钮调用这样的函数:
function onPressSave() {
fetch(`webapp/api/save-json/${jobId}`, {
method: "POST",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": csrftoken,
"Content-Type": "application/json; charset=utf-8",
Accept: "application/json"
},
credentials: "same-origin",
body: JSON.stringify("test json")
});
}
我在控制台中收到“POST 403(Forbidden)”错误。任何有关这方面的帮助将不胜感激!
我也不确定接收功能到底应该是什么样子。目前它看起来像这样:
def save_json(request, id):
j = Job.objects.get(job_id=id)
j.setup_json = json.dumps(dict(name="testing"))
return HttpResponse("OK")
我最终想要从POST请求中检索正确的JSON,但看起来我是否在使用此功能的正确轨道上?
Django ORM支持各种数据库的JSONFields,例如,如果您使用的是mySQL后端,则可以:
from django_mysql.models import JSONField
setup_json = JSONField(null=True)
或者使用PostGreSQL:
from django.contrib.postgres.fields import JSONField
setup_json = JSONField(null=True)
然后使用您的保存功能,您可以:
def save_json(request, id):
# The json you want to save, litterally a python dict {}, or list of dicts [{},{},...]
json_to_be_saved = {}
j = Job.objects.get(job_id=id)
j.setup_json = json_to_be_saved
j.save()
return HttpResponse("OK")
关于403,可能是您的设置文件中没有:
CORS_ORIGIN_ALLOW_ALL = True
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # <- Added in manually, must be at the top of this list
这将需要你pip安装:pip3 install django-cors-headers
这是我很久以前做的事情:
$.ajax({
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
url: "{% url 'login_verification_view' %}",
headers: {
'X-CSRFToken': '{{ csrf_token }}'
},
success: function(j) {
...
your code
}