Reputation: 29
Attempting to use bootstrap4 with django for forms. Installed crispy forms and and everything seems to work as I expected except for the browse file button selection functionality. When a file selection window comes up and file is choosen from explorer it does not show as selected it the field. However when the form is submitted everything works as expected and the file is uploaded. Am I missing a helper class setting? I could not find one that looked like it addresses this.
Any help is appreciated, details below.
Environment:
Models.py
from django.db import models
# Create your models here.
class Csvfile_model(models.Model):
name = models.CharField(max_length=50)
csv_file_name = models.FileField(upload_to='csv_file/')
forms.py
from django import forms
from crispy_forms.helper import FormHelper
from .models import *
class CsvForm(forms.ModelForm):
helper = FormHelper()
class Meta:
model = Csvfile_model
fields = ['name', 'csv_file_name']
views.py
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .forms import *
# Create your views here.
def csv_upload(request):
if request.method == "POST":
form = CsvForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('sucess')
else:
form = CsvForm()
return render(request, 'csv_upload.html', {'form' : form})
def sucess(request):
return HttpResponse('sucessfully uploaded')
csv_upload.html
<!-- templates/home.html -->
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% crispy form form.helper %}
{% block title %}Home{% endblock %}
{%block subject%} <h1>Pandas Profiler Home</h1> {% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-12">
<h2> CSV Upload</h2>
<div class="row">
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
<div class="input-group">
{% crispy form %}
<span class="input-group-btn">
<button class="btn btn-default" type="submit"> Upload </button>
</span>
</div>
</form>
</div>
</div class="col-12">
</div class="row">
</div class="container">
{% endblock %}
base.html
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}Django Auth Tutorial{% endblock %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<style>
.fakeimg {
height: 200px;
background: #aaa;
}
</style>
</head>
<body>
<div class="jumbotron text-center" style="margin-bottom:0">
<subject>{% block subject %} <h1> Django Auth Tutorial </h1>{% endblock %}</subject>
<p>Quick and dirt responsive website to do eploratory data analysis (EDA) </p>
</div>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<a class="navbar-brand" href="#">Menu</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact Us</a>
</li>
</ul>
</div>
</nav>
<div class="container" style="margin-top:30px">
<div class="row">
<div class="col-sm-12">
{% block content %}
{% endblock %}
</div>
</div>
</div>
<div class="jumbotron text-center" style="margin-bottom:0">
<p>Pandas Profiler is an experiment using django, bootstrap to upload a file to a website, process that file and display the results back to the user withouth having to know python or pandas. It's also great for lazy data scientests</p>
</div>
</body>
</html>
settings.py
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'y(9-(8p)v+s8!i#f0&4_@#zd#lw3qq9^fj@$e7vt(#&%7kih_o'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.staticfiles', 'csvfile.apps.CsvfileConfig',
'crispy_forms',
]
...
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
Upvotes: 1
Views: 3277
Reputation: 26
This is bootstrap4 functionality and not crispy. To correct this you need to add some javascript to interact with the form button and the filename field. Insert this at the bottom of your html file and it should work.
<script type="application/javascript">
$('input[type="file"]').change(function(e){
var fileName = e.target.files[0].name;
$('.custom-file-label').html(fileName);
});
</script>
Upvotes: 1