0

I am attempting to send a post request containing the name of a genre of music from react to my django api so that this genre can be put into a query param to be searched using the spotify api.

Genre.js // Fetch and map list of genres, when a genre is clicked it is saved to state, then sent in a post request to my endpoint.

import React, { useState, useEffect } from "react";

function Genres() {
  const [genres, setGenres] = useState([]);
  const [clickedGenre, setClickedGenre] = useState("");
  const [type, setType] = useState("")

  useEffect(() => {
    fetch("http://localhost:8000/api/genres/")
      .then((response) => response.json())
      .then((data) => setGenres(data.genres))
      .catch((error) => console.log(error));
  }, []);

  function handleClick(genre) {
    setClickedGenre(genre);
    const query_params = {
      genre: genre,
    };

    // const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
  
    fetch("http://localhost:8000/api/search/", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        // "X-CSRFToken": csrftoken, // Add the CSRF token to the headers
        
      },
      body: JSON.stringify(query_params),
    })
      .then((response) => response.json())
      .then((data) => console.log(data))
      .catch((error) => console.log(error));
  }

  return (
    <div>
      <div className="genre-list-container">
        <ul className="genre-list">
          {genres.map((genre) => (
            <li
              className="genre"
              onClick={() => handleClick(genre)}
              key={genre}
            >
              {genre}
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default Genres;

views.py // Retrieve post request and put result into the "q" param. Then make spotify api request.

import requests
from django.http import HttpResponse, JsonResponse
import json
from .metal_genres import metal_genres
from .oauth import access_token

def search_spotify(request):
    if request.method == "POST":
        data = json.loads(request.body) 
        genre = data.get("genre")
        query_params = {
            "q": genre,
            "type": "artist",
            "market": "US",
            "limit": 1,
            "include_external": "audio",
        }

        headers = {"Authorization": f"Bearer {access_token}"}

        response = requests.get(
            "https://api.spotify.com/v1/search", headers=headers, params=query_params
        )

        if response.status_code == 200:
            results = response.json()
            artists = results["artists"]["items"]
            sorted_artists = sorted(artists, key=lambda x: x["popularity"], reverse=True)
            response_data = {"total": results["artists"]["total"], "artists": []}
            for artist in sorted_artists:
                artist_data = {
                    "name": artist["name"],
                    "id": artist["id"],
                    "genres": artist["genres"],
                    "popularity": artist["popularity"],
                    "top_tracks": [],
                }
                top_tracks_response = requests.get(
                    f"https://api.spotify.com/v1/artists/{artist['id']}/top-tracks?market=ES",
                    headers=headers,
                )
                if top_tracks_response.status_code == 200:
                    top_tracks_results = top_tracks_response.json()
                    top_tracks = top_tracks_results["tracks"]
                    artist_data["top_tracks"] = [
                        {
                            "name": track["name"],
                            "id": track["id"],
                            "preview_url": track["preview_url"],
                        }
                        for track in top_tracks
                    ]
                response_data["artists"].append(artist_data)

            return JsonResponse(response_data)
        else:
            print(f"Request failed with status code {response.status_code}")
            return HttpResponse("Search failed.")
    else:
        return HttpResponse("Invalid request method")


def genres(request):
    return JsonResponse(metal_genres)

The server error I'm getting says: Forbidden (Origin checking failed - http://localhost:3000 does not match any trusted origins.): /api/search/[16/Mar/2023 20:35:46] "POST /api/search/ HTTP/1.1" 403 2569

The console says: POST http://localhost:8000/api/search/ 403 (Forbidden) SyntaxError: Unexpected token '<', "

1 Answers1

0

Your frontend project is hosted on different port, because of that, you need to specify CSRF_TRUSTED_ORIGINS in your settings.py file like this:

For django 4: CSRF_TRUSTED_ORIGINS = ['http://localhost:3000']

For django 3: CSRF_TRUSTED_ORIGINS = ['localhost:3000']

Also, you might need to include frontend host to your API_ALLOWED_HOSTS settings.

Related post: CSRF validation does not work on Django using HTTPS

COSHW
  • 146
  • 8