I am a Django developer just getting started with adding React to one page of my app, and really enjoying it so far. (It's a normal Django app with a home page, an about page, etc, but also a "chart" page with an interactive chart, and I want to build the interactive part in React.)
The problem is that I've started with the downloadable React starter kit and I'm not sure how to do things the 'right' way, and it's complicated by using Django to serve my project (all the tutorials seem to assume you're using node, which I'm not).
Right now I just have this in my Django template:
<div id="myapp"></div>
<script src="/static/js/vendor/react.js"></script>
<script src="/static/js/vendor/JSXTransform.js"></script>
<script src="/static/js/myapp.js"></script>
And myapp.js has all the React code. I'm aware this isn't really the grown-up modern JS way of doing things.
Now I want to use React Bootstrap, but it seems that the only sensible way to do that is with npm. So it's time to make the switch, but I'm not completely sure how.
I have run npm install react and npm install react-bootstrap from inside my static/js directory in Django. This has created a node_modules folder with various files inside.
So three questions from a confused newbie:
Where should I put my React code to work with these npm modules (should I use var React = require('react')?
Do I need to compile this code somehow (using webpack?)
How do I then integrate this with Django? Should I compile it all to myapp.js and just include that in my HTML template?
I'm also doing the same thing right now - moving away from embedded HTML script tags into require land. Here is the tutorial I am following, and here is my file system so far. I am doing it in Node but it shouldn't be that different for a Django project as the React frontend code is decoupled from any backend other than API URL's.
Your node_modules folder contains react-bootstrap. In your myapp.js, use the require('react-bootstrap') to load up the library which is contained in your node_modules folder.
Where should I put my React code to work with these npm modules (should I use var React = require('react')?
You can put the code anywhere. If your file system looks like this:
project/
react/
myapp.js
node_modules/
react source code
react bootstrap stuff
Then you can just do var React = require('react'); in myapp.js.
Do I need to compile this code somehow (using webpack?)
Yes, I would consult the webpack tutorial I linked earlier, it should explain how to compile all your React code into a single bundle.js. Here is also another good tutorial. This bundle.js file contains all the source code of your requires. So if your myapp.js looks something like
var React = require('react');
var ReactBootstrap = require('react-bootstrap');
then the bundle.js now contains all of the React and react-bootstrap javascript code, along with the myapp.js source code.
How do I then integrate this with Django? Should I compile it all to myapp.js and just include that in my HTML template?
I've only done work on Nodejs, but my React code so far hasn't touched any Node code, and I don't think it will touch any Django code (again I've never done Django so I might be wrong). All you need to do is compile with webpack, which spits out a bundle.js. You put that bundle.js in your HTML and it'll load up myapp.js.
ReactJS code is still JS code. Even though you do require/import/other module based syntax when coding, in browser you will still load the JS code by a script tag.
The problem is how to let the script generated by webpack(bundle.js) to work with other 'VanillaJS' script. For example, if you only write an individual component using React, like a small table. And its data(props/state) will depend on another element/event written in VanillaJS, e.g, a click listener on a button render by django template. Then the question is, how they communicate with each other.
So far, the solution I know is:
when you write React Code, instead of calling ReactDOM.render explicitly with preset props/state, you can store that in a global function, the arguments could be the props. You load this script first, then the other script can use this global function to trigger the React render Component.
I'm using Django Rest Framework to build an API and then connect to that API from React (using simple Create react app), this way the front end and back end are separated and the application is very scalable. The second way to do this, is call create react app then run build and point your django settings to that react build, this way the front end is not separated from the backend. I hope this helped, good luck.
Related
I am quite new to django so I am sorry if I have overlooked something simple.
This is my current website: https://www.michealnestor.com
I am trying to remake it using react and django, and a lot of it is different, however I want to keep the functionality of being able to run my js apps from the website: https://www.michealnestor.com/projects EXAMPLE: https://www.michealnestor.com/projects/sortingalgorithms/ .
I want to be able to upload project folders, with html, css and js in them from the admin page, and then be able to open these projects from my website. I am not sure how to do this though.
I have tried manually placing such a folder in a templates folder in my app, and I have managed to use a view to load the html file, but this file can't seem to find the css and js.
Maybe I am going about this the wrong way, in any case I would appreciate some guidance!
I am developing a react app inside of a django project and connect them using the Django rest framework. For making API calls from within the react app I am using axios.
Now in my development environment, I obviously call a localhost URL to access the API. For this, I have a file that contains an axios instance:
import axios from "axios";
export const axiosInstance = axios.create({
baseURL: "http://127.0.0.1:8000/api/",
timeout: 60000,
});
Obviously, my API calls don't work in production as the URL differs from the one above. I am compiling my react app to a static file which I include in my django project so I don't think I could really add any code that checks for the environment.
One idea that I had is that I could include a file into my project that I would not push into production and then check for whether this file exists or not and adjust the url in an if statement. However, I am not sure if that is a good solution or how I would implement this in plain Javascript.
I am happy to hear any thoughts on this
Edit
After thinking about my question, it actually doesn't make any sense - I am compiling my file before committing it so it can't be dynamic anyways. What I actually need is one main.js file which I am using in development and another one that I would use in production. However, I have no idea how I could achieve this as I am not bundling any files in production? Maybe there is a way of always bundling two files - one with the localhost url and the other one with my production url.
I am using the django-webpack-loader application which tells my django application which file to load into the html file. By accessing environment variables, I could arrange that change. But how do I tell webpack to make the two distinct bundles?
I think you could use something like dotenv to access environment variables to configure your baseURL.
This question asks if it is possible, and there are many solutions discussed there, like using .env and configuring it with webpack at build time, mind that with the last one you'll require dotenv-webpack plugin.
// separate js file
baseURL = ""
FirstEndpoint = `${baseURL}/addition/`
...etc
change the baseURL in production.
I am a Laravel developer and used Vue as my frontend framework in the past.
However, I got interested in learning Python, specially its web framework equivalent - Django. Compared to Laravel, Django is pretty much way better in all aspects - it's fast, it's one of those 'all-in-one' type of framework, plus it's PYTHON. A 15-minute task in Laravel can be accomplished in Django for 5 minutes.
One thing that's just bugging me is how to integrate Vue on its templates. I tried the normal CDN method but it doesn't actually work. I figured maybe because django's syntax -{{ sample variable here }} and Vue's are the same. I tried writing delimiters like delimiters: ['[[', ']]'], but it just made it more complex and still will not work.
I tried doing the webpack method which install a separate vue project within the django project, then used several (like a lot of third-party plugins) to somewhat connect the vue project, to the django project. It is so tedious on its process and it seems like it's not the why it should be. I kinda miss it on Laravel where you could just create an app.blade.php main template, import app.js on it, then just take it from there.
Is there a way to just integrate Vue on django's templates quickly like you can on Laravel?
We use Vue with Django via cdn, and it is pretty easy to set up as you can do everything in the template file.
You have to be sure to import Vue via script tag somewhere on the page and then either define your own delimiters (as you've done) or use the {% verbatim %} {% endverbatim %} tags around any variables you do not want django to try and evaluate. You can either write your Vue function in a script tag on the page or import an external file via script tag the way you would import any other js file into a django template. If you posted your template code, I might be able to provide more guidance.
I want to do something very simple that I am a little surprised people are not talking about more. I would like to generate on my server my own index.html from the files that are created from building ember for production. I use ember for part of my application and so when a certain URL is hit, I would then like my ember app to take over. I have tried generating my own index.html by changing the flag storeConfigInMeta in ember-cli-build.js.
storeConfigInMeta: false
This gets rid of the ember app having its configuration stored in a meta tag but the app still does not work and gives the error,
Uncaught ReferenceError: define is not defined
I have the latest version of ember and I am building ember with the command,
ember build --env production
My server generated index.html looks identical accept for the integrity attributes set on the include js and css scripts. Is their anything I am missing about approaching ember this way? Should I not be trying to do this?
when a certain URL is hit, I would then like my ember app to take
over.
You need to configure app server to return index.html file for the certain URL.
Generally, it's not required you to create your own index.html.
May be you can check ember-islands addon to include Ember components anywhere on a server-rendered page.
I made a mistake. I was grabbing the production assets with a regular expression with my server and generating my index.html file with these assets in the wrong order. To anyone looking to do this, it is very possible and is more preferable in my opinion to using the generated index.html unless you are using ember for your entire site's routing. However do use the setting in ember-cli-build.js,
storeConfigInMeta: false
This will make it so your ember app stores it's settings in javascript instead of in a tag. This is required for generating your own index.html file.
What is the best approach to use EAK and ember-data-tastypie-adapter?
I am currently trying the following:
Django running on localhost:7000
EAK running on localhost:8000
Added ember-data-tastypie-adapter to bower.json
Added both JS files to index.html
<script src="/vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_adapter.js"></script>
<script src="/vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_serializer.js"></script>
Created everything needed on Django side
I figured that I had to create serializers/application.js and put in it:
export default DS.DjangoTastypieSerializer.extend();
Also adapters/application.js needed adjustments:
export default DS.DjangoTastypieAdapter.extend({
serverDomain: 'http://localhost:7000',
});
Requests go to Django and responses are sent.
However in EAK this gives "Sorry, something went wrong" message without any further information (empty error message box). No errors in console either.
If I remove serializers/application.js I get similar message, in this case with information about the error:
Assertion Failed: Nested controllers need be referenced as [/django/tastypie],
instead of [_djangoTastypie].
Refer documentation: http://iamstef.net/ember-app-kit/guides/naming-conventions.html
Do I have to define defaultSerializer in adapters/application.js? If so, what is it, /django/tastypie or something else?
What am I missing to integrate ember-data-tastypie-adapter in EAK? Trouble is, I have not seen any example where EAK and tastypie would be working together.
Of course this two local server system is development environment. Production is planned like here, both API and JS is served by one Django instance.
UPDATE:
Creating deployment code by grunt dist and serving it using Django works.
I suspect that problem lies with different JSON origin.
Turns out, that EAK has API proxy option.
Updated package.json to my API settings:
"proxyURL": "http://localhost:7000",
"proxyPath": "/api/v1",
Removed custom settings from adapters/application.js.
Now running grunt server:proxy gets data from Django. And ember.js app works without errors, not being same origin was most likely the problem.