Проблемы при попытке сохранить изображение из react-native в модель django

Я пишу свое первое react-native приложение с бэкендом django. чтобы мое приложение работало правильно, мне нужно отправить изображение из библиотеки изображений устройства на сервер django и затем сохранить его в модели. вот мой код -

react-native-

const sendI = async (image) => {
  
    const formData = new FormData()
    let image_data = {
      uri : image.uri,
      name : image.fileName,
      type : image.type,
    }
    if (image != null){
    
      await formData.append( 'image', image_data)
      await formData.append('name', usern)
      //await formData.append('name', 'a' )
      console.log(formData)
      setSentI(formData)
      console.log('recieved')
    }

    
    console.log(image)
    
  }

  


  const showImagePicker = async () => {
    
    // Ask the user for the permission to access the media library 
    const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this appp to access your photos!");
      return;
    }
    
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    // Explore the result
    console.log(result);

    if (!result.cancelled) {
      await setProfileImage(result);
      console.log(result.uri);
      sendI(result);
      
    }
  }

  const openCamera = async () => {
    // Ask the user for the permission to access the camera
    const permissionResult = await ImagePicker.requestCameraPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this appp to access your camera!");
      return;
    }

    const result = await ImagePicker.launchCameraAsync();

    // Explore the result
    console.log(result);

    if (!result.cancelled) {
      setProfileImage(result);
      console.log(result);
    }
  }


  const image = () => {
    

    console.log(sentI)
    fetch(server + `home/imagetest/`, {
      method: 'POST',
      headers: {
        'Content-Type': 'multipart/form-data',

         },
      body: sentI, 
  })
  .then( res => res.json())
  .then( res => {
    console.log(res)

  })
  .catch( error => console.log(error))

}

django-

models.py

class Profile(models.Model):
  image = models.ImageField(upload_to="images/", blank=True)

views.py

@csrf_exempt
def imagetest(request):
    if request.method == "POST":
        print(request.FILES)
        image = request.FILES.get('image', False)
        user = request.POST.get('name', False)
        print(image)
        print(user)
        userid = User.objects.get(username=user).id
        profile = Profile.objects.get(id=userid)
        profile.image = image
        print(profile)
        print(profile.image)

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('home/', include('home.urls')),
    path('auth/', obtain_auth_token),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

settings.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
STATIC_URL = '/static/'

Когда я пробую это и пытаюсь распечатать profile.image, я получаю имя файла без "image/" перед ним. Когда я проверил интерфейс администратора, поле изображения пустое. Я работал над этим вопросом несколько недель и до сих пор не могу понять, как сохранить изображение в модели django?

проблема в том, что Django rest framework требует изображения в формате base64

поэтому вы можете установить drf_extra_fields

from drf_extra_fields.fields import Base64ImageField

и использовать его внутри класса сериализатора следующим образом:

profile_image = Base64ImageField(use_url=True, required=False)

из react native вы должны преобразовать изображение в base64 . в react вы можете использовать этот код, но я не знаю, работает ли он с react native

const convertBase64 = (file) => {
    return new Promise((resolve, reject) => {
        const fileReader = new FileReader();
        fileReader.readAsDataURL(file)
        fileReader.onload = () => {
            resolve(fileReader.result);
        }
        fileReader.onerror = (error) => {
            reject(error);
        }
    })
}

этот код также содержит дополнительную либу для сжатия изображения под названием 'compressorjs'

const handleFileRead = async (event) => {
    const file = event.target.files[0]
    let compressedFile = null;
    const compressed = new Compressor(file, {
        quality: 0.6,

    });
    const base64 = await convertBase64(compressed.file)
    setValue('profile_image', base64)
    setFile(compressedFile)
}
Вернуться на верх