0

I am trying to make my first post request using axios to a Django view which accepts both POST and GET. I am getting an empty dict from the request.POST:

<QueryDict: {}>
[13/Aug/2022 16:44:00] "POST /users/114260670592402026255 HTTP/1.1" 200 9

The server does return a 200 status code but the data I sent from the UI is not present.

I have the following django view:

from django.shortcuts import render
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

import json

from .models import UserProfile

@csrf_exempt
def get_user_profile(request, user_id):
    if request.method == 'GET':
        try:
            user = UserProfile.objects.get(user_id=user_id)
            print("user found")
        except Exception as error:
            print("User profile wasnt found:")
            print(error)
            user = None
            profile = UserProfile()
            profile.user_id = user_id
            profile.searches = [
                {'search_term': 'hd'},
                {'search_term': 'wba'},
            ]
            profile.save()
            print("user saved in db")
            user = UserProfile.objects.get(user_id=user_id)

        data = {
            'user_id': user.user_id,
            'searches': user.searches
        }
        json_data = json.dumps(data)
        return HttpResponse(json_data, content_type='application/json')
    if request.method == 'POST':
        data = request.POST
        print(data)
        return HttpResponse("it worked")

in the UI app, SearchPage.js:

  useEffect(() => {
    console.log("user id changed")
    if (userId) {
      const user_profile_api_url = BASE_URL + '/users/' + userId
      axios.get(user_profile_api_url, {})
        .then(response => {
          const recent_searches_response = response.data.searches;
          const new_recent_searches = [];
          recent_searches_response.map(dict => {
            new_recent_searches.push(dict.search_term)
          })
          setRecentSearches(new_recent_searches);
        })
        .catch((error) => {
          console.log("error in getting user profile: ", error.message)
        })
    }
  }, [userId])

  useEffect(() => {
    const user_profile_api_url = BASE_URL + '/users/' + userId
    const data = {searches: recentSearches}
    // axios.post(user_profile_api_url, {
    //   params: {
    //     searches: recentSearches
    //   }
    // })
    axios.post(user_profile_api_url, data
    })
      .then(response => {
        console.log(response)
      })
  }, [recentSearches])

As you can see I pass it in the normal way, as the second arg, then I also try passing it in the way a Udemy course does using the params key. Neither works. My suspicion is the @csrf_exempt may be causing the issue but I a following the same format all the examples online give. I want to get the data of recentSearches from the post request in the Django view

Response from the server after request is made:

enter image description here

network tab

enter image description here

codyc4321
  • 9,014
  • 22
  • 92
  • 165

2 Answers2

1

axios is async

You might call like bellow

useEffect( async () => {
    const user_profile_api_url = BASE_URL + '/users/' + userId
    const data = {searches: recentSearches}
   const response = await axios.post(user_profile_api_url, data)

console.log(response)
  }, [recentSearches])
underscore
  • 6,495
  • 6
  • 39
  • 78
  • causes the following error: `react-dom.development.js:86 Warning: useEffect must not return anything besides a function, which is used for clean-up. It looks like you wrote useEffect(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately: useEffect(() => { async function fetchData() { // You can await here const response = await MyAPI.getData(someId); // ... } fetchData(); }, [someId]); // Or [] if effect doesn't need props or state ` – codyc4321 Aug 13 '22 at 19:00
1

more digging led to Django docs for http requests, I Should have started there instead of third party examples

print(request.body)

the data can be found on request.body in the django view and converted to a python object by loading the json

b'{"searches":["hd","wba","psec"]}'



if request.method == 'POST':
    # data = request.POST
    raw_data = request.body
    """https://stackoverflow.com/questions/29780060/trying-to-parse-request-body-from-post-in-django"""
    body_unicode = raw_data.decode('utf-8')
    body = json.loads(body_unicode)
    print(body)
    searches = body['searches']
    searches_objects = [{'search_term': x} for x in searches]
    print(searches_objects)
    user = UserProfile.objects.get(user_id=user_id)
    user.searches = searches_objects
    user.save()
    return HttpResponse("it worked")
codyc4321
  • 9,014
  • 22
  • 92
  • 165