获取Django POST请求的API

时间:2017-06-23 01:25:17

标签: django reactjs redux fetch fetch-api

我试图从React / Redux / Django webapp中删除jQuery,并用Fetch API替换$.ajax方法。我或多或少得到了所有我的GET请求正常工作,我似乎能够点击我的POST请求,但我似乎无法格式化我的请求,以便实际将我的POST数据输入Django { {1}}对象。每次我点击/ sign_in视图时,request.POST对象都是空的。我的整个应用程序的后端是使用Django表单构建的(没有Django模板,只有React控制的组件),我真的不想重写我的所有视图来使用request.POSTrequest.body

以下是我认为相关的所有代码,如果还有其他更多信息,请与我们联系:

这是我用来构建完整POST数据并附加CSRF令牌的curry函数:

request.data

这是我在React应用中使用的API方法:

const setUpCsrfToken = () => {
  const csrftoken = Cookies.get('csrftoken')

  return function post (url, options) {
  const defaults = {
    'method': 'POST',
    'credentials': 'include',
    'headers': {
      'X-CSRFToken': csrftoken,
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  }

  const merged = merge(options, defaults)
  return fetch(url, merged)
  }
}

export const post = setUpCsrfToken()

最初打包在React应用程序中的数据就像具有字符串值的对象一样简单:

export const signIn = data => {
  return post('/api/account/sign_in/', data)
}

我已经看过这些问题并发现它们名义上有帮助,但是我无法想出为自己综合一个答案,考虑到我认为是Django的一些错综复杂的问题:

question

question

question

question

谢谢!

1 个答案:

答案 0 :(得分:3)

您必须设置相应的X-Requested-With: XMLHttpRequest 标头。 jQuery执行此操作under the hood

const setUpCsrfToken = () => {
  const csrftoken = Cookies.get('csrftoken')

  return function post (url, options) {
    const defaults = {
      'method': 'POST',
      'credentials': 'include',
      'headers': new Headers({
        'X-CSRFToken': csrftoken,
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'X-Requested-With': 'XMLHttpRequest'
      })
    }

    const merged = merge(options, defaults)
    return fetch(url, merged)
  }
}

因此,在您的示例中,您需要以下内容:

import React from 'react';
import {
  Media,
  Dropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem,
} from 'reactstrap';
import PropTypes from 'prop-types';

const UserPreview = ({user}) => (

this.toggle = this.toggle.bind(this);
this.state = {
  DropdownOpen: false
  };
}

toggle() {
  this.setState({
    DropdownOpen: !this.state.DropdownOpen
  });
}

  <tr className="user">
    <td>
      <Media>
        <img
          alt={`${user.name} avatar`}
          className="avatar d-flex mr-3"
          src={user.url} />
        <Media body>{user.name}</Media>
      </Media>
    </td>
    <td>
      <Dropdown isOpen={this.state.DropdownOpen} toggle={this.toggle}>
        <DropdownToggle caret>
          Admin
        </DropdownToggle>
        <DropdownMenu>
          <DropdownItem>Read</DropdownItem>
          <DropdownItem>Write</DropdownItem>
        </DropdownMenu>
      </Dropdown>
    </td>
  </tr>
);

UserPreview.propTypes = {
  user: PropTypes.shape({
    name: PropTypes.string,
    // TODO: add an url proptype.
    url: PropTypes.string,
  }).isRequired,
};

export default UserPreview;