Folder structure for React and Django REST - django

I'm in the process of refactoring a rather basic/traditional Django webapp to a more modern React-plus-Django-REST setup. I'm far more familiar with Django than React, so where to put the React part is what's confusing to me.
My question is: what are the best practices for folder structure in using both Django and React? Ideas I've had:
Put all React files in their own folder like this:
.
├── app1
│   └── example-files.py
├── app2
│   └── example-files.py
├── manage.py
├── react-django-project
│   ├── settings.py
│   └── urls.py
├── requirements.txt
├── some-app-1
│   └── example-files.py
├── some-app-2
│   └── example-files.py
├── src
│   └── components
│   ├── component1.js
│   └── component2.js
└── ...
Put all React files in the static folder, but this doesn't seem right to me.
Is there an established set of best practices for this?

Most of the time there are two separate projects for the back and the front end:
To build a ReST API using Django I'd strongly recommend you to check out Django REST framework if you haven't already. There is a simple tutorial on that home page that should get you up and running.
For the React app "React Create App" seems to be the standard way to start a project nowadays. See the linked GitHub page for step-by-step instructions.
Then follow this "Proxying API Requests in Development" guide to proxy requests to your API for your development setup.

I agree with Igonato about having separate projects for frontend and backend. As client(Frontend) would make Ajax(API) calls to the server(Backend) and with the response data, client renders the page.
Especially with react, you need to convert the react code to minified js and css for higher performance on the production server.
You may use djangorestframework in the backend and setup a django server. For frontend, here are a couple of options:
1. you can use dva (if you intend to use redux). dva is good. I would recommend not to use redux until the state management in your application gets complicated.
2. If you are not gonna use redux, then you can use create-react-app
For front-end I would recommend to use antd if you want to go for material design based application. It's quite a lot of UI elements that you would need in your application. It's battle tested. I have used it in ~9 applications, I have made in the past 6 months.

As the others mentioned, using different repositories is the common approach to solve this. However for a smaller team / smaller project a single repository should suffice.
To keep everything in one repo you create a separate for folder for the react app, usually I name it projectname-client. If you are using create-react-app you could serve the index.html from the build folder by adding that path to settings file.
# settings.py
# Path to the frontend app build directory
BUILD_DIR = os.path.join(BASE_DIR, '{{ project_name }}-client/build')
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BUILD_DIR
],
...
},
]
STATICFILES_DIRS = [
os.path.join(BUILD_DIR, 'static'),
]
# urls.py
urlpatterns = [
...
path('', TemplateView.as_view(template_name='index.html'), name='index'),
]
If you are interested, I'm working on a django-admin startproject template that sets up the project to work with create-react-app. You can take a look here.

Related

Project architectures differences for Django + Vuejs (or other) integration

I'm currently looking at project setups for a Django + Vuejs project (though I guess the question is likely just as valid for other frontends, react, svelte etc.).
It seems that there are mainly 2 approaches that come up often, resulting in the following project structure:
The frontend embedded within the Django project (perhaps as a git submodule):
root
├── djangoapp
├── djangoproject
├── manage.py
├── requirements.txt
├── static
├── venv
└── vueproject
├── node_modules
├── package.json
├── public
└── src
Another approach is to have them at the same level from project root, as 2 seperate projects actually (or I guess both could be git submodules to a "wrapper" project), so essentially:
root
├── djangoproject
│   └── <django files & folders>
└── vueproject
└── <vue files & folders>
With the 2nd approach, it seems you basically just see Django as an API. Stuff like collectstatic does not (?) come into play. In development, you need a server up to serve Django's api, and a dev server for the vue frontend.
With the 1st approach (if I understand correctly), seems that you build the Vue static files, and then manage all of that with Django's collectstatic/static files management.
Seems the 2nd approach is a better decoupling of the 2 components. With the 1st, you need to configure vue (or vite) rather specifically and Django's static files as well. What we gain by doing this isn't obvious to me - the more I think about it, the more it seems clear that the 2nd approach is better.
What potential advantages would there be in the 1st approach? Dev conveniences I'm not seeing? Easier deployment? Or is it just a somewhat outdate approach that still lingers the web?

Integrating jquery-csv into Rails app, ES15 syntax causing issues

I have already implemented a csv import feature in my app using this plugin, and it works great! But recently I had to reinstall some of my assets and it appears the plugin has some recent additions that include ES15 syntax. My Rails 4 app isn't ready to digest ES15 so I'm looking for a way to exclude the offending files if I can.
The plugin's directory structure looks like this (with some items omitted for brevity).
├── src
│   ├── jquery.csv.js
│   └── jquery.csv.min.js
└── test
├── csv.from_array.js
├── csv.from_arrays.js
├── csv.parsers.js
├── csv.to_array.js
├── etc ...
The ES15 code only appears in the test/ files. In my assets pipeline I include jquery.csv.js, which apparently includes the test/ files, as it's choking on the ES15 when I precompile assets. (If I don't require jquery.csv.js, assets precompile fine.)
This illustrates the errors I'm seeing when I precompile.
Seems like I should be able to do without the test files, but looking in jquery.csv.js it's not obvious to me how they're being included.
I know I should probably focus on getting Rails upgraded or use webpack/babel/whatever to integrate ES15 but I'm hoping for a short-term fix so I can move forward.
Thanks for any tips!

