Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading Image in a React+Django app

So I have a little project written in python/django for the backend and react for the frontend. I followed the tutorial from: http://geezhawk.github.io/using-react-with-django-rest-framework

I want to show an image for the logo of the project, the webpack build was success, but however, the image could not load up when I see the page, I suppose that is because the compiled URL of the image could not be resolved from the django's urls, and also accessing the url for it just load the same index page....

At this point I'm not sure how I can fix it, but I would be more than grateful if anyone can point me to an example code of how to do this, how to load image in a react + django project.

Edit
Project structure

project
|- api
|  |- models.py
|  |- serializers.py
|  |- views.py
|- assets
|  |- bundles
|  |- js
|- node_modules
|- project
|  |- settings.py
|  |- static
|  |- urls.py
|- templates
|  |- index.html

And inside the urls.py

    url(r'^$', TemplateView.as_view(template_name='index.html'))

and here is my index.html

{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
    <head>
        <title>Hello React</title>
    </head>
    <body>
        <div id="content"></div>
        {% render_bundle 'main' %}
    </body>
</html>

and here is where I'm trying to load an image in my JS

import React from 'react'
import logo from './resources/logo.jpeg'

class Header extends React.Component {
  render() {
    return (
      <nav className="navbar navbar-expand-md fixed top bg-dark navbar-dark">
        <a className="navbar-brand" href="#">
          <img src={logo} width="30" height="30" className="d-inline-block align-top" alt="" />
          Project Name
        </a>
      </nav>
    )
  }
}
like image 585
bman765 Avatar asked Jan 13 '18 12:01

bman765


1 Answers

I ran into the same problem that you are running into when I was building a react front-end, django backend single-page-app. The issue is that webpack controls imports in the JS code and wants to manage the location of static files, but django is the one hosting the website and, thus, the static files.

The way that we worked around this is by not importing the images in the javascript but, instead, putting the url path to the image that points to the location where it is being hosted by django.

After looking at the tutorial you linked to, I believe you should make the following additions to your django app:

  • Add STATIC_URL = '/static/' to your settings.py
  • Either put the logo.jpeg, and subsequent images, in your assets/ folder or add the resources/ folder to the STATICFILES_DIR variable in settings.py as such (assuming resources is in the top level direcrory of your project):

    STATICFILES_DIRS = (
        #This lets Django's collectstatic store our bundles
        os.path.join(BASE_DIR, 'assets'), 
        os.path.join(BASE_DIR, 'resources'), 
    )
    

Now, you should be able to access the image (if you do django admin.py runserver) by going to 127.0.0.1:8000/static/logo.jpeg. Within the HTML/JS, the URL to the image is simply "/static/logo.jpeg" since within the browser it will resolve that to the entire URL.

Thus, now if you have an image that you put in your assets or resources folder with a path within the folder of "path/to/image.jpeg", then the URL to put as the src of the image in your react code is "/static/path/to/image.jpeg" (the / in the beginning is very important to ensure it does the absolute URL). Thus, you can change your Header class to be:

import React from 'react'

class Header extends React.Component {
  render() {
    return (
      <nav className="navbar navbar-expand-md fixed top bg-dark navbar-dark">
        <a className="navbar-brand" href="#">
          <img src={"/static/logo.jpeg"} width="30" height="30" className="d-inline-block align-top" alt="" />
          Project Name
        </a>
      </nav>
    )
  }
}

This should work as long as your host your static files through Django.

like image 56
Rohan Varma Avatar answered Nov 11 '22 23:11

Rohan Varma