8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Expo React Native post 方法在 Django rest 框架正确路径上不包括 MEDIA

scibuff 1月前

18 0

我正在尝试创建一个 Expo React Native 应用程序,在该应用程序中我将一个 Pdf 文件发送到我在 Django Rest Framework 中创建的 API。但是,当我发送该 pdf 文件时,它并没有保存在正确的位置,我会把它放……

我正在尝试创建一个 Expo React Native 应用程序,其中我将一个 Pdf 文件发送到我在 Django Rest Framework 中创建的 API。但是,当我发送 pdf 文件时,它没有保存在正确的位置,我会放上代码和日志来更好地解释。

# models.py

from django.db import models


# Create your models here.
class PDFFile(models.Model):
  name = models.CharField(max_length=200, blank=True)
  pdf_file = models.FileField(upload_to="pdfs/", blank=True)

  def __str__(self):
    return str(self.name)
# serializers.py
from rest_framework import serializers
from .models import PDFFile


class PDFFileModelSerializer(serializers.ModelSerializer):
  class Meta:
    model = PDFFile
    fields = ["id", "name", "pdf_file"]
# views.py
from .models import PDFFile
from .serializers import PDFFileModelSerializer

from rest_framework import viewsets, status
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response

class PDFFileViewSet(viewsets.ModelViewSet):
  queryset = PDFFile.objects.all()
  serializer_class = PDFFileModelSerializer
  parser_classes = (MultiPartParser, FormParser)

  def create(self, request, *args, **kwargs):
    name = request.data["name"]
    pdf_file = request.data["pdf_file"]
    print("PDF FILE: ", pdf_file)

    PDFFile.objects.create(name=name, pdf_file=pdf_file)

    return Response("PDF create with success!", status=status.HTTP_200_OK)
  
# urls.py from the app

from rest_framework import routers
from .views import PDFFileViewSet
from django.urls import path, include

router = routers.DefaultRouter()
router.register("pdfs", PDFFileViewSet)

urlpatterns = [
  path("", include(router.urls))
]

# urls.py from the project
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include("pdf_uploader.urls")),
]  + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


# settings.py

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser'
     )
 }

DATA_UPLOAD_MAX_MEMORY_SIZE = 5242880

STATIC_URL = '/static/'

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

STATIC_ROOT = BASE_DIR / 'staticfiles'

Expo React Native 组件:

import { View, Text, StyleSheet, TouchableOpacity, SafeAreaView, Alert } from 'react-native'
import React, { useState } from 'react'
import * as DocumentPicker from 'expo-document-picker'
import { PDF_BASE_URL } from '../data/api'

const PdfPicker = () => {
  
  const [pdfFile, setPdfFile] = useState(null)
  const [name, setName] = useState("")
  const [uploading, setUploading] = useState(false)
  
  const pickerPdf = async () => {
    let result = await DocumentPicker.getDocumentAsync({
      type: 'application/pdf',
    })
    
    const fileName = result.uri.split('/').pop() // extract the file name from the URI
    const source = { uri: fileName, name: result.name }
    console.log("source", source)
    setPdfFile(source.uri)
    setName(source.name)
  }
  
  const uploadPdfFile = async () => {
    setUploading(true)
    
    const uploadPdf = pdfFile
    const pdfName = name
    const data = new FormData()

    data.append("name", pdfName)
    data.append("pdf_file", uploadPdf)

    const response = await fetch(PDF_BASE_URL + "pdfs/", {
      method: "POST",
      headers: {
        "Content-Type": "multipart/form-data",
      },
      body: data
    })

    console.log("RESULT: ", JSON.stringify(response))

    try {
      await JSON.stringify(response)
    } catch (e) {
      console.log("Catch error:", e)
    }
    setUploading(false)
    Alert.alert(
      "Pdf file uploaded..!!"
    )
    setName("")
    setPdfFile(null)
  }

  return (
    <SafeAreaView style={styles.container} >
      <View>
        <Text style={{color: "white", marginBottom: 30}}>{name}</Text>
      </View>
      <TouchableOpacity style={styles.selectButton} onPress={pickerPdf} >
        <Text style={styles.buttonText}>Pick a Pdf file</Text>
      </TouchableOpacity>
      <View style={styles.pdfContainer}>
        <TouchableOpacity style={styles.uploadButton} onPress={uploadPdfFile}>
          <Text style={styles.buttonText}>Upload Pdf file</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  )
}

export default PdfPicker

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    backgroundColor: '#000',
    justifyContent: 'center',
  },
  selectButton: {
    borderRadius: 5,
    width: 150,
    height: 50,
    backgroundColor: 'blue',
    alignItems: 'center',
    justifyContent: 'center',
  },
  buttonText: {
    color: 'white',
    fontSize: 18,
    fontWeight: 'bold'
  },
  pdfContainer: {
    marginTop: 30,
    marginBottom: 50,
    alignItems: 'center',
  },
  uploadButton: {
    borderRadius: 5,
    width: 150,
    height: 50,
    backgroundColor: 'green',
    alignItems: 'center',
    justifyContent: 'center',
  }
})