How to deploy a Go web application in Beanstalk with custom project folder structure

I'm new to Go.
I am trying to deploy a simple web project to EB without success.
I would like to deploy a project with the following local structure to Amazon EB:
$GOPATH
├── bin
├── pkg
└── src
├── github.com
│   ├── AstralinkIO
│   │   └── api-server <-- project/repository root
│   │   ├── bin
│   │   ├── cmd <-- main package
│   │   ├── pkg
│   │   ├── static
│   │   └── vendor
But I'm not sure how to do that, when building the command, Amazon is treating api-server as the $GOPATH, and of course import paths are broken.
I read that most of the time it's best to keep all repos under the same workspace, but it makes deployment harder..
I'm using Procfile and Buildfile to customize output path, but I can't find a solution to dependencies.
What is the best way to deploy such project to EB?
Long time has past since I used Beanstalk, so I'm a bit rusty on the details. But basic idea is as follows. AWS Beanstalk support for go is a bit odd by design. It basically extracts your source files into a folder on the server, declares that folder as GOPATH and tries to build your application assuming that your main package is at the root of your GOPATH. Which is not a standard layout for go projects. So your options are:
1) Package your whole GOPATH as "source bundle" for Beanstalk. Then you should be able to write build.sh script to change GOPATH and build it your way. Then call build.sh from your Buildfile.
2) Change your main package to be a regular package (e.g. github.com/AstralinkIO/api-server/cmd). Then create an application.go file at the root of your GOPATH (yes, outside of src, while all actual packages are in src as they should be). Your application.go will become your "package main" and will only contain a main function (which will call your current Main function from github.com/AstralinkIO/api-server/cmd). Should do the trick. Though your mileage might vary.
3) A bit easier option is to use Docker-based Go Platform instead. It still builds your go application on the server with mostly same issues as above, but it's better documented and possibility to test it locally helps a lot with getting configuration and build right. It will also give you some insights into how Beanstalk builds go applications thus helping with options 1 and 2. I used this option myself until I moved to plain EC2 instances. And I still use skills gained as a result of it to build my current app releases using docker.
4) Your best option though (in my humble opinion) is to build your app yourselves and package it as a ready to run binary file. See second bullet point paragraph here
Well, which ever option you choose - good luck!

Managing Static Files and Templates Django

I have gone through a few tutorials on creating a web application in Django. Based on the different tutorials so far, everyone seems to have a slightly different ways of storing their static files and templates.
In one particular tutorial, the author created a static folder at the same level as the project folder. Within the static folder, he created four more folders.They are :
media
static
static-only
templates
Within static, he created:
css
js
within templates, he stores all the web app templates such as base.html, aboutus.html, etc.
However, in the official django documentation, it says
https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-during-development
Store your static files in a folder called static in your app. For example my_app/static/my_app/myimage.jpg.
May I ask which is the most common way of doing it? Many thanks!
It depends. Since my apps share the same set of static and templates I store them in root dirs:
# Settings
STATIC_URL = '/static/'
STATIC_ROOT = abspath('static')
STATICFILES_DIRS = (abspath('styles'),)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
...
)
TEMPLATE_DIRS = (abspath('templates'),)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
# All styles are in one place
├── styles
│   ├── less
│   ├── js
# App's templates are stored in privite dirs so I can move them in app dir any time
# without changing my code: flatpages/flatpage_detail.html Also it works well with
# class based views.
├── templates
│   ├── base.html
│   ├── flaptages/
│   │   └── flatpage_detail.html
│   ├── another_app/
│   │   └── another_app_detail.html
Then I do manage.py collecstatic and have all static in root/static dir.
It fits me. But if I would make an app to share with community I will put static and templates in it's own dir as described in docs.

Emulate DirectoryIndex in Django dev server

I'm able to configure a new Django project to serve static files. This is the project layout:
.
├── __init__.py
├── manage.py
├── settings.py
├── mystatic
│   └── index.html
└── urls.py
settings.py:
STATICFILES_DIRS = (
join(abspath(dirname(__file__)), 'mystatic'),
)
I run the server the usual way:
./manage.py runserver
This works pretty well. At http://127.0.0.1:8000/static/index.html it shows my custom index page. What I'd like to do is access to http://127.0.0.1:8000/static/ (with or without trailing slash) and get the same page. Instead the server doesn't respond with my own page, but with the default Django project page (It worked! Congratulations on your first Django-powered page. etc.).
How should I change things (maybe in urls.py or in some view), so that even if without specifying index.html both the URLs give the page I want? Using plain Apache this is the default behavior, because when a page name is not specified index.html is used (see Apache's DirectoryIndex). I need to replicate the same on Django development server.