我正在使用django-crispy-forms(http://django-crispy-forms.readthedocs.org/),我正在尝试使用Jasny Bootstrap文件上传(http://jasny.github.io/bootstrap/javascript.html#fileupload)来使我的网页看起来更好。
据我所知,开箱即用的Crispy表单不支持Jasny文件上传。由于我不是很有经验,我试图使用Crispy表单中的任何可用内容而不是创建自己的布局对象。但是,我已经尝试了好几天了,但它不起作用。
我知道这不是正确的方法,但到目前为止我的尝试是尝试在forms.py中使用Crispy-form的Div来使django生成类似于Jasny文件上传的示例代码。< / p>
来自Jasny文件上传的代码:
<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
<div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;"></div>
<div>
<span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" /></span>
<a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
</div>
</div>
摘自我的forms.py:
Div(
HTML("""<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
<div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;"></div>
<div class"smalltest">
<span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span>
"""),
Field('photo1'),
HTML("""</span><a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a></div></div>"""),
css_class = 'photofield'
),
这是非常难看的代码并且它不起作用,因为我仍然在新按钮内获得原始的“选择文件”按钮。
我非常感谢任何可以提供帮助的人!我一直非常沮丧,拔出了很多头发试图做到这一点:(
非常感谢。
答案 0 :(得分:3)
我以为我会根据其他一些SO答案分享我的解决方案。
首先,您不应该尝试使用Crispy Forms中的布局,因为Jasny的HTML与默认的Crispy Form模板太不一样了。首先,我们创建一个与Jasny一起使用的Crispy Form模板。这基本上只是使用Jasny HTML更新的field.html模板。
file_field.html:
{# Custom Crispy Forms template for rendering an image field. #}
{% load crispy_forms_field %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field|is_checkbox %}
<div class="form-group">
{% if label_class %}
<div class="controls col-{{ bootstrap_device_type }}-offset-{{ label_size }} {{ field_class }}">
{% endif %}
{% endif %}
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" {% if not field|is_checkbox %}class="form-group{% else %}class="checkbox{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors%}{% if field.errors %} has-error{% endif %}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label and not field|is_checkbox and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
{% if field|is_checkboxselectmultiple %}
{% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
{% endif %}
{% if field|is_radioselect %}
{% include 'bootstrap3/layout/radioselect.html' %}
{% endif %}
{% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
{% if field|is_checkbox and form_show_labels %}
<label for="{{ field.id_for_label }}" class="{% if field.field.required %} requiredField{% endif %}">
{% crispy_field field %}
{{ field.label|safe }}
{% include 'bootstrap3/layout/help_text_and_errors.html' %}
</label>
{% else %}
<div class="controls {{ field_class }}">
<div class="fileinput fileinput-{% if field.value and field.value.url %}exists{% else %}new{% endif %}" data-provides="fileinput">
<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
<img data-src="holder.js/100%x100%" alt="100%x100%" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOTAiIGhlaWdodD0iMTQwIj48cmVjdCB3aWR0aD0iMTkwIiBoZWlnaHQ9IjE0MCIgZmlsbD0iI2VlZSIvPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk1IiB5PSI3MCIgc3R5bGU9ImZpbGw6I2FhYTtmb250LXdlaWdodDpib2xkO2ZvbnQtc2l6ZToxMnB4O2ZvbnQtZmFtaWx5OkFyaWFsLEhlbHZldGljYSxzYW5zLXNlcmlmO2RvbWluYW50LWJhc2VsaW5lOmNlbnRyYWwiPjE5MHgxNDA8L3RleHQ+PC9zdmc+" style="height: 100%; width: 100%; display: block;">
</div>
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 10px;">
{% if field.value and field.value.url %}
<img src="{{ field.value.url }}">
{% endif %}
</div>
{# imgfileinput, imgselect, imremove used for removing image #}
<div id="imgfileinput">
<span id="imgselect" class="btn btn-default btn-file">
<span class="fileinput-new">Select image</span>
<span class="fileinput-exists">Change</span>
<input id="imgfile" type="file" name="{{ field.name }}">
</span> 
<a id="imgremove" href="#" class="btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
</div>
</div>
{# removed {% crispy_field field %} #}
{% include 'bootstrap3/layout/help_text_and_errors.html' %}
</div>
{% endif %}
{% endif %}
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
{% if field|is_checkbox %}
{% if label_class %}
</div>
{% endif %}
</div>
{% endif %}
{% endif %}
其次,在为表单定义布局时引用模板:
from crispy_forms.layout import Layout, Fieldset, Div, Submit, Reset, HTML, Field, Hidden
class UserForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Field('avatar', template='file_field.html'),
'username',
'first_name',
'last_name',
)
第三,默认情况下,无法使用Jasny和Django轻松清除图像。您可以找到Jasny行为here的摘要。基本上Jasny提交None或空字符串,具体取决于图像是否未更新或删除。 Django将这两个解释为图像未更新,而不是图像被删除。
Django使用ClearableFileInput小部件添加一个复选框,如果要删除文件,应该选中该复选框。为了模仿这个功能,我添加了一些jQuery来在选择删除按钮时添加此输入,并在选择更改或插入按钮时删除输入:
<script>
// Allow image to be deleted
$('#imgremove').on('click', function() {
field_name = $('#imgfile')[0].getAttribute('name');
$('#imgfileinput').append('<input id="imgclear" type="hidden" name="'+field_name+'-clear" value="on">');
})
$('#imgselect').on('click', function() {
$('#imgclear').remove();
})
</script>
您会注意到我上面的Jasny HTML已经过轻微修改,以便为感兴趣的标记添加ID,以便更轻松地进行选择。
看似很多工作,但一旦完成,它就像普通的脆形一样容易使用。
答案 1 :(得分:0)
我最终没有使用django-crispy-forms,我正在使用Django模板语言编写自己的custom form template。 Jasny Bootstrap file upload以这种方式运作良好。