Search code examples
javascriptdjangofetch

Using Fetch with Javascript and Django


I am new to Javascript and I am using Django.

I've read documentation about the Javascript fetch API but I'm confused about something - if anyone can explain it I'd really appreciate it.

I've seen code that didn't include a url for the API. Where is this coming from within the framework - when I write code, how do I know what to put right after the fetch part?

Example:

const load_like = (post, postLikes, likePost, current_user) => {
    const csrftoken = getCookie('csrftoken');
    fetch(`/post/${post.id}`, {
        method: 'PUT',
        body: JSON.stringify({
            likes: [post.original_poster.id]
        }),
        headers: { "X-CSRFToken": csrftoken }
    })
        .then(response => response.json())
        .then(data => {
            display_likes(data, postLikes, likePost, current_user)
        })
}

Is this done in urls.py ? For example would it be:

 path("post/<int:post_id>", views.post, name="post" ),

I want to make sure I understand how to write this type of line and understand why these parts should go here:

fetch(`/post/${post.id}

Solution

  • So I am also new to this, but this is my approach. I'm not sure if this is how you would do it in production.

    Here is an example from one of my recent projects. One of the apps in the project is called packaging, so the example is from this app.

    urls.py for packaging app:

    app_name = "packaging"
    urlpatterns = [
        ...
        path("brand/<str:brand_id>", views.brand_info, name="brand_info"),
        ...
    ]
    

    views.py (This view renders the html page and reverses the above url into the template):

    @login_required
    def package(request):
        try:
    
            brand_information = reverse('packaging:brand_info', args=['brand_id'])
    
            return render(request, "packaging/package.html", {
                ...
                'brand_information' : brand_information,
                ...
                })
    
        except Exception as e:
            print(e)
            return render(request, "packaging/package.html")
    
    
    
    # The view, `brand_info` returns some information about the brand as a JsonResponse.
    
    
    

    Then, in package.html I used the template tag to extract the reversed url to make it available to the JavaScript file:

    {{ brand_information|json_script:"url_brand_info" }}
    

    The above template tag is an element that has url_brand_info as its id.

    Now, in your JavaScript file:

    function func_to_get_brand_info(id) {
    
        let url_string = JSON.parse(document.querySelector('#url_brand_info').textContent);
        // Here, the url_string looks like this: "/packaging/brand/brand_id".
        // We want to replace the last part of the string with the actual brand id
    
        let url_base = url_string.split('brand_id')[0];
    
        // making a valid url to hit with the fetch
        let url = `${url_base}${id}`;            // NOTE These are backticks not quotes
    
    
    
        // Or, if you don't want to use the dynamic method,
        // you can just hardcode the url in the fetch like:
        // fetch(`/packaging/brand/${id}`, {
        // ...
        // }
        // Here, the '/packaging/brand/' is the url that is in my urls.py file when resolved.
        // This is what is in your example, the url is hardcoded but the id is dynamic.
    
    
        fetch(url, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json'
            }
        })
        .then(response => {
            result = response.json()
            status_code = response.status;
            if(status_code != 200) {
                console.log('Error in getting brand info!')
                return false;
            }
            
            return result
        })
        .then(result => {
            console.log(result);
    
            // Do something with the result
    
        })
        .catch(error => {
            console.log(error)
        })
    
    
    }