I am working on a django web application. the application holds two forms in the same page. The first form is for uploading an image and the second form is a description for the image. After the user uploads an image and clicks on the upload image button, an image classifier should classify the image and autofill some parts of the second form.
This is my code so far
models.py
class Item(models.Model):
title = models.CharField(max_length=100)
color = models.CharField(max_length=100)
img = models.ImageField(upload_to='item/img/', null=False, blank=False)
def __str__(self):
return self.title
def delete(self, *args, **kwargs):
self.img.delete()
super().delete(*args, **kwargs)
forms.py
from .models import Item
class ItemImage(forms.ModelForm):
class Meta:
model = Item
fields = ('img',)
class ItemForm(forms.ModelForm):
class Meta:
model = Item
fields = ('title', 'color')
views.py
from .forms import ItemForm, ItemImage
from .models import Item
def upload_item(request):
if request.method == 'POST':
form_img = ItemImage(request.POST, request.FILES)
if form_img.is_valid():
form_img.save()
form_des = ItemForm(request.POST, request.FILES)
if form_des.is_valid():
form_des.save()
return redirect('item_list')
else:
form_img = ItemImage()
form_des = ItemForm()
return render(request, 'upload_item.html', {'form_img': form_img, 'form_des': form_des})
upload_item.html template
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %} upload_item {% endblock title %}
{% block content %}
<div class="row justify-content-center">
<div class="col-6">
<h2>Upload item</h2>
<div class="card mb-5 mt-1">
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form_img|crispy}}
<button type="submit" class='btn btn-primary'>upload img</button>
</form>
</div>
</div>
<div class="card mb-5 mt-1">
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form_des|crispy}}
<button type="submit" class='btn btn-primary'>Save item</button>
</form>
</div>
</div>
</div>
</div>
{% endblock content %}
The problem I am facing is after uploading an image, when I press the upload image button, the page reloads and I have to start all over again. I guess when I press the button the the page is trying to save the form. how do I rectify this?
[NOTE] I have not written the image classification code yet. I will be writing that code under upload_item function in views.py once I solve this problem
[EDITS]
I made some changes to the template file. Now I am able to upload the image and run the classifier on the image.
These are the changes I made
upload_item.html template
{% block content %}
<div class="row justify-content-center">
<div class="col-6">
<h2>Upload item</h2>
<div class="card mb-5 mt-1">
<div class="card-body">
<form action="{{ request.build_absolute_uri }}image_classification/" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input id="search" , type="file" name="file"/>
<input class='btn btn-primary' , type="submit" value="Upload image" />
</form>
</div>
</div>
<div class="card mb-5 mt-1">
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form_des|crispy}}
<button type="submit" class='btn btn-primary'>Save item</button>
</form>
</div>
</div>
</div>
</div>
{% endblock content %}
views.py
def handle_uploaded_file(file, filename):
if not os.path.exists('media/classification/'):
os.mkdir('media/classification/')
with open('media/classification/' + filename, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
def image_classification(request):
form = ItemForm()
cascade_path = "./classifier.h5"
classifier = load_model(cascade_path)
if request.method == 'POST':
handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))
img = np.expand_dims(cv2.resize(cv2.imread(os.path.join('./media/classification/', str(request.FILES['file']))), (170, 100)), axis=0)
pred_class = str(classifier.predict_classes(img)[0])
print(pred_class)
form.fields['title'].widget.attrs['value'] = pred_class
return render(request, 'upload_item.html', {'form': form})
return HttpResponse("Failed")
I added the code @Alexander Strakhov suggested. This is the result I am getting.

What am I doing wrong?
Thanks in advance
<form>tag with a single submit button.