PyQt5 and Django : How to Upload Image using HTTP Request ( Multipart-form )?

后端 未结 1 715
别那么骄傲
别那么骄傲 2020-12-11 12:11

currently I am working in a project to create a seller application where the seller can upload the menu picture and some additional information such as the price and the nam

相关标签:
1条回答
  • 2020-12-11 12:43

    In the following example I show you create the query:

    import json
    from PyQt5 import QtCore, QtNetwork, QtWidgets
    
    class MenuWidget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(MenuWidget, self).__init__(parent)
            self._manager = QtNetwork.QNetworkAccessManager()
            self._manager.finished.connect(self.handleResults)
    
            self.init_ui()
    
        def init_ui(self):
            self.filepath_lineedit = QtWidgets.QLineEdit()
            select_button = QtWidgets.QPushButton(
                text="Select File",
                clicked=self.select_file
            )
            self.name_lineedit = QtWidgets.QLineEdit()
            self.price_spinbox = QtWidgets.QSpinBox()
            self.category_spinbox = QtWidgets.QSpinBox()
            self.availability_checkbox = QtWidgets.QCheckBox()
            self.seller_id_spinbox = QtWidgets.QSpinBox()
            self.log_textedit = QtWidgets.QTextBrowser()
            upload_button = QtWidgets.QPushButton(
                text="Upload",
                clicked=self.upload
            )
    
            hlay = QtWidgets.QHBoxLayout()
            hlay.addWidget(self.filepath_lineedit)
            hlay.addWidget(select_button)
            lay = QtWidgets.QFormLayout(self)
            lay.addRow("Image:", hlay)
            lay.addRow("Name:", self.name_lineedit)
            lay.addRow("Price:", self.price_spinbox)
            lay.addRow("Category:", self.category_spinbox)
            lay.addRow("Availability:", self.availability_checkbox)
            lay.addRow("SellerID:", self.seller_id_spinbox)
            lay.addRow(self.log_textedit)
            lay.addRow(upload_button)
    
        @QtCore.pyqtSlot()
        def select_file(self):
            filename, _ = QtWidgets.QFileDialog.getOpenFileName(
                self, 
                "Open Image", 
                QtCore.QDir.currentPath(), 
                "Image Files (*.png *.jpg *.bmp)"
            )
            if filename:
                self.filepath_lineedit.setText(filename)
    
        @QtCore.pyqtSlot()
        def upload(self):   
            data = {
                "name": self.name_lineedit.text(),
                "price": self.price_spinbox.value(),
                "category": self.category_spinbox.value(),
                "availability": self.availability_checkbox.isChecked(),
                "sellerID": self.seller_id_spinbox.value()
            }
            path = self.filepath_lineedit.text()
            files = {"image": path}
            multi_part = self.construct_multipart(data, files)
            if multi_part:
                url = QtCore.QUrl("http://127.0.0.1:8000/api/menu/")
                request = QtNetwork.QNetworkRequest(url)
                reply = self._manager.post(request, multi_part)
                multi_part.setParent(reply)
    
        @QtCore.pyqtSlot(QtNetwork.QNetworkReply)
        def handleResults(self, reply):
            parsed = json.loads(reply.readAll().data())
            text = json.dumps(parsed, indent=4, sort_keys=True)
            self.log_textedit.setText(text)
            if reply.error() == QtNetwork.QNetworkReply.NoError:
                QtWidgets.QMessageBox.information(self, "Menu", "Upload Success!")
            else:
                errorMessage = "Error occured: {}".format(reply.errorString())
                QMessageBox.critical(self, "Error Done", errorMessage)
            reply.deleteLater()
    
        def construct_multipart(self, data, files):
            multi_part = QtNetwork.QHttpMultiPart(QtNetwork.QHttpMultiPart.FormDataType)
            for key, value in data.items():
                post_part = QtNetwork.QHttpPart()
                post_part.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader, 
                    "form-data; name=\"{}\"".format(key))
                post_part.setBody(str(value).encode())
                multi_part.append(post_part)
            for field, filepath in  files.items():
                file = QtCore.QFile(filepath)
                if not file.open(QtCore.QIODevice.ReadOnly):
                    break
                post_part = QtNetwork.QHttpPart()
                post_part.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
                    "form-data; name=\"{}\"; filename=\"{}\"".format(field, file.fileName()))
                post_part.setBodyDevice(file)
                file.setParent(multi_part)
                multi_part.append(post_part)
            return  multi_part
    
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = MenuWidget()
        w.show()
        sys.exit(app.exec_())
    

    0 讨论(0)
提交回复
热议问题