0

I am writing my first react-native app with a django backend. for my app to work properly I need to send an image from the device's image library to the django server and then save it in the model. here's my code -

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)

urls.py(home)

router = routers.DefaultRouter()
router.register('users', UserViewSet)
router.register('profiles', ProfileViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('login/', views.login),
    path('signup/', views.signup),
    path('profile/', views.setprofile),
    path('profileimg/', views.setprofileimg),
    path('checkprofile1/', views.checkprofile1),
    path('checkprofile2/', views.checkprofile2),
    path('matchfriends/', views.matchfriends),
    path('getRequesting/', views.getRequesting),
    path('acceptRe/', views.acceptRe),
    path('denyRe/', views.denyRe),
    path('request/', views.request),
    path('unrequest/', views.unrequest),
    path('imagetest/', views.imagetest),
    path('counttest/', views.counttest),

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/'

When I try this and I try to print the profile.image I get the file's name without the "image/" before it. When I checked the admin's interface the image field is blank. I have worked on this issue for weeks and I still can't figure out how to save the image in the django model?

4
  • Share entire imagetest view. Also share urls. Commented Oct 7, 2022 at 3:51
  • Can you please show how you are trying to send the image? Commented Oct 7, 2022 at 4:24
  • I added the urls page but this is the entire imagetest view. Commented Oct 7, 2022 at 12:20
  • I am sending the image with fetch as FormData in react-native Commented Oct 7, 2022 at 12:21

1 Answer 1

1

The problem is Django rest framework need images in base64 format.

so you can install drf_extra_fields.

from drf_extra_fields.fields import Base64ImageField

and use it inside serializer class like this:

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

From react native you should convert image to base64. In react you can use this code but I don't know if works with 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);
        }
    })
}

This code also contain extra lib to compress image called '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)
}
Sign up to request clarification or add additional context in comments.

2 Comments

What would the full serializer for the profile image look like?
profile_image should be in ‘fields’ in serializer, also with same name as model field

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.