Incorrect URL to file in Django admin - django

I'm getting the wrong URL to files that have been uploaded to the media-folder in the Django admin.
The URL for the file is:
/media/Users/hammer/Dev/*****/media/attachments/2018/09/12/pdf-test.pdf
But the correct URL to the file is:
/media/attachments/2018/09/12/pdf-test.pdf
It seems like MEDIA_ROOT (/Users/hammer/Dev/*****/media/) is (incorrectly, I guess) added after the first /media/ in the URL.
MEDIA_URL is:
MEDIA_URL = '/media/'
MEDIA_ROOT is:
MEDIA_ROOT = settings.BASE_DIR + '/media/'
The definition of the file-field for the model is:
file = models.FileField(upload_to=settings.MEDIA_ROOT + "attachments/%Y/%m/%d/", null=True)
The incorrect URL for the file-field is appearing on the change-page for the model for the file field.
Any ideas on how to fix this?

You shouldn't include MEDIA_ROOT specifically in your upload_to parameter. See the documentation:
If you are using the default FileSystemStorage, the string value will be appended to your MEDIA_ROOT path to form the location on the local filesystem where uploaded files will be stored.
So, just remove that:
file = models.FileField(upload_to="attachments/%Y/%m/%d/", null=True)
You'll need to recreate the instances with the incorrect value in the db, though.

Related

Page 404 error on clicking at the image link in django admins site

