Andrew Bregman
Andrew Bregman

Reputation: 170

Django/React App: How to have both Django URLS (for the api to send data) and React URLS (to render my components) in my web app, compatibly

I just added this to the urls.py in my react folder: re_path(r'^(?:.*)/?$', views.index), after following this stackoverflow post: react routing and django url conflict. My error in the dev tools is: Unknown_URL_Scheme

However, in my situation, this creates problems. My method of sending JSONs to my react is through the url: "api/leads," which is now inaccessible. How do I produce a way for my react urls to exist in harmony with my django urls? Attached are my django urls.py, react--> App.js, urls.py, views.py, index.html, and DataFetching.py (where you will be able to see how I send the data from my api).

Django: urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('api/lead/', views.LeadListCreate.as_view()),

]

Django Project: urls.py

from django.contrib import admin
from django.urls import path, include, re_path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('leads.urls')),
    path('', include('frontend.urls')),
    
]

React--> urls.py

from django.urls import path, re_path
from . import views

urlpatterns = [
    #path('', views.index),
    re_path(r'^(?:.*)/?$', views.index),
]

By the way, I tried to look at the documentation for urls(r^...) and it wouldn't tell me how to import it, but instead basically said that urls is basically the same as re_path; this may be the problem, nonetheless, I would still not know the solution.

React-->views.py

from django.shortcuts import render


def index(request):
    return render(request, 'frontend/index.html')

React--> App.js

import './index.css';
import BellIcon from './icons/bell.svg';
import MessengerIcon from './icons/messenger.svg';
import CaretIcon from './icons/caret.svg';
import PlusIcon from './icons/plus.svg';
import DataFetching from "../DataFetching";
import DropdownMenu from "../DropDown";
import React, { useState } from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";


function App() {
  return (
    <Router>
    <div className="App">
      <Navbar>
        <NavItem icon={<PlusIcon />} />
        <NavItem icon={<BellIcon />} />
        <NavItem icon={<MessengerIcon />} />
        <NavItem icon={<CaretIcon />}>
          <h1> Hello World </h1>
          <DropdownMenu></DropdownMenu>
        </NavItem>
      </Navbar>
      
      <Switch>
          <Route path="/about">
            <About />
            <DataFetching />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
    </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}

(There is more, but it is not relevant)

DataFetching.js

import React, {useState, useEffect} from 'react'
import axios from 'axios'

function DataFetching() {
    const [leads, setLeads] = useState([])

    useEffect(() => {
        axios.get("api/lead")
            .then(res =>{
                console.log(res)
                setLeads(res.data)
            })
            .catch(err => {
                console.log(err)
            })
    }, [])
    return (
        <div>
            <ul>
                {
                    leads.map(lead => <li key={lead.id}>{lead.name} says {lead.message}</li>)
                }
            </ul>
        </div>
    )
}

export default DataFetching

index.html

<!DOCTYPE html>
<html>
<head>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700;900&display=swap" rel="stylesheet">
    <title>React App</title>
</head>
<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root">
      <!-- React will load here -->
  </div>
  {% load static %}
  <script src="{% static "frontend/main.js" %}"></script>
</body>

</html>

If you have a better way to send data to my react app, or other useful insights, feel free to drop in the chat!

EDIT PROGRESS: NONE, STILL HAVE NO CLUE ABOUT WHERE TO EVEN START ON THIS PROBLEM, CAN'T FIND ANYTHING OF SUSBSTANCE ON THE TOPIC

Upvotes: 1

Views: 5349

Answers (3)

gbk_Prado
gbk_Prado

Reputation: 41

I added the following re_path at the end of the project urls.py

from django.urls import path, include, re_path

urlpatterns = [
    ...
    ...
    re_path(r'.*', views.home)
]

that will make all the other previous django url paths work, and if a not existent path is requested should be handled by react router.

the source of my approach link

Upvotes: 4

Andrew Bregman
Andrew Bregman

Reputation: 170

This is how I fixed the issue:

Django project urls.py

from django.contrib import admin
from django.urls import path, include, re_path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('leads.urls')),
    path('', include('frontend.urls')),

]

Urls for django app (API)

from django.urls import path
from . import views

urlpatterns = [
    path('lead/', views.LeadListCreate.as_view()),
    path('profiles/', views.ProfileAPI.as_view()),

]

Urls for frontend

from django.urls import path, re_path
from . import views
from django.conf.urls import url

urlpatterns = [
    #path('', views.index),
    url('', views.index)
]

Upvotes: 2

ruddra
ruddra

Reputation: 51978

Here are my thoughts about your problem:

First, you don't have any urls at path api/leads/ but you do have api/lead/ defined in urls.py. It might be a typo. Also at axios, you should use axios.get("/api/lead/").

Second, your urls should be in harmony. Because of the order of urls:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('leads.urls')), 
    path('', include('frontend.urls')), 
    
]

If you hit the django server at path /, first it tries with first path, as it does not match at /admin, it goes to second path. It does not match either, so finally it matches with regex ^(?:.*)/?$(any path should match that) at third path, hence React app should be visible there. So it should work if you fix the typo.

Third, it would be best to have React application served differently then using Django. You can use Nginx to serve the React application seperatly in production. Or there are documentations on how you can serve React in production. In local machine, you can use npm start or yarn start to run the application. Then there will come the issue for authenitcation and session in React. You can use Token based authentication to resolve that.

Upvotes: 2

Related Questions