Django uploaded file doesn't process - python

I'm building a Django web-app where the user needs to upload a file. This file should go through a machine-learning alogritme after that the results will be presented on a different page.
right now it works if I have text fields present for every feature but when I want to upload a csv file(the csv file is called test.csv) put it in a pandas dataframe the resultpage doesn't show and it looks like the csv file isn't processed.
what it should do is if file is uploaded keep the uploaded file in memory process it and return the output on the results page.
HTML
{% extends "base.html" %}
{% block content %}
<div class="content">
<div class="row">
<div class="col-lg-4">
<div class="card card-tasks">
<h1> </h1>
<form action="{% url 'result' %}">
{% csrf_token %}
<p>temp_normal:</p>
<input class="form-control" type="text" name="temp_normal">
<br>
<p>hour:</p>
<input class="form-control" type="text" name="hour">
<br>
<p>hour_x:</p>
<input class="form-control" type="text" name="hour_x">
<br>
<p>hour_y:</p>
<input class="form-control" type="text" name="hour_y">
<br>
<input class="form-control" type="submit" value='Submit'>
</form>
</div>
</div>
<div class="col-lg-4">
<div class="card card-tasks">
<form action="{% url "result" %}" method="POST" enctype="multipart/form-data" class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-md-3 col-sm-3 col-xs-12 control-label">File: </label>
<div class="col-md-8">
<input type="file" name="csv_file" id="csv_file" required="True" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-3 col-sm-3 col-xs-12 col-md-offset-3" style="margin-bottom:10px;">
<button class="btn btn-primary"> <span class="glyphicon glyphicon-upload" style="margin-right:5px;"></span>Upload </button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock content %}
views.py
def handle_uploaded_file(f):
with open('test.csv', 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
# custom method for generating predictions
def getPredictions(data):
import pickle
model = pickle.load(open("test_model.sav", "rb"))
prediction = model.predict(data)
return prediction
#login_required
def result(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
data = form
data = pd.read_csv(data,header=0)
result = getPredictions(data)
return render(request, 'result.html', {'result': result})
else:
form = UploadFileForm()
return render(request, 'index.html', {'form': form})

try:
<form action="{% url "result" %}" method="POST" enctype="multipart/form-data" class="form-horizontal">
{% csrf_token %}
<div class="form-group">
<label for="name" class="col-md-3 col-sm-3 col-xs-12 control-label">File: </label>
<div class="col-md-8">
{{ form }}
</div>
</div>
<div class="form-group">
<div class="col-md-3 col-sm-3 col-xs-12 col-md-offset-3" style="margin-bottom:10px;">
<button class="btn btn-primary" type="submit"> <span class="glyphicon glyphicon-upload" style="margin-right:5px;"></span>Upload </button>
</div>
</div>
</form>
as we discussed for the view:
#login_required
def result(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
file = request.FILES['file']
handle_uploaded_file(file)
data = pd.read_csv(file,header=0)
result = getPredictions(data)
return render(request, 'result.html', {'result': result})
else:
form = UploadFileForm()
return render(request, 'index.html', {'form': form})

Related

Using django form within custom html template

I have a html file that I wanna use this template to render my form and save it to my database
How to do this?
HTML code:
<div class="container-contact100">
<div class="wrap-contact100">
<form class="contact100-form validate-form" enctype="multipart/form-data" method="POST">
{% csrf_token %}
<span class="contact100-form-title">
Add Item!
</span>
<div class="wrap-input100 validate-input" data-validate="Name is required">
<span class="label-input100">Title</span>
<input class="input100" type="text" name="name" placeholder="Enter food name">
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input">
<span class="label-input100">Price</span>
<input class="input100" type="number" name="price" placeholder="Enter food price">
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input" data-validate = "Message is required">
<span class="label-input100">Description</span>
<textarea class="input100" name="message" placeholder="Your description here..."></textarea>
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Image is required">
<input type="file" class="custom-file-input" id="customFile" name="filename">
<label class="custom-file-label" for="customFile">Choose file</label>
<span class="focus-input100"></span>
</div>
<div class="container-contact100-form-btn">
<div class="wrap-contact100-form-btn">
<div class="contact100-form-bgbtn"></div>
<button class="contact100-form-btn" type="submit">
<span>
Add
<i class="fa fa-long-arrow-right m-l-7" aria-hidden="true"></i>
</span>
</button>
</div>
</div>
</form>
</div>
</div>
<div id="dropDownSelect1"></div>
and here is my forms.py :
from django import forms
from .models import Product
class AddItemForm(forms.ModelForm):
class Meta:
model = Product
fields = '__all__'
even you can access my project from this link via github:
https://github.com/imanashoorii/FoodMenu.git
You have to set the name attributes in your form in your html according to field names of your Porudct model like this (using data from your GitHub link):
add_product.html
<form method="post" enctype="multipart/form-data"> # here define enctype attribute so your form can accept images
{% csrf_token %}
<input type="text" name="title">
<input type="text" name="description">
<input type="number" name="price">
<input type="file" name="image">
<button type="submit">Submit</button>
</form>
Or instead of manually defining each field you can just pass a {{ form.as_p }} to your html to render each field inside a <p> tag like this:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
Then here is how you would save it in a view:
views.py
def add_product(request):
if request.method == 'POST':
form = AddItemForm(request.POST, request.FILES) # request.FILES is so your form can save images
if form.is_valid()
form.save()
return redirect('home') # redirect to a valid page
else:
form = AddItemForm()
return render(request, 'add_product.html', {'form': form})
I have fixed my problem by changing views.py to this and fix it :
if form.is_valid():
title = request.POST.get('title')
description = request.POST.get('description')
price = request.POST.get('price')
image = request.POST.get('image')
form.save()
return redirect("food:home")

price range filter in django

I want to filter products by price range from min price to max price. I tried but I am getting all products. Please suggest to me how can I do that?
def search(request):
price_from = request.GET.get('price_from', None)
price_to = request.GET.get('price_to', None)
products = Product.objects.filter(price__range=(price_from,price_to))
context = {
'price_from': price_from,
'price_to': price_to,
'products': products,
}
return render(request, 'search.html', context)
my template code
<div class="range-slider">
<form method="get" action="{% url 'search' %}" class="d-flex align-items-center justify-content-between">
<div class="price-input">
<label for="amount">PriceFrom </label>
<input type="number" name="price_from" value="{{price_from}}">
</div>
<div class="price-input">
<label for="amount">PriceTo</label>
<input type="number" name="price_to" value="{{price_to}}">
</div>
<button class="filter-btn">filter</button>
</form>
</div>
<div class="range-slider">
<form method="get" action="{% url 'search' %}" class="d-flex align-items-center justify-content-between">
<div class="price-input">
<label for="amount">PriceFrom </label>
#Just Apply For loop for evry price form
{% for i in price form %}
<input type="number" name="price_from" value="{{price_from}}">
{% end for %}
</div>
<div class="price-input">
<label for="amount">PriceTo</label>
{% for i in price to %}
<input type="number" name="price_to" value="{{price_to}}">
{% end for %}
</div>
<button class="filter-btn">filter</button>
</form>
</div>
</div>
Tell me if this worked for you

Submit django form in a modal popup

I render my form inside a modal:
view:
#login_required
def task_edit(request, pk):
member = get_object_or_404(Tasks, pk=pk)
if request.method == "POST":
form = TasksForm(request.POST or None, instance=member)
if form.is_valid():
reg = form.save(commit=False)
reg.save()
return HttpResponse(
'<script type="text/javascript">window.close();</script>')
else:
form = TasksForm(instance=member)
return render(request, 'TaskProj/task_edit.html', {'form': form})
my html rendered in a modal popup:
{%load staticfiles %}
<div class="row">
<div class="col-lg-12">
<div class="panel">
<div class="content-box">
<h3 class="content-box-header bg-primary">
<span class="icon-separator">
<i class="glyph-icon icon-tasks"></i>
</span>
<span class="header-wrapper">
Eidt Tasks </span>
</span>
</h3>
<div class="panel">
<div class="panel-body">
<form method="POST" id="form" class="form-horizontal bordered-row" autocomplete="off">
{% csrf_token %}
<div class="example-box-wrapper">
<div class="form-group">
{{ form.as_p }}
</div>
</div>
<button type="submit" class="btn btn-primary btn-lg btn-block">Salva</button>
</div>
</div>
</form>
<script type="text/javascript">
$(document).on('click','.submit',function(){
$( "#form" ).submit();
});
</script>
{% endblock %}
This form is rendered inside a modal popup.
I try to save, it close modal but not save form.
I think there is a problem with submit button...
Any idea?
TY
you need to declare an action attribute with the url to your function that handles the specific form in views.py. So that the form knows where to go, and be handled:
<form method="POST" id="form" class="form-horizontal bordered-row" action="{% 'task_edit' your-object.pk %}" autocomplete="off">
{% csrf_token %}
<div class="example-box-wrapper">
<div class="form-group">
{{ form.as_p }}
</div>
</div>
<button type="submit" class="btn btn-primary btn-lg btn-block">Salva</button>
</div>
</div>
</form>

form.is_valid() not working when using django forms for updating information to the databse

So I wanna be able to update information of a router in the database using a form, I wanna have a form pre-populated with that specific router details. The problem is that form.is_valid() is not working
I tried using {{ form.errors }} {{ form.non_field_errors }} and print(form.errors) but none of them worked
views.py (incomplete)
def info_router(request, pk):
rout = Routers.objects.get(sn=pk)
if request.method == 'GET': # Insert the info in forms
form = UpdateRouter()
rout = Routers.objects.get(sn=pk)
args = {'router': rout}
return render(request, "router_info.html", args)
if request.POST.get('delete'):
# Delete router
rout.delete()
messages.warning(request, 'Router was deleted from the database!')
return redirect("db_router")
if request.method == 'POST':
#Updating the form
form = UpdateRouter(instance=Routers.objects.get(sn=pk))
print(form)
print(form.errors)
if form.is_valid():
data = UpdateRouter.cleaned_data
mac = data['mac']
print(mac)
return HttpResponseRedirect('db_router')
else:
print("Invalid form")
return render(request, "db_router.html", {'form': form})
forms.py
class UpdateRouter(ModelForm):
class Meta:
model = Routers
fields = ['model', 'ip_addr', 'name', 'sn', 'mac']
template
<form class="form-horizontal" action="" method="post">
{% csrf_token %}
<div class="form-group"> <!-- Form with the router details -->
<label class="control-label col-sm-2" for="text">Serial number:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="text" name="sn" value="{{ router.sn }}" readonly>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="text">Model:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="text" value="{{ router.model }}" name="model" readonly>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="text">Ip address:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="text" value="{{ router.ip_addr }}" name="ip_addr">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="text">Name:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="text" value="{{ router.name }}" name="name">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="text">Mac address:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="text" value="{{ router.mac }}" name="mac">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="text">Extra info:</label>
<div class="col-sm-10">
<textarea class="form-control" name="extra_info" id="FormControlTextarea" rows="3">Example of some info</textarea>
</div>
</div>
<div class="form-group" style="margin-top: 20px;">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Update</button> <!-- Responsible for updating the router -->
Cancel
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#myModal" style="float: right"> <!-- Responsible for the delete modal to open -->
Delete
</button>
</div>
</div>
</form>
You never passed request.POST and rquest.FILES. If you want to update the fields and files, you need to form.save() your form:
if request.method == 'POST':
#Updating the form
form = UpdateRouter(request.POST, request.FILES, instance=Routers.objects.get(sn=pk))
print(form)
print(form.errors)
if form.is_valid():
data = form.cleaned_data
mac = data['mac']
form.save()
print(mac)
return redirect('db_router')
else:
print("Invalid form")
If you do not pass request.POST and/or request.FILES, then Django does not consider the form filled in, and it is never considered valid.
If you pass both files and data, then you need to add the enctype="multipart/form-data" to your <form> tag:
<form enctype="multipart/form-data" class="form-horizontal" action="" method="post">
<!-- -->
</form>
you need to create a bound_form
form = UpdateRouter(request.POST)
form = UpdateRouter(request.POST) binds the data to the form class. then validate
the inputs using is_valid().

Form is not valid in django because it is empty

I'm trying to setup the register form for a website but it doesn't work because the form is empty so the print (request.POST) contains all the information but the form is not valid.
This is the view:
def register(request):
print("Request submitted", request, request.method)
if request.method == 'POST':
print (request.POST)
form = RegistrationForm(request.POST, prefix="user")
print (form.is_valid())
print (form.errors)
if form.is_valid():
...
else:
print("not valid")
else:
form = RegistrationForm(prefix="user")
return render(request, 'registration_form.html', {'form': form})
And this is the html:
<body>
<div class="login">
<h1>Alta de Usuario</h1>
{% if messages %}
{% for message in messages %}
<div class="alert">{{ message }}</div>
{% endfor %}
{% endif %}
<form class="login-form" method="post">
{% csrf_token %}
<div>
<label for="username">Nombre de usuario:</label>
<input type="text" name="username" value="" placeholder="Elige un nombre de usuario">
<p class="form-valid"><i class="fas fa-check"></i></p>
</div>
<div>
<label for="email">eMail:</label>
<input type="text" name="email" value="" placeholder="Introduce tu email">
<p class="form-valid"><i class="fas fa-check"></i></p>
</div>
<div>
<label for="pass">Contraseña:</label>
<input type="password" name="pass" value="" placeholder="Introduce una contraseña">
<p class="form-valid"><i class="fas fa-times"></i></p>
</div>
<div>
<label for="pass">Repite contraseña:</label>
<input type="password" name="pass" value="" placeholder="Repite la contraseña introducida">
<p class="form-valid"><i class="fas fa-times"></i></p>
</div>
<div class="disclaimer">
<div class="check-terms">
<input class="terms" name="terms" type="checkbox">
<label for="terms">
Acepto los términos y condiciones
</label>
</div>
</div>
<button class="access" type="submit">Registrarme</button>
</form>
</div>
</body>
</html>
{#{{ form.as_p }}#}
Many thanks for your help!
Try instantiating the form like this instead:
form = RegistrationForm(data=request.POST, prefix="user")
Solved using:
form = RegistrationForm(request.POST or None)

Categories