We have a django project in which we are storing images in the backend using image field.The image link is being stored on django admin site.However ,when I click on the link ,I get an error page.Here's my code.
models.py
images=models.ImageField(upload_to=upload_to,null=True)
def upload_to(instance, filename):
return 'images/{filename}'.format(filename=filename)
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('app/',include('firstapp.urls')),
path('',include('firstapp.api.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'media')
# URL used to access the media
MEDIA_URL = '/media/'
I have created a folder named media but the images are not being stored there.Please help.
You can try this way:
MEDIA_ROOT=os.path.join(BASE_DIR,'media') #Just add like this
Do pass directly to field instead of creating function of uploat_to.
images=models.ImageField(upload_to="images/",null=True)
Do above things and see if it solves.
Do reply if it is not solved.
From Python Doc. os.path.dirname(...)
Return the directory name of pathname path. This is the first element
of the pair returned by passing path to the function split().
os.path.join() takes first argument as full path becouse of this your MEDIA_ROOT is giving wrong path.
If you're using Django>=3.0 version then you can use pathlib like this
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'

Django wrong imagefield.path

i have a model with an image field like this
app_icon = models.ImageField(upload_to='icons/')
the project has 'uploads' as media folder, which has subfolders, including 'icons'.
The image is correctly uploaded to the 'icons' subfolder but when i try to access it using self.app_icon.path it returns .../uploads/imagename.jpg instead of .../uploads/icons/imagename.jpg so i get file not found error. Even the url doesn't include the 'icons' subfolder
my settings:
MEDIA_URL = '/uploads/'
MEDIA_ROOT = BASE_DIR / 'uploads/'
i can't find any answer to this problem, which seems so random to me.

Django turns absolute filepaths into relative, forcing the server to be run from the project folder

I'm trying to create a website where you can add images to models, which will then be in turn loaded on the homepage. However, I've noticed that when I run my server, it tries to get images from my /home folder.
Here's my models.py:
image_directory = join(settings.STATICFILES_DIRS[0], "website/images")
class Item(models.Model):
image = models.FilePathField(path=image_directory, recursive=True)
Here's my home.html (I'm just abbreviating it, item is passed in OK:
<img src="{{ item.image }}">
I run the migrations and run the server, and I'm able to select the image in /admin. The images look like: "sub_img_folder/img.jpg"
Then I go to /home and I get the following errors:
Not Found: /home/...absolute-path-to-project.../static/website/images/sub_img_folder/img.jpg
Not Found: /home/static/website/images/sub_img_folder/img.jpg
Any help would really be appreciated.
EDIT: Here's some of my settings.py contents.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
...
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
...
MEDIA_ROOT = os.path.join(BASE_DIR + "/static/website/")
MEDIA_URL = "images/"
EDIT 2: Just to clarify, the images you add to models are already on the server. You just need to clarify which image in the admin page, hence FilePathField instead of FileField. It somehow doesn't find the image when trying to load it on the home page but it successfully shows and selects in the admin page.
EDIT:
Since you are using a FilePathField, it only stores the path on disk, not the URL. The solution would be to use the MEDIA_URL in your template to formulate the URI string, something like this:
<img src="{{ MEDIA_URL }}/{{ FILE_NAME}}">
Where MEDIA_URL is your Media URL from settings.py and FILE_NAME is the name of the file itself.
It may be better to use an actual ImageField or FileField which stores all the information you need, or just have a CharField with the file name and build the URL like above.
PREVIOUS ANSWER:
Try adding the MEDIA elements to your Django settings.py. MEDIA_ROOT and MEDIA_URL tell Django how to handle user uploaded files:
In your settings.py:
MEDIA_ROOT = "/path/to/media/folder"
MEDIA_URL = '/media/'
In your urls.py:
urlpatterns = [
.......
] += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Documentation:
https://docs.djangoproject.com/en/3.0/ref/settings/#media-root

Failing to show images in templates Django

I have problems showing images in my Django templates (I'm uploading the images from the admin application). I read the documentation and other posts about the upload_to and still couldn't figure it out. I tried this <img src="{{ a.image}}"/> in my template and then this <img src="{{MEDIA_URL}}{{ a.image}}"/> and same results. Here is my settings.py code :
MEDIA_ROOT = '/home/mohamed/code/eclipse workspace/skempi0/media'
MEDIA_URL = '/media/'
and finally, I tried the following in my models.py and I failed miserably:
image = models.ImageField(upload_to = "ads/")
image = models.ImageField(upload_to = ".")
and when I used image = models.ImageField(upload_to = MEDIA_URL) I got the following error
SuspiciousOperation at /admin/advertisments/banner/add/
Attempted access to '/media/cut.jpg' denied.
EDIT
Generated links are as follows :
<img src="./DSCN6671.JPG">
RE-EDIT
Here is my view:
def index(request):
spotlightAlbum = Album.objects.filter(spotlight = True)
spotlightSong = Song.objects.filter(spotlight = True).order_by('numberOfPlays')
homepage = Song.objects.filter(homepage = True).order_by('numberOfPlays')
ads = Banner.objects.all()
copyright = CopyrightPage.objects.get()
try:
user = User.objects.get(userSlug = "mohamed-turki")
playlists = UserPlaylist.objects.filter(owner = user.userFacebookId)
purchase = Purchase.objects.filter(userName = user.userFacebookId)
user.loginState = 1
user.save()
except:
user = None
playlists = None
context = {'copyright':copyright, 'ads':ads, 'spotlightSong':spotlightSong,'spotlightAlbum': spotlightAlbum, 'homepage':homepage, 'user':user, 'playlists':playlists, 'purchase':purchase }
return render_to_response('index.html',context,context_instance = RequestContext(request))
Could anybody tell me what am I doing wrong??
P.S I'm using Django 1.4
The path you provide in upload_to will be a relative path from the MEDIA_ROOT you set in your project's settings file (typically settings.py).
Your MEDIA_ROOT is where your uploaded media will be stored on disk while the MEDIA_URL is the URL from which Django will serve them.
So if your MEDIA_ROOT is /home/mohamed/code/eclipse workspace/skempi0/media and your model's image attribute is:
image = models.ImageField(upload_to = "ads/")
Then the final home on disk of your uploaded image will be /home/mohamed/code/eclipse workspace/skempi0/media/ads/whatever-you-named-your-file.ext and the URL it will be served from is /media/ads/whatever-you-named-your-file.ext
Setting your upload path to be settings.MEDIA_URL won't work because that's where the media is served FROM not where it is allowed to be stored on disk.
If you want to load your uploaded image in your templates just do this (replace whatever with the name of the variable sent from the view to the template that represents this object):
<img src="{{ whatever.image.url }}"/>
The image attribute on your model isn't actually an image, it's a Python class that represents an image. One of the methods on that ImageField class is .url() which constructs the path to the URL of the image taking into account how you set your MEDIA_URL in your project's settings. So the snippet above will generate HTML like this:
<img src="/media/ads/whatever-you-named-your-file.ext"/>
RequestContext() and settings.TEMPLATE_CONTEXT_PROCESSORS
Since the render_to_response() you are returning from your view is utilizing RequestContext() you need to make sure you have settings.TEMPLATE_CONTEXT_PROCESSORS set correctly. Check out the 1.4 docs for further clarification.
upload_to needs to be an absolute path to the directory, not the web url. So try this:
image = models.ImageField(upload_to = settings.MEDIA_ROOT)
in your templates, just use
<img src="{{ a.image.url }}">
First, I suggest to change the MEDIA_ROOT to be
MEDIA_ROOT = os.path.join(PROJECT_ROOT,'media')
this way you ensure the media directory path is right under your project root. Your MEDIA_URL is set up correctly, but it is not used when uploading a file. MEDIA_ROOT is.
Regarding the file upload, in your model set the field to be
image_field = models.ImageField('Image', upload_to='images/some_sub_folder')
Note that I didn't use neither a leading nor trailing forward slashes. The above will upload the image to PROJECT_ROOT/media/images/some_sub_folder/ with the filename and extension of the original file. Alternatively, you can alter the filename by using a callable - upload_to=filename_convetion - more info here.
In your template, you can access the image using
<img src="/media/{{ your_model.image_field }}" />
Hope this helps, cheers.
I know this question is old but I had the same problem and this solved in my case:
settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
PROJECT_DIR = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media")
MEDIA_URL = '/media/'
urls.py
Then, my urls.py was missing this line of code to discover the /media/ folder and show the content:
urlpatterns += staticfiles_urlpatterns()
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}, name="media_url"),
) + urlpatterns
Hope it can help someone.

Django FileField url not relative

I have something like:
MEDIA_ROOT = '/home/httpd/foo/media/'
MEDIA_URL = 'http://www.example.org/media/'
(...)
file = models.FileField(upload_to='test')
When I create an object with that field in the admin page Django stores in the DB the full file path, like: "/home/httpd/foo/media/test/myfile.pdf". This is contrary to what says in the docs.
All that will be stored in your
database is a path to the file
(relative to MEDIA_ROOT).
When I use the file.url in a template I get something like:
http://www.example.org/home/httpd/foo/media/test/myfile.pdf
instead of what I would like:
http://www.example.org/media/test/myfile.pdf
What am I doing wrong?
I just did a sample FileField in one of my projects and it seemed to work as you are expecting. Here are a couple things to try.
Try making your settings like the following. I know they say it is bad to not end your MEDIA_URL with a / but this is how I do it and I like it better. You just have to remember whenever you use MEDIA_URL in a template to follow it with a slash: href="{{ MEDIA_URL }}/path/to/file"
MEDIA_ROOT = '/home/httpd/foo/media'
MEDIA_URL = '/media'
If that doesn't help anything, create a new simplified model with a FileField nothing customized and see if you are still getting the same problem.