material-ui 和 Django 上的 axios POST 请求的困难

Difficulties with axios POST request on material-ui & Django

我正在做一个项目,react.js & material-table 作为前端,django 作为后端。目前,我正在尝试对 material-table 执行 CRUD 操作。 axios PUT 和 DELETE 请求非常顺利。但是,我对 axios post 请求有一些问题。我的代码如下:

export default function DataWorker() {
  
  const [entries, setEntries] = useState({
    data: [
      {
        id: "",
        position: "",
        defect: "",
        tool: ""
      }
    ]
  });

  const [state] = React.useState({
    columns: [
      { title: "Position", 
        field: "position",
        width: 150,
        // lookup: { 1: "Position 1", 2: "Position 2", 3: "Position 3"}, 
        cellStyle: { textAlign: "center" } 
      },

      { title: "Defect Type", 
        field: "defect",
        width: 150,
        // lookup: { 1: "None", 2: "Spalling", 3: "Scratch", 4: "Crack"},
        cellStyle: { textAlign: "center" }
      },

      { title: "Tool Decision", 
        field: "tool", 
        width: 150,
        // lookup: { 1: "None", 2: "Tool 1", 3: "Tool 2", 4: "Tool 3"},
        cellStyle: { textAlign: "center" } 
      }
    ]
  });

  const url = "http://127.0.0.1:8000/api/manual_ver_data/"

  useEffect(() => {
    axios.get(url)
    .then(response => {
      let data = [];
      response.data.forEach(el => {
        data.push({
          id: el.id,
          position: el.position,
          defect: el.defect,
          tool: el.tool
        });
      });
      setEntries({ data: data });
    })
    .catch(function(error) {
      console.log(error);
    });
  }, []);

  return (
    <MaterialTable
      components={{
        Toolbar: props => (
          <div style={{ color: "#005005" }}>
            <MTableToolbar {...props} /> 
          </div>
        )
      }}

      title="Manual Verification Label"
      columns={state.columns}
      data={entries.data}
      options={{
        sorting: false,
        draggable: false,
        emptyRowsWhenPaging: false,
        pageSize: 3,
        actionsColumnIndex: -1,
        pageSizeOptions: [3],
        minBodyHeight: 225,
        maxBodyHeight: 225,
        searchFieldStyle: {
          width: 200,
        },
        headerStyle: {
          color: "#212121",
          backgroundColor: "#4caf50",
          textAlign: "center",
        },
        tableLayout: "fixed"
      }}

      localization={{
        header: {
          actions: "Edit"
        }
      }}
      
      editable={{
        onRowAdd: (newData) =>
        new Promise(resolve => {
          setTimeout(() => {
            resolve();
            const data = [...entries.data]
            axios.post(url, newData)
            .then(res => console.log(res));
          setEntries({ ...entries, data })
          }, 600)
        }),

        onRowUpdate: (newData, oldData) =>
        new Promise(resolve => {
          setTimeout(() => {
            resolve();
            const data = [...entries.data];
            data[data.indexOf(oldData)] = newData;
            axios.put(url + entries.data[data.indexOf(newData)].id + "/", newData)
            .then(res => console.log(res.data));
          setEntries({ ...entries, data });
          }, 600)
        }),

        onRowDelete: oldData =>
        new Promise(resolve => {
          setTimeout(() => {
            resolve();
            const data = [...entries.data];
            let deleteDataId = entries.data[entries.data.indexOf(oldData)].id
            data.splice(data.indexOf(oldData), 1);
            axios.delete(url + deleteDataId + "/")
            .then(res => console.log(res.data));
          setEntries({ ...entries, data });
          }, 600);
        })
      }}
    />
  )
};

我使用“id”列作为索引来执行 PUT 和 DELETE 请求,一切正常,因为“id”是在我使用 django admin 创建数据时自动生成的。

但是我的方法有缺陷,因为在 django admin 中创建新数据之前,我无法使用 axios POST 请求访问新数据的“id”。结果,我的代码仍然可以执行 POST 请求,但它不会立即呈现新创建的数据,我必须刷新它才能显示它。谁能告诉我如何改进我的 axios POST 请求,并在不刷新的情况下呈现新数据?

我已经通过在 view.py

中包含以下代码解决了这个问题
@api_view(['GET', 'POST'])
def TableViewList(request):
    
    if request.method == 'POST':
        serializer = TabelSerializer(data=request.data)
        
        
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

另外,在onRowAdd中包含axios回调函数:

            const data = [...entries.data];
            const populateData = (axiosResponse) => {data.push(axiosResponse)}
            axiosCallBack(populateData)

            function axiosCallBack (populateData) {
              axios.post(url, newData)
              .then(function(res){
                populateData(res.data)
              })  
            }

唯一的方法是让 django 在 post 响应中包含新创建的对象。然后您可以从 axios 回调访问它并将它添加到您的数据数组。