【问题标题】:Getting a json from a string in Django TemplateView to make a request to django-rest API从 Django TemplateView 中的字符串获取 json 以向 django-rest API 发出请求
【发布时间】:2020-01-04 10:25:27
【问题描述】:

我从this question 开始,但无法解决这个问题:我有一个 Django 模板视图,其中包含我想通过 HTML 表单传递给 django-rest API 的信息。

已接受 API POST 请求:带有字符串值的 JSON 文件

[
{"filename" : "01-01-01-01-01-01-01.wav"}
]

我构建了什么:

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']

我遇到的错误:

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

完整的代码库(如果需要)https://github.com/marcogdepinto/Django-Emotion-Classification-Ravdess-API

【问题讨论】:

    标签: python django


    【解决方案1】:

    您发送的不是您声称的数据。您提交的是标准表单,因此 request.data 是一个简单的字典。您不需要遍历它;直接取值即可。 (另外,querydicts 是不可变的,所以不要使用 pop。)

        with graph.as_default():
            filename = request.data["filename"]
    

    【讨论】:

    • 以这种方式更改代码我在 /App/predict/ 'filename' 处收到“MultiValueDictKeyError” 请求方法:POST 请求 URL:127.0.0.1:8000/App/predict Django 版本:2.2.4 异常类型:MultiValueDictKeyError 异常值: '文件名'
    • 好的,解决了添加 .get() 排除错误 + 更改渲染请求的模板(调用错误) return render(request, "select_file_prediction.html", context={'文件名': filename_json})
    猜你喜欢
    • 2021-10-05
    • 2020-10-05
    • 2018-06-02
    • 2017-11-28
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    相关资源
    最近更新 更多