Django,上传图片在Ajax调用中抛出403 CSRF令牌丢失错误



我正在尝试使用Django上传多个文件。这个想法是,在创建博客文章的同时,用户还可以在文章中添加图像。我正在使用Ajax提交博客文章,然而,在添加图像表单后,"提交"按钮似乎不起作用,我的文章也没有创建。我已经建立了两个模型,Images和Post。以下是与此功能相关的代码。我的项目名称是register,图像在一个名为"home"的应用程序中:(如果我删除了图像上传功能,则帖子创建成功,因此ajax工作正常(

我的图像模型:

我在家庭应用程序视图中的post_creat视图:

@login_required
def post_create(request):
data = dict()
if request.method == 'POST':
image_form = ImageForm(request.POST, request.FILES or None)
images = request.FILES.getlist('image')
form = PostForm(request.POST)
if form.is_valid() and image_form.is_valid():    
post = form.save(False)
post.author = request.user
post.save()
for i in images:
image_instance = Images(image=i,post=post)
image_instance.save()
data['form_is_valid'] = True
posts = Post.objects.all()
posts = Post.objects.order_by('-last_edited')
data['posts'] = render_to_string('home/posts/home_post.html',{'posts':posts},request=request)
else:
data['form_is_valid'] = False
else:
image_form = ImageForm
form = PostForm      
context = {
'form':form,
'image_form':image_form
}
data['html_form'] = render_to_string('home/posts/post_create.html',context,request=request)
return JsonResponse(data) 

我处理ajax请求的javascript代码:

$(document).ready(function(){
var ShowForm = function(e){
e.stopImmediatePropagation();
var btn = $(this);
$.ajax({
url: btn.attr("data-url"),
type: 'get',
dataType:'json',
beforeSend: function(){
$('#modal-post').modal('show');
},
success: function(data){
$('#modal-post .modal-content').html(data.html_form);
}
});
return false;
};
// change form to FormData
// var form = $(this)
// processData, contentType were removed
var SaveForm =  function(e){
e.stopImmediatePropagation();
var data = new FormData($('form').get(0));
$.ajax({
url: $(this).attr('data-url'),
type: $(this).attr('method'),
data: data,
processData: false,
contentType: false,
dataType: 'json',
success: function(data){
if(data.form_is_valid){
$('#post-list div').html(data.posts);
$('#modal-post').modal('hide');
} else {
$('#modal-post .modal-content').html(data.html_form)
}
}
})
return false;
}
//create
$('.create-post-btn').click(ShowForm);
$('#modal-post').on("submit",".post-create-form",SaveForm)
//update
$('#post-list').on("click",".show-form-update",ShowForm);
$('#modal-post').on("submit",".update-form",SaveForm)
//delete
$('#post-list').on("click",".show-form-delete",ShowForm);
$('#modal-post').on("submit",".delete-form",SaveForm)
});

我的post_create.html文件:

<form method="POST" data-url="{% url 'home:post-create' %}" class="post-create-form" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title" >Create a Post</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" style="overflow-y: auto;">
{{ form|crispy }}
<button type="button" id="show-image-upload-inputs" class="btn btn-sm mr-auto btn-primary pb-1">
<span><i class="fas fa-camera"></i></span>
</button>
<div id="image-upload-div" class="mt-1" style="display: none;">
<hr class="my-2">
<p class="mx-2 text-muted small">Add up to four images to your post</p>
<div class="d-flex flex-row justify-content-between px-1">
{{ image_form }}    
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</form>

**隐藏的显示只是一个javascript功能,当用户点击vamera按钮时显示表单。

我的图像模型:

class Images(models.Model):
post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name='images')
image = models.FileField(upload_to=upload_to_uuid('media/post_images/'),verbose_name='Image')
date_added = models.DateTimeField(auto_now_add=True)

我的项目(注册(设置.py:

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

我的项目(注册(urls.py;

urlpatterns = [
#Has to be included for Forgot Password funcitonality on main page
path('', include('django.contrib.auth.urls')), 
path('admin/', admin.site.urls),    
path('',views.user_login,name='user_login'),
path('',include('main.urls'),name='main'), 
url(r'^home/',include(('home.urls','home'), namespace='home'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT ) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

并且我的媒体文件夹是在注册/media中创建的

编辑:我已经更改了Ajax函数,现在我正在使用FormData,但是,我得到了一个

Forbidden (CSRF token missing or incorrect.): /home/post/create/
[06/Apr/2020 01:18:53] "POST /home/post/create/ HTTP/1.1" 403 2513

错误,当我点击提交时,我确实有一个csrf_token。如何解决此问题?

您的代码发布模型应该是这样的

class Post(models.Model):
title=models.CharField(max_length=50)
sub_title=models.CharField(default="This is the subtitle of the post ",max_length=150)
content=models.TextField(max_length=4000)
date_posted=models.DateTimeField(default=timezone.now)
blog_image_1=models.ImageField(Blank=True,Null=True,upload_to='media')
blog_image_2=models.ImageField(Blank=True,Null=True,upload_to='media')
blog_image_3=models.ImageField(default='default.jpg',upload_to='media')
author =models.ForeignKey(User,on_delete=models.CASCADE) 
def __str__(self):
return self.title

媒体目录如下

MEDIA_ROOT=os.path.join(BASE_DIR,'media')
MEDIA_URL='/media/'

Html就像

<body>
<div class="container">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="'border-bottom mb-4">Post</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn-outline-info" type="submit"> Submit</button>
</div>
</form>
</div>
</body>

并使用类基础视图他们更强大完整

class PostCreateView(LoginRequiredMixin,CreateView):
model = Post
fields = ['title','sub_title','content','blog_image_1','blog_image_2','blog_image_2']

def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)

最新更新