【问题标题】:Sending data from React form to Django Rest Framework without a Model在没有模型的情况下将数据从 React 表单发送到 Django Rest Framework
【发布时间】:2019-09-16 16:31:59
【问题描述】:

我正在尝试将一些数据从我的 React 前端发送到我的 Django REST 后端。

我的 Django 应用程序没有模型。

我有一个反应形式。当用户提交按钮时,表单“提交”三个参数:

  • 公司名称

  • 时间范围

  • numberOfResults

我想将这三个参数发送到我的 Django 后端。为此,我假设 React 正在向 Django 端点发送“POST”请求。 我需要 Django 中的这些参数,以便我可以使用它们对 ML 模型进行一些操作。

我的 React 函数

  handleSubmit(event){
    event.preventDefault()
    fetch("/myapi/getreactinfotwitter",{
      method:"POST",
      headers:{
        'Accept':'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        'data_options': {
          'partnerName': this.state.firmName,
          'timeframes': this.state.timeframes,
          'numberOfResults': this.state.numberOfResults,
        }
      })
    })

现在,我认为 Reast “POST” 必须与 Django “GET” 匹配,以便 Django 获取三个参数。

在 DJANGO 我有:

urls.py

path('getreactinfotwitter/', getreactinfotwitter, name="getreactinfotwitter")

myapi/views.py

@api_view(['GET', 'POST'])
def getreactinfotwitter(request):
    print(request)
    if request.method == 'GET':
        return Response(request.data)

但是

  • 我在views.py 中的request 没有收到任何信息。

  • 在 Web 控制台中,当我单击提交时,我得到 POST http://localhost:8080/myapi/getreactinfotwitter/ 500 (Internal Server Error)

【问题讨论】:

  • 快速谷歌搜索把我带到了这个,也许这会帮助你valentinog.com/blog/drf
  • 我认为Reast“POST”必须与Django“GET”匹配这是错误的。如果您通过 post 方法响应发送数据,那么在 django 视图中也使用 post。我建议您使用 Postman 软件首先检查您的 django-rest api 是否正常工作,然后使用 React
  • 你能详细说明一下为什么我应该在 Django 上使用 POST 来接收来自 React 的数据吗?
  • post, get, put, patch, delete 等是客户端请求服务器做某事的http方法。在这个 API 时代,相同的 API url 用于不同的目的(从服务器获取一些数据,通过后端代码将一些数据保存到数据库,编辑某些东西等)。这就是为什么服务器必须检查请求响应客户端的方法。如果客户端需要来自服务器的某些东西,那么客户端会通过 url 向服务器发送 get 请求。然后服务器检查请求的方法(这里是get)并根据方法做出响应。
  • 你的问题解决了吗?

标签: django reactjs


【解决方案1】:

法蒂玛的回答已经足够出色了。我在这里添加了一些您想在评论中了解的额外内容。

基本上您不需要手动捕获数据并将其保存到数据库中。 Django 给了我们极大的灵活性。如果您的模型、序列化程序和视图如下所示,那么任何 axios 请求都将由 django 自己处理(即 django 捕获数据并将其保存到数据库中),您无需编写代码手动将其保存到数据库中。

型号

class Partner(models.Model):
    partnerName =  models.CharField(max_length=100)
    timeFrames = models.IntegerField()
    numberOfResults = models.IntegerField()

序列化器

class PartnerSerializer(serializer.ModelSerializer):
    class Meta:
        model=Partner
        fields = '__all__'

观看次数

class PartnerView():
    queryset = Partner.object.all()
    serializer_class = PartnerSerializer

如果您仍然想在视图中捕获数据并以您的方式进行修改,那么只需在您的视图类中添加内置函数create()(ModelViewSet 的内置函数)。如果您想修改serializer 中的数据而不是view,请在您的序列化程序中添加内置的create() 函数(ModelSerializer 的内置函数)。

提到的内置功能(以及更多内置功能)可以在这个网站http://www.cdrf.co/找到

viewcreate()函数的确切url是this

serializercreate()函数的准确url是this

见下方自定义代码。

自定义视图

class PartnerView():
    queryset = Partner.object.all()
    serializer_class = PartnerSerializer

    def create(self, request, *args, **kwargs):        
        serializer = self.get_serializer(data=request.data)        
        serializer.is_valid(raise_exception=True)

        # Here all incoming data we kept in serializer variable.
        # Change the data in your way and then pass it inside perform_create()

        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(
           data={
               "status": 201,
               "message": "Product Successfully Created",                
               "data": serializer.data,                
               },
               status=status.HTTP_201_CREATED,
               headers=headers
           )

如果您想修改序列化器中的数据,请使用以下代码。

自定义序列化程序

    class PartnerSerializer(serializer.ModelSerializer):

        class Meta:
            model = Partner
            fields = '__all__'

        def create(self, validated_data):
            my_incoming_data = validated_data

            # If you want to pop any field from the incoming data then you can like below.
            # popped_data = validated_data.pop('timeFrames')

            inserted_data = Partner.objects.create(**validated_data)

            return Response(inserted_data)

【讨论】:

  • 我的应用程序不包含任何模型。我怎样才能实现你的代码?
  • 那么您应该手动将其从views 保存到数据库中。这里是PartnerView。无论如何,你解决了吗? @Prova12
【解决方案2】:

以下是使用 Django REST 后端配置 React 前端的步骤。

Django 设置:

  1. 使用以下命令安装django-cors-headers
pip install django-cors-headers
  1. 将其添加到您的项目settings.py 文件中:
INSTALLED_APPS = (
    ##...
    'corsheaders'
)
  1. 接下来,需要在settings.py中的中间件类中添加corsheaders.middleware.CorsMiddleware
MIDDLEWARE = [
    # corsheaders middleware
    'corsheaders.middleware.CorsMiddleware',
    ...
]
  1. 您应该允许settings.py 中的主机从您要获取数据的位置获取数据。在初始阶段允许*
ALLOWED_HOSTS = [*]

反应设置:

  1. 使用以下命令安装axios
npm i axios
  1. 现在按照下面的示例操作 React 类。
import React from "react";
...
import Axios from "axios";
...


yourFunctionName = () => {

    Axios.post(`URL`, {
            'partnerName': this.state.firmName,
            'timeframes': this.state.timeframes,
            'numberOfResults': this.state.numberOfResults,
        },
        {
            headers: {
                "Authorization": `AUTHORIZATION_KEY`,
                "Content-Type": 'application/json'
            }
        }
    )
    .then(res => console.log(res))
    .catch(error => console.err(error))
}

【讨论】:

  • 谢谢,但我应该如何在views.py 中获取请求?我的 React 正在发布,我如何在后面看到 React 发布的内容?
  • 嘿,如果这个答案对你有帮助,那么请接受这个答案。
  • 我不明白你在views.py 中获取请求的意义。你的意思是这样的 - 你想查看并捕获从 React 应用程序请求的数据??
  • 不,我需要从 React 表单中获取“参数”(partnerName, timeframes, numberOfResults”),以便我可以在 python 中修改它们。
【解决方案3】:

如果您尝试使用 reactfetch 将数据发送到 Django 中的 APIView,您唯一需要做的就是从 fetch 标头中删除 Content-Type 标头,因此 DRF 将设置它,你可以访问来自request.data的文件和数据。

DRF API 视图:

class ImportProductsAPI(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated, IsAdmin)

    def put(self, request):
        # you can pass other data as well as files too.
        site_id = request.data["site_id"]
        # and there is the file you want
        file = request.data["excel"]
        return JsonReponse()

获取(在反应项目中)

let formData = new FormData();
formData.append("excel", file);
formData.append("site_id", site_id);

fetch(
    "api/for/upload", 
    {    
      method: "PUT",
      headers: {
        Accept: "application/json",
        Authorization: "token thisisthetokenforthisuser",
        // consider that there is no Content-Type being setted.
        },
      body: formData,
    })
      .then((response) => {
        return response.json();
      })
      .then((response) => {
        console.log(response);
      })
      .catch((error) => {
        console.error(error);
      });

【讨论】:

    猜你喜欢
    • 2015-12-17
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多