尝试使用FileField上传文件时,表单不会将文件数据发布到服务器。 如果您使用文本字段,它可以正常工作,但由于某种原因,它无法识别文件,因为它没有 根据要求出现.FILES,或request.POSTS。
MEDIA_ROOT和MEDIA_URL配置:
MEDIA_ROOT = '/home/grove/pootleImages/'
MEDIA_URL = '/pootleImages/'
decorators.py中的get_unit_context装饰器:
def get_unit_context(permission_codes):
def wrap_f(f):
@wraps(f)
def decorated_f(request, uid, *args, **kwargs):
unit = get_object_or_404(
Unit.objects.select_related("store__translation_project",
"store__parent"),
id=uid,
)
_common_context(request, unit.store.translation_project,
permission_codes)
request.unit = unit
request.store = unit.store
request.directory = unit.store.parent
return f(request, unit, *args, **kwargs)
return decorated_f
return wrap_f
我的forms.py方法:
def unit_image_form_factory(language):
image_attrs = {
'lang': language.code,
'dir': language.direction,
'class': 'images expanding focusthis',
'rows': 2,
'tabindex': 15,
}
class UnitImageForm(forms.ModelForm):
class Meta:
fields = ('image',)
model = Unit
# It works if using a CharField!
#image = forms.CharField(required=True,
# label=_("Image"),
# widget=forms.Textarea(
# attrs=image_attrs))
image= forms.FileField(required=True, label=_('Image'),
widget=forms.FileInput(
attrs=image_attrs))
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(UnitImageForm, self).__init__(*args, **kwargs)
def save(self):
super(UnitImageForm, self).save()
return UnitImageForm
我的models.py代码段:
class Unit(models.Model, base.TranslationUnit):
# ...
# ...
# It works if using a TextField!
#image = models.TextField(null=True, blank=True)
image = models.FileField(upload_to=".", blank=True, null=True)
# ...
# ...
我的urls.py片段:
url(r'^xhr/units/(?P<uid>[0-9]+)/image/?$',
'image',
name='pootle-xhr-units-image'),
我的views.py方法:
@require_POST
@ajax_required
@get_unit_context('translate')
def image(request, unit):
"""Stores a new image for the given ``unit``.
:return: If the form validates, the cleaned image is returned.
An error message is returned otherwise.
"""
# Update current unit instance's attributes
unit.uploaded_by = request.profile
unit.uploaded_on = timezone.now()
language = request.translation_project.language
form = unit_image_form_factory(language)(request.POST, request.FILES, instance=unit,
request=request)
if form.is_valid():
form.save()
context = {
'unit': unit,
'language': language,
}
t = loader.get_template('unit/image.html')
c = RequestContext(request, context)
json = {'image': t.render(c)}
rcode = 200
else:
json = {'msg': _("Image submission failed.")}
rcode = 400
response = simplejson.dumps(json)
return HttpResponse(response, status=rcode, mimetype="application/json")
我上传图片的HTML模板:
<div id="upload-image">
<form enctype="multipart/form-data" method="post" action="{% url 'pootle-xhr-units-image' unit.id %}" id="image-form">
{% csrf_token %}
<input type="file" name="image" id="id_image" />
<p><input type="submit" value="{% trans 'Upload' %}" /></p>
</form>
</div>
当实例化表单时,request.POST不返回用户浏览的文件,也不返回request.FILES。
form.errors只返回"This field is required"
表单对象返回以下内容:
<tr><th><label for="id_image">Image:</label></th><td><ul class="errorlist"><li>This field is required.</li>
</ul><input lang="pl" rows="2" name="image" id="id_image" type="file" class="images expanding focusthis" dir="ltr" tabindex="15" /></td></tr>
当用户单击提交按钮时,会发生以下POST错误:
"POST /xhr/units/74923/image HTTP/1.1" 400 35
我可以通过在图像属性中包含required = False来绕过它,但无论如何都不会发布文件。
更多输出调试信息:
需要fileField时的POST = True:
状态代码:400 BAD REQUEST 表格数据: csrfmiddlewaretoken:yoTqPAAjy74GH
form.errors:
“msg”:“
如果需要更改= True到required = False:
状态代码:200 OK 表格数据: csrfmiddlewaretoken:yoTqPAAjy74GH
但是图像字段仍然没有显示在表单数据中。
谢谢,
亚历
我添加了一个gist hub,其中包含与此问题相关的所有文件,以简化可视化:
答案 0 :(得分:0)
您似乎忘记在表单中添加{%csrf_token%}了。在标签之间添加。
... OR
您可以将csrf_exempt装饰器添加到处理视图中:
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
@csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
更多信息:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
答案 1 :(得分:0)
最后设法让它以某种方式运作。在主页面中使用该表单时,该表单根本不起作用,因此我创建了一个指向仅包含上载图像表单的空白页面的链接。当与主页分开时,上传工作正常。然后我上传后重定向到主页面。为什么表单在主页面中不起作用,这是个谜。