I started from this question but was not able to solve this: I have a Django templateview with an information I want to pass to a django-rest API via HTML form.
API POST request accepted: a JSON file with a string value
[
{"filename" : "01-01-01-01-01-01-01.wav"}
]
What I build:
Views.py
class SelectPredFileView(TemplateView):
"""
This view is used to select a file from the list of files in the server.
After the selection, it will send the file to the server.
The server will return the predictions.
"""
template_name = "select_file_predictions.html"
success_url = '/predict_success/'
def get_context_data(self, **kwargs):
"""
This function is used to render the list of file in the MEDIA_ROOT in the html template.
"""
context = super().get_context_data(**kwargs)
media_path = settings.MEDIA_ROOT
myfiles = [f for f in listdir(media_path) if isfile(join(media_path, f))]
context['filename'] = myfiles
return context
def send_filename(self, request):
filename_json = json.dumps(self.context)
return render(request, "template.html", context={'filename': filename_json})
class Predict(views.APIView):
def __init__(self, **kwargs):
super().__init__(**kwargs)
modelname = 'Emotion_Voice_Detection_Model.h5'
global graph
graph = tf.get_default_graph()
self.loaded_model = keras.models.load_model(os.path.join(settings.MODEL_ROOT, modelname))
self.predictions = []
def post(self, request):
"""
This method is used to making predictions on audio files previously loaded with FileView.post
"""
with graph.as_default():
for entry in request.data:
filename = entry.pop("filename")
filepath = str(os.path.join(settings.MEDIA_ROOT, filename))
data, sampling_rate = librosa.load(filepath)
try:
mfccs = np.mean(librosa.feature.mfcc(y=data, sr=sampling_rate, n_mfcc=40).T, axis=0)
x = np.expand_dims(mfccs, axis=2)
x = np.expand_dims(x, axis=0)
numpred = self.loaded_model.predict_classes(x)
self.predictions.append([self.classtoemotion(numpred)])
except Exception as err:
return Response(str(err), status=status.HTTP_400_BAD_REQUEST)
return Response(self.predictions, status=status.HTTP_200_OK)
select_file_predictions.html:
{% extends "index.html" %}
{% block content %}
<form action="/App/predict/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
{% for myfile in filename %}
<input type="checkbox" name="file_name" value="{{ myfile }}">{{ myfile }}<br>
{% endfor %}
<button type="submit" class="btn btn-primary" value="{{ filename_json }}">Predict</button>
</form>
{% endblock %}
forms.py
class FileForm(ModelForm):
"""
Creating a form that maps to the model: https://docs.djangoproject.com/en/2.2/topics/forms/modelforms/
This form is used for the file upload.
"""
class Meta:
model = FileModel
fields = ['file']
Error I am getting:
AttributeError at /App/predict/
'str' object has no attribute 'pop'
Request Method: POST
Request URL: http://127.0.0.1:8000/App/predict/
Django Version: 2.2.4
Exception Type: AttributeError
Exception Value:
'str' object has no attribute 'pop'
Exception Location: /Users/marcogdepinto/PycharmProjects/DjangoRestDeepLearning/App/views.py in post, line 118
Python Executable: /Users/marcogdepinto/anaconda3/bin/python
Python Version: 3.6.8
Python Path:
['/Users/marcogdepinto/PycharmProjects/DjangoRestDeepLearning',
'/Users/marcogdepinto/anaconda3/lib/python36.zip',
'/Users/marcogdepinto/anaconda3/lib/python3.6',
'/Users/marcogdepinto/anaconda3/lib/python3.6/lib-dynload',
'/Users/marcogdepinto/anaconda3/lib/python3.6/site-packages',
'/Users/marcogdepinto/anaconda3/lib/python3.6/site-packages/aeosa']
Server time: Sat, 31 Aug 2019 14:51:02 +0000
Full code repository, if needed: https://github.com/marcogdepinto/Django-Emotion-Classification-Ravdess-API