How to provide data to react with drf without extra requests? - reactjs

I build a single page application with react and django rest framework. I want to have an ability to change "static" info through django admin interface to avoid unnecessary extra deploy every time. Such info like background image and text from about section.
To edit it I create cms django app and register models in admin.
To serve frontend in production I use TemplateView from django.views.generic package. It serves html file from bundled react app directory. here's part of root urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
# ...
# api endpoints here
# ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += [re_path(r'^.*', TemplateView.as_view(template_name='index.html'))]
to serve it in development I use react-scripts start from create-react-app
How can I pass information like the current url of the background image, text for about section, etc. there?
Simple option is to create bunch of views to get this info and request all the data from react app, but I don't really like this approach.
another option is to redefine TemplateView like this
from django.views import generic
class TemplateView(generic.TemplateView):
template_name = 'index.html'
def get_context_data(self, **kwargs):
context_data = dict()
# get all data from db here
return context_data
But how then I use this in react app? in production and in development.
I believe there should be correct way to solve such problem.

One possible solution I found is to hardcode url to background image on frontend and create or update symlink corresponding to this url.
So when I upload new image on django admin, behind scene it saves record in the database, save file itself and update symlink. In this way I also able to set another image as active just updating symlink in process of saving.
This solution looks good for me, but only works for static files, not text data.

Related

URL config Wagtail-pages in own Django project

I have set up my own Django-project. I have no own app’s installed. That’s for later. What I did was copying the ‘base’ and ‘blog’ app from the bakerydemo to my own project. These run fine, I can access the blog-pages and the admin-site from wagtail.
Only problem is the root url is now a blank-page (can’t add wagtail-field or anything). My wagtail homepage is now on ip-adress/home and it should be on ip-adress. This is my url-config:
from wagtail.admin import urls as wagtailadmin_urls
from wagtail import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('cms/', include(wagtailadmin_urls)),
path('documents/', include(wagtaildocs_urls)),
# path('pages/', include(wagtail_urls)),
path('', include(wagtail_urls)),
# path("test404/", TemplateView.as_view(template_name="404.html")>
# path("test500/", TemplateView.as_view(template_name="500.html")>
]
How can I change this? So my first wagtail page is on root-url and not on root-url/home/
Thnx in advanced.
Edit: found this on the wagtail docs, but don’t know how to apply:
Note that there’s one small difference when not using the Wagtail project template: Wagtail creates an initial homepage of the basic type Page, which does not include any content fields beyond the title. You’ll probably want to replace this with your own HomePage class - when you do so, ensure that you set up a site record (under Settings / Sites in the Wagtail admin) to point to the new homepage.
Instead of trying to move your wagtail page to root-url, you should create (or update) the default site so its root_page should be the page currently shown at /home/

FieldPanel failed to be reflected on content_panels

I am integrating wagtail into my existing Django project.
before integration: file architecture is as below
|- MyProject/
__|- templates/
__|- manage.py
__|- MyProject/
____|- urls.py
____|- models.py
____|- settings.py
____|- views.py
After I installed wagtail packages and reflected that on settings.py, file architecture did not change. Now I can successfully log in to localhost/cms/.
Now I want to customize content_panel of CMS admin, hence I defined below class;
# MyProject/models.py
class HomePage(Page):
template = "homepage.html"
content = RichTextField()
content_panels = Page.content_panels + [
FieldPanel("content")
]
then I migrate database and restart web server, but I did not see any change on content_panels of CMS admin portal. why ?
As mentioned at https://docs.wagtail.io/en/stable/getting_started/integrating_into_django.html#start-developing - when you integrate Wagtail into an existing project (rather than using the wagtail start project template), the initial homepage created will be a basic Page type with no content fields. After you define a real HomePage class, you'll need to delete the initial page and create a HomePage type page in its place (along with creating a Site record under Settings -> Sites).

Loading Django static files from React component

I am fairly new to React/Django/web development in general. I know there are a lot of questions on SO about how to load static files in Django templates, but I couldn't find anything helpful on how to do this in React components.
Scenario: I am building a React-Django app, and one of the features is to render a PDF document based on some user input. I am able to render the pdf successfully with react-pdf if the file is stored somewhere in the react app's source tree.
However, I want to serve these pdf files from the backend. Currently, I have a Django model with a FilePathField that points to where these pdfs are on my filesystem. What is the best practice for using this file path to render the pdf in React? Also, is this approach even correct?
I made it work under development settings. Here are the steps that I followed
First, in the project-level urls.py, add staticfiles_urlpatterns to urlpatterns
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
path('admin/', admin.site.urls),
path('ml/', include('ml.urls'))
]
urlpatterns += staticfiles_urlpatterns()
Second, specify where your static files are in settings.py. In my case, I put all of these files in the project-level assets folder.
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'assets')
Finally, I just send the static URL as a response (e.g /static/assets/sample.pdf) to a react component that can render pdfs.
Would welcome any feedback in the comments. Thanks!

django rest + react js how can I access directly the url of react route?

My project has django-rest framework backend api server and reactjs frontend.
there is index.html of reactjs file in django static/file directory.
So, I can access the react page by the url "backend_url.com/static/index.html".
problem is I want to access the url of react router.
"backend_url.com/static/index.html/public/log-in-page/" like this. to go directly to react log-in page.
but, the server try to find "static/index.html/public/log-in-page/" directory. so It will fail.
Finally, what I want to develop is to go directly the specific react page and pass over parameters by the url.
how can I reach that?
You will have to configure your webserver so that it serves index.html regardless of the rest of the URL. Depending on your webserver, this will done one way or another.
However, if you are using Django, I suggest that you use Django views to render your page. You could be saving your React page as a template, and render the template from the view.
# urls.py
from django.urls import re_path
url_patterns = [
re_path(r'^/your/app/?.*', views.app)
]
# views.py
from django.shortcuts import render
def app(request):
return render(request, 'index.html')

Deploying Create React App to a subdirectory but make API calls to parent path

I'm deploying my Create React App to a specific path in a larger non-React webapp. For example, I will say the webapp path is www.example.com and the React app is deployed at www.example.com/react/
I have done this by setting the "homepage" property in package.json of the React app to "homepage": "/react", which does properly serve the static files from the /react/ path on my server.
However, when I make API calls from my react app, they go to /react/api/etc instead of /api/etc.
I can configure axios to use a hardcoded base path of www.example.com, but I deploy this to multiple environments with different URLs and need a solution that doesn't rely on a hardcoded value.
I could also write a workaround on the server side, but it would be less clean / mess with my logging and request statistics.
I would love a clean solution if one exists.
what if you used the window.location property in your axios config object:
{
baseURL: `${location.hostname}/api/` // or window.location.hostname
}

Resources