Django
There are 2 question about this topic, but both of them (this is one Absolute paths on images uploaded by django-ckeditor) are not updated. For example, in Django 4.X, url was removed. Despite this, I've tried these solutions, but no one worked for me.
I've also tried to use:
CKEDITOR_MEDIA_PREFIX on my settings.py
But it didn't work either.
This is my settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/'
CKEDITOR_UPLOAD_PATH = 'uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
This is my urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('api/news/', include('news.urls')),
re_path(r'^ckeditor/', include('ckeditor_uploader.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += [
re_path(r'^media/(?P<path>.*)$', serve, {
'document_root': settings.MEDIA_ROOT
}),
]
So here is my question, how can I set up my Django-rest-framework app in such way that I get the absolute path when I render the html on my next.js site?
This is what I get right now:
<img alt=\"\" src=\"/media/uploads/2022/01/19/video.svg\"/>
This is what I'd like to get:
<img alt=\"\" src=\"http://website.com/media/uploads/2022/01/19/video.svg\"
React
Is there any way to achieve these from the frontend? For example, updating all img's src
If you need a quick solution (I'm pretty sure this is not the "right" way of doing this), here is my approach:
As I only need to update the img.src in one JavaScript file, I did it using a hook to get all the images, filter only those ones that are stored in the server and update their src.
useEffect(()=>{
//! Don´t forget to update this
const imgDomain = 'https://...';
const imgStore = document.querySelectorAll("img[src]");
Object.keys(imgStore).map((x)=>{
if(imgStore[x].src.includes('uploads')){
const originalURL = imgStore[x].src;
var mediaPos = originalURL.indexOf('/media/');
var URLlength = originalURL.length;
var slicedSRC = originalURL.slice (mediaPos, URLlength);
var newSRC = imgDomain+slicedSRC;
imgStore[x].src = newSRC;
}
})
}, []);
Related
I'm confused about serving media files on django and react. Here is my code:
Here is my settings.py :
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'build/static'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('api-user/', include('landingpage.urls')),
path('', TemplateView.as_view(template_name='index.html'))
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Render it on react :
<img
src="/img/logo.jpeg" // is it true?
/>
I put my image on build/img folder. When i open with localhost 3000 it's rendered but when i open with localhost 8000, i get not found error with this image link http://127.0.0.1:8000/img/logo.jpeg
My question is :
Where to put images? Should i create media folder to store all my image or put it on build/image folder? How to specify the src link to image on in react?
Thanks.
In your original config Django looking the files in media dir, not in build/img dir
Change media files settings from
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
To
If you are storing images inside the build/img folder as you
mentioned in the comments then MEDIA_URL & MEDIA_ROOT should be
like
MEDIA_URL = "/img/" #edited
MEDIA_ROOT = os.path.join(BASE_DIR, 'build/img') #if the build dir is in root directory, if not then change it accordingly
Now you can use the access image files in This URL Pattern http://127.0.0.1:8000/img/logo.jpeg
Answering:
Put react images into public/static react project directory, so they will be moved to build/static and later served as other static files
In react there is something called PUBLIC_LINK. I recommend to read this answer
I can propose more general approach for react+django in production:
In settings.py create 3 varibles:
REACT_DIR – for your react project root
REACT_ROOT_URL_FILES – list of filenames to be served via root url (e.g. /favicon.png)
STATICFILES_DIRS – add directory where react created static files bundles
#settings.py
REACT_DIR = os.environ.get('REACT_DIR','/path/to/react/app/')
REACT_ROOT_URL_FILES = os.environ.get("REACT_ROOT_URL_FILES",'favicon.png manifest.json robots.txt').split(" ")
STATIC_URL = f'/{os.environ.get("STATIC_URL","static")}/'
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATICFILES_DIRS = [
#...
os.path.join(REACT_DIR,'build','static')
]
Then in views.py write view to handle react root dir files (of names from REACT_ROOT_URL_FILES) as also react index.html:
from django.views.generic import View
from django.http import HttpResponse,FileResponse
from django.conf import settings
import os
class ServeReactView(View):
def get(self,request):
try:
url = request.path.strip('/')
if url in settings.REACT_ROOT_URL_FILES:
#return one of the files named from the list
file_name = url
file = open(os.path.join(settings.REACT_DIR,'build',file_name),'rb')
return FileResponse(file)
with open(os.path.join(settings.REACT_DIR,'build','index.html')) as file:
#return react index.html
return HttpResponse(file.read())
except:
return HttpResponse(
"""
{} not found!
""".format(request.path),status=501)
And at the and add this view to urls.py:
#urls.py
urlpatterns = [
#...
re_path(r"^.*",ServeReactView.as_view(),name="serve_web_client_view")
]
P.S
When you're serving more common react files (images etc..) I think it's better to put them into public/static/ react project directory, so they will be moved to build/static and later served as other static files
I have a trouble with using django-rest-framework.
I uploaded some videos.
And I try to play that videos in react.
But I faced 404 error.
I added static and media root in setting.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
This is upload code.
videofile = request.FILES['videoData']
fs = FileSystemStorage()
filename = fs.save(videofile.name, videofile)
user = request.user
File.objects.create(
user = user,
title = request.data['videotitle'],
url = filename,
categorys = request.data['categories'],
preveimage = request.data['vidoePrevimg'],
filetype = request.data['videoType'],
filesize = request.data['videoSize']
)
It works fine
And in react I tried like this.
<ReactPlayer url={`${baseurl}/media/${videoDetaildata.url}`} playing={true} controls={true} playIcon={true}/>
This works when the url is Youtube url.
Please help me.
Thank you in advance.
During development you have also to append media url and static url to the urlpatterns.
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Kindly check the following Serving files uploaded by a user during development.
Make sure not to use the above example in production, check the following gist.
I wanna use react as frontend with django as backend
I tried
urlpatterns = [
path('api/',include('api.urls')),
path('admin/', admin.site.urls),
path('',include('frontend.urls')),
]
frontend is the app contains react
frontend app urls
urlpatterns = [
path('/',index)
]
def index(request):
return render(request,'frontend/index.html')
i wanna use index.html any other route
project/urls.py
urlpatterns = [
path('api/',include('api.urls')),
path('admin/', admin.site.urls),
path('', include('frontend.urls')), # This has to be the last item!
]
frontend/urls.py
#...
from django.urls import re_path
#...
urlpatterns = [
re_path(r".*", index) # RegExpr: any character is correct
]
Django routing and react routing don't have to mix. They are completely separate from each other. You get your API data from the django routes and then create you own routes on the front-end with react-router. Read this for some context: https://www.digitalocean.com/community/tutorials/build-a-to-do-application-using-django-and-react.
I have an ImageField in a django model
image = models.ImageField(upload_to='images')
My media root is set like so in settings.py
MEDIA_ROOT = '/art/'
But when I upload select a gif url for the Imagefield, the url does not save as /art/images
I get this error message in Django Admin when I upload the url for the gif "Barnie.gif", which is stored at art/images/Barnie.gif
Art with ID "1/change/images/Barnie_L2fAl.gif" doesn't exist. Perhaps it was deleted?
I had the same problem. I solved it by adding the following imports:
from django.conf import settings
from django.conf.urls.static import static
I also added the following urlpatterns:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I wanted to try to get away with not doing all the config stuff, but you do have to do that.
In my base app urls.py I added:
from django.conf import settings
from django.conf.urls.static import static
and at the end of the urls list I added:
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Then in my settings.py I added:
MEDIA_ROOT = os.path.join(BASE_DIR, '/art/images')
MEDIA_URL = '/images/'
I'm currently having an issue that has been driving me crazy for the past 30-40 mins. I've successfully created a products api using Django/Django REST framework. But when I call the endpoint to try and consume it with angular, I get a 404 error. When I open the console I am greeted with an error that states GET http://localhost:8000/static/api/products/ 404 (Not Found). However, when I navigate to the URL manually in browser I get the browsable api menu.
I'm not exactly sure what's going on here...but I'm thinking it could be because of my angular static URLs/roots.
Here is the current code for the main area URLs of the app:
from django.conf.urls import url,include
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include('customerreview_rest.urls', namespace='api')),
url(r'^api/',include ('products_rest.urls', namespace='api')),
url(r'^', include('GemStore_App.urls',namespace='frontend')),
] + static(settings.MEDIA_URL,document_root = settings.MEDIA_ROOT)
Here is the products URL/root for the endpoint:
from django.conf.urls import url,include
from rest_framework import routers
from products_rest.viewsets import ProductsViewsets
router = routers.DefaultRouter()
router.register('products',ProductsViewsets,'products')
urlpatterns = [
url(r'^', include(router.urls)) #base router
]
Lastly, here is the code for the static angular files:
from django.conf.urls import url, include
from django.views.generic.base import RedirectView
urlpatterns = [
url(r'^$', RedirectView.as_view(url='static/index.html', permanent=False), name='index')
]
Here also, is the code I planed to use to consume the api using Angular:
myStore.controller("myStoreController",function($scope,$http){
$scope.gems = $http.get("api/products/").then(
function(response){
$scope.gems = response.data
}, function(error){
$scope.error = error
});
})
Any light that can be shed on this topic, or maybe a point in the right direction would be greatly appreciated.
Thanks
Turns out that the issue was that I needed to include a another / in my call in order for it to be accepted.
So in summary, the code for the angular portian looks like this now:
myStore.controller("myStoreController",function($scope,$http){
$scope.gems = $http.get("/api/products/").then(
function(response){
$scope.gems = response.data
}, function(error){
$scope.error = error
});
})
#Sayse Thanks for helping.