如何在 Django 模板中发布隐藏的文件字段?
我正在尝试在 Django 中上传文件,但遇到了障碍。我的目标是创建一个表单,允许用户上传文本和文件数据、预览该输入,然后发布它。
我将所有逻辑放在一个视图中,其中包含与各种提交按钮关联的多个模板。我不想保存所有实例,然后为已发布的帖子创建自定义管理器。然而,也许我应该这样做。
我的问题是我的文件格式集无法正常工作。我刚提交数据的时候,没有预览,是可以的。但是,有一次,我开始向不同的模板发帖,它就停止工作了。我知道您想在 POST 之后进行 HttpResponseRedirect,但我认为在这种情况下我的方法很好。老实说我不知道。
这是我的视图逻辑
def post(request):
page="post"
#check if user has already posted and if so, direct them to their account post history page
try:
user=User.objects.get(pk=request.user.id)
except User.DoesNotExist:
user=''
if user:
try:
post=user.post_set.all()[0]
return HttpResponseRedirect("/profile/post/")
#Here a user who has not posted is shown a form to do so
except IndexError:
postform=PostForm(prefix="post")
PhotoFormSet=modelformset_factory(Post_Photo,exclude=('post',), extra=4, max_num=4)
photo_formset=PhotoFormSet(queryset=Post_Photo.objects.filter(post__lt=0),prefix="photos") #lt 0 is a hack to return an empty query set, so that other photos aren't returned with the form
#Here an anonymous user sees the form, though they can't successfully submit
else:
postform=PostForm(prefix="post")
PhotoFormSet=modelformset_factory(Post_Photo,exclude=('post',), extra=4, max_num=4)
photo_formset=PhotoFormSet(queryset=Post_Photo.objects.filter(post__lt=0),prefix="photos")
if request.method=='POST' and user and request.POST.get('preview'):
photo_formset=PhotoFormSet(request.POST, request.FILES, prefix="photos")
postform=PostForm(request.POST,prefix="post")
if postform.is_valid() and photo_formset.is_valid():
post=postform.save(commit=False)
photos=photo_formset.save(commit=False)
return render_to_response('website/preview_post.html', {'page':page,'post':post,'photos':photos,'photo_formset':photo_formset}, context_instance=RequestContext(request))
else:
return HttpResponse('error test')
if request.method=='POST' and user and request.POST.get('edit'):
photo_formset=PhotoFormSet(request.POST, request.FILES, prefix="photos")
postform=PostForm(request.POST,prefix="post")
neighborhood=request.POST.get('post-neighborhood','')
if postform.is_valid() and photo_formset.is_valid():
return render_to_response('website/post_upload.html', {'page':page, 'neighborhood':neighborhood,'postform':postform, 'photo_formset':photo_formset}, context_instance=RequestContext(request))
else:
return HttpResponse(postform.errors)
if request.method=='POST' and user and request.POST.get('publish'):
photo_formset=PhotoFormSet(request.POST, request.FILES, prefix="photos")
postform=PostForm(request.POST,prefix="post")
if postform.is_valid() and photo_formset.is_valid():
post=postform.save(commit=False)
post.user=user
post.save()
photos=photo_formset.save(commit=False)
for photo in photos:
photo.post=post
photo.save()
return HttpResponse('/post_upload/?success=1')
else:
return HttpResponse('%s' %postform.errors)
return render_to_response("website/post_upload.html", {'page':page,'postform':postform,'photo_formset':photo_formset}, context_instance=RequestContext(request))
在我的预览模板中,我包含隐藏的输入,然后将其发布回编辑页面或发布。我的 photo_formset 包含在具有 display:none 属性的 div 中,因此它是不可见的。
当我从编辑页面发布时,隐藏的文本输入会通过,但文件输入不会。对此我能做什么?
谢谢
I'm attempting to deal with uploading files in Django and I've hit a snag. My goal is to create a form which allows users to upload text and file data, preview that input, and then publish it.
I put all the logic in a single view with multiple templates associated with the various submit buttons. I didn't want to save all of the instances and then create a custom manager for published posts. However, perhaps I should do that.
My issue is that my file formset isn't working properly. When I just submitted the data, without previewing it, it was fine. But, once, I started POSTing back forth to different templates, it stopped working. I know that you want to HttpResponseRedirect after a POST, but i figured my method was fine in this case. I honestly have no clue.
Here's my view logic
def post(request):
page="post"
#check if user has already posted and if so, direct them to their account post history page
try:
user=User.objects.get(pk=request.user.id)
except User.DoesNotExist:
user=''
if user:
try:
post=user.post_set.all()[0]
return HttpResponseRedirect("/profile/post/")
#Here a user who has not posted is shown a form to do so
except IndexError:
postform=PostForm(prefix="post")
PhotoFormSet=modelformset_factory(Post_Photo,exclude=('post',), extra=4, max_num=4)
photo_formset=PhotoFormSet(queryset=Post_Photo.objects.filter(post__lt=0),prefix="photos") #lt 0 is a hack to return an empty query set, so that other photos aren't returned with the form
#Here an anonymous user sees the form, though they can't successfully submit
else:
postform=PostForm(prefix="post")
PhotoFormSet=modelformset_factory(Post_Photo,exclude=('post',), extra=4, max_num=4)
photo_formset=PhotoFormSet(queryset=Post_Photo.objects.filter(post__lt=0),prefix="photos")
if request.method=='POST' and user and request.POST.get('preview'):
photo_formset=PhotoFormSet(request.POST, request.FILES, prefix="photos")
postform=PostForm(request.POST,prefix="post")
if postform.is_valid() and photo_formset.is_valid():
post=postform.save(commit=False)
photos=photo_formset.save(commit=False)
return render_to_response('website/preview_post.html', {'page':page,'post':post,'photos':photos,'photo_formset':photo_formset}, context_instance=RequestContext(request))
else:
return HttpResponse('error test')
if request.method=='POST' and user and request.POST.get('edit'):
photo_formset=PhotoFormSet(request.POST, request.FILES, prefix="photos")
postform=PostForm(request.POST,prefix="post")
neighborhood=request.POST.get('post-neighborhood','')
if postform.is_valid() and photo_formset.is_valid():
return render_to_response('website/post_upload.html', {'page':page, 'neighborhood':neighborhood,'postform':postform, 'photo_formset':photo_formset}, context_instance=RequestContext(request))
else:
return HttpResponse(postform.errors)
if request.method=='POST' and user and request.POST.get('publish'):
photo_formset=PhotoFormSet(request.POST, request.FILES, prefix="photos")
postform=PostForm(request.POST,prefix="post")
if postform.is_valid() and photo_formset.is_valid():
post=postform.save(commit=False)
post.user=user
post.save()
photos=photo_formset.save(commit=False)
for photo in photos:
photo.post=post
photo.save()
return HttpResponse('/post_upload/?success=1')
else:
return HttpResponse('%s' %postform.errors)
return render_to_response("website/post_upload.html", {'page':page,'postform':postform,'photo_formset':photo_formset}, context_instance=RequestContext(request))
In my preview template, I include hidden inputs that are then POSTed either back to the edit page or published. My photo_formset is contained in a div with display:none property so it's invisible.
When I POST from the edit page, the hidden text inputs go through but the FILE inputs do not. What can I do about this?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的猜测是文件输入不会传递到步骤 2,因为
元素不包含数据并且不会预先填充。
在加载时始终为空白。
您无法在浏览器刷新之间共享文件数据,除非您将数据编码到表单文本元素中并对其进行解码或将其存储在会话中。
这是一种浏览器安全措施。
在这里检查我的答案:
Resubmitting Image in ImageField after Validation Error in Django
我会将保存的文件信息存储在会话中,并在表单的第 3 步中将其取出。
或者,您可以设置 ajax 预览等?
My guess is that the file inputs are not being passed into step 2, because
<input type="file">
elements don't contain data and don't get prepopulated.<input type="file">
are always blank on load.You can't share file data between browser refreshes, unless you encode the data into a form text element and decode it or store it in the session.
It's a browser security measure.
Check my answer here:
Resubmitting Image in ImageField after Validation Error in Django
I'd store the saved file information in the session and pull it back out in step 3 of your form.
Or, you could set up an ajax preview or such?