世博会日志

 LOG  RESULT:  {"type":"default","status":200,"ok":true,"statusText":"","headers":{"map":{"allow":"GET, POST, HEAD, OPTIONS","content-length":"26","content-type":"application/json","cross-origin-opener-policy":"same-origin","date":"Thu, 06 Apr 2023 14:19:30 GMT","referrer-policy":"same-origin","server":"railway","vary":"Accept, Origin, Cookie","x-content-type-options":"nosniff","x-frame-options":"DENY"}},"url":"{my.server}/api/pdfs/","bodyUsed":false,"_bodyInit":{"_data":{"size":26,"offset":0,"blobId":"837A79CD-3B4F-4D1C-A15D-74BE46D9CD26","type":"application/json","name":"pdfs.json","__collector":{}}},"_bodyBlob":{"_data":{"size":26,"offset":0,"blobId":"837A79CD-3B4F-4D1C-A15D-74BE46D9CD26","type":"application/json","name":"pdfs.json","__collector":{}}}}

浏览器发送:

{
        "id": 5,
        "name": "livro",
        "pdf_file": "{my.server}/media/pdfs/Stephen.King.-.A.Balsa_WF9W8Kc.pdf"
    }

由 Expo 应用程序发送

{
        "id": 4,
        "name": "CERTIDAO-IANDERSONPIZETTEUENDERSONPABLOIII.pdf",
        "pdf_file": "{my.server}/media/C2699748-A1CF-49F5-A3C7-6B527AD3FF44.pdf"
    },

后端日志:

Not Found: /media/C2699748-A1CF-49F5-A3C7-6B527AD3FF44.pdf

所以,我不知道我的问题出在哪里。

也许一双新的眼睛可以帮助我。

我读过 Django 和 DRF 文档、Expo React Native 文档。我尝试从 ChatGPT 获取帮助。

现在我正尝试在这里寻求一些帮助。

帖子版权声明 1、本帖标题:Expo React Native post 方法在 Django rest 框架正确路径上不包括 MEDIA
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由scibuff在本站《api》版块原创发布, 转载请注明出处!
最新回复 (0)
  • d-b 1月前 0 只看Ta
    引用 2

    我找到了我的问题的解决方案,我注意到我通过移动应用程序发送的是我的 pdf 文件的 blobId,而通过浏览器,我发送的是下载的 pdf 文件,因此我开始在移动应用程序上下载文件,然后发送到我的后端。

    并且成功了。代码如下。我将与看到这篇文章并遇到与我相同或类似问题的人分享我的解决方案。

    import { View, Text, StyleSheet, TouchableOpacity, SafeAreaView, Alert } from 'react-native'
    import React, { useState } from 'react'
    import * as DocumentPicker from 'expo-document-picker'
    import { PDF_BASE_URL } from '../data/api'
    import * as FileSystem from 'expo-file-system';
    
    const PdfTry = () => {
      const [pdfFileUri, setPdfFileUri] = useState(null)
      const [pdfFileName, setPdfFileName] = useState("")
      const [uploading, setUploading] = useState(false)
      
      const pickerPdf = async () => {
        let result = await DocumentPicker.getDocumentAsync({
          type: 'application/pdf',
          copyToCacheDirectory: false
        })
        
        const pdfUri = result.uri
        const pdfName = result.name
    
        // Download the selected PDF file to the device's local storage
        const fileUri = FileSystem.documentDirectory + pdfName
        await FileSystem.copyAsync({ from: pdfUri, to: fileUri })
        
        setPdfFileUri(fileUri)
        setPdfFileName(pdfName)
      }
      
      const uploadPdfFile = async () => {
        if (!pdfFileUri) {
          Alert.alert("Please select a PDF file first.")
          return
        }
    
        setUploading(true)
    
        const data = new FormData()
        data.append("name", pdfFileName)
        data.append("pdf_file", { uri: pdfFileUri, name: pdfFileName, type: 'application/pdf' })
    
        const response = await fetch(PDF_BASE_URL + "pdf_upload/", {
          method: "POST",
          headers: {
            "Content-Type": "multipart/form-data",
          },
          body: data
        })
    
        try {
          await JSON.stringify(response)
        } catch (e) {
          console.log("Catch error:", e)
        }
        setUploading(false)
        Alert.alert(
          "Pdf file uploaded..!!"
        )
        setPdfFileName("")
        setPdfFileUri(null)
      }
    
      return (
        <SafeAreaView style={styles.container} >
          <View>
            <Text style={{color: "white", marginBottom: 30}}>{pdfFileName}</Text>
          </View>
          <TouchableOpacity style={styles.selectButton} onPress={pickerPdf} >
            <Text style={styles.buttonText}>Pick a Pdf file</Text>
          </TouchableOpacity>
          <View style={styles.pdfContainer}>
            <TouchableOpacity style={styles.uploadButton} onPress={uploadPdfFile}>
              <Text style={styles.buttonText}>Upload Pdf file</Text>
            </TouchableOpacity>
          </View>
        </SafeAreaView>
      )
    }
    
    export default PdfTry
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: 'center',
        backgroundColor: '#000',
        justifyContent: 'center',
      },
      selectButton: {
        borderRadius: 5,
        width: 150,
        height: 50,
        backgroundColor: 'blue',
        alignItems: 'center',
        justifyContent: 'center',
      },
      buttonText: {
        color: 'white',
        fontSize: 18,
        fontWeight: 'bold'
      },
      pdfContainer: {
        marginTop: 30,
        marginBottom: 50,
        alignItems: 'center',
      },
      uploadButton: {
        borderRadius: 5,
        width: 150,
        height: 50,
        backgroundColor: 'green',
        alignItems: 'center',
        justifyContent: 'center',
      }
    })
返回
作者最近主题: