Django upload file url problem - python

I've got this media root:MEDIA_ROOT = '/var/www/hosted/myapp/static/' and this media urlMEDIA_URL = '/static/res/' and I am trying to upload a file using a callable: def get_uploadto(instance, filename):
''' Dummy callable to silence the upload_to field of FileFields '''
return os.path.join('uploads', filename), it uploads the picture on the disk in /var/www/hosted/myapp/static/uploads/ just as planned, but in the admin it creates a link poiting to static/res/uploads, which does not exist. Does anyone know why? Of course, I can simply move the uploads dir within static res, but I am looking for a more elegant solution.

This is the expected behaviour. The files are in
MEDIA_ROOT + 'uploads' + filename
or
/var/www/hosted/myapp/static/uploads/filename
the URL's that point to those files are:
MEDIA_URL + 'uploads' + filename
or
/static/res/uploads/filename
You then need to make sure that your application or hosting environment points the URL to the on disk location. In the dev environment you would have something like this in your urlpatterns:
(r'^static/res/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.dirname(settings.MEDIA_ROOT)}),

Related

Django Rest app not using media root correctly to serve images

I have a project that has 3 apps, one named stores with store models, products with product models, and api which is the rest framework app that serves the Json results to clients. I set the media root in settings.py as MEDIA_ROOT = '/photos/' and the upload works for both product and store models. The main problem here is that for some reason the rest framework returns a url that references the api app instead of the products or stores apps for the media root url. here are my models
class Product(models.Model):
def get_image_path(instance, filename):
return '/Products/' + filename
picture = models.ImageField(width_field=None, max_length=100, blank =True, null =True)
store:
class Store(models.Model):
def __str__(self):
return self.name
def get_image_path(instance, filename):
return os.path.join('productphotos', 'stores', filename)
picture = models.ImageField(width_field=None, max_length=100, blank =True, null =True)
How do i set the mediaroot to the project directory instead so that all apps in the project reference it as mediaroot instead of themselves?
The upload works and upoads the pictures to the instructed directories in the root of the project (where manage.py is found), but the rest framework thinks it should get the media from the api app.. what's the proper way of doing this? here are screenshots:
the path uploaded to
the path returned in json
The MEDIA_URL setting is the URL path in the browser. The MEDIA_ROOT setting is the root directory on your server, and should be an absolute path.
MEDIA_URL = '/pictures/'
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploaded_pictures')
Also, if you want Product and Store pictures to go into different sub directories, for example pictures/products/ and pictures/store/, you'd need to set the upload_to argument on the model field. For example
picture = models.ImageField(upload_to='products/', ... )
Edit: To serve static and media files during development, add this at the end of the urls.py
if settings.DEBUG:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Where can I find the admin code for uploading an image in django?

I'm currently coding an image upload in a view and I want to compare it to the code the admin uses for uploading images. Is there code the admin generates the file forms from? Where can I find the python code to an admin image/file upload?
I'm using ubuntu 14, python 2.7 and django 1.9.
I have been searching around in here for the admin code for uploading files, but I cannot find it:
/usr/local/lib/python2.7/dist-packages/django/
This is my image upload code in my view I want to compare to the admin image upload code:
avatarFile=request.FILES["avatar_im"]
print(avatarFile)
for key, file in request.FILES.items():
path = file.name
path = "images/"+path
dest = open(path, 'w')
if file.multiple_chunks:
for a in file.chunks():
dest.write(a)
else:
dest.write(file.read())
dest.close()
I'm trying to understand how my admin uploads files to my
MEDIA_ROOT/images, and why my code uploads to my PROJECT_ROOT/images folder.
PROJECT_ROOT = os.path.normpath(os.path.dirname(__file__))
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'static_in_pro/media')
I think the code used for file uploading stays inside
django.core.files.storage.FileSystemStorage
and
django.core.files.move
If you want to upload files in the directory MEDIA_ROOT/images/ then just use:
import os
from django.conf import settings
...
...
path = os.path.join(settings.MEDIA_ROOT, 'images', file.name)

django get media directories in view or model

I have a model where I I am writing a function to upload files :
def get_upload_file_name(instance, filename):
return "my_files/{}".format(filename)
In my settings I have
MEDIA_ROOT = os.path.join(BASE_DIR, 'static')
My static structure
static
css
img
js
my_files
Here I dont want to return hardcoded my_files I want to return from setting like
{{MEDIA_ROOT}}/{}".format(filename)
or something like that...
How can I do this ?
To answer the question you actually asked, you can access your MEDIA_ROOT setting (and any other Django settings) in your views and models with:
settings.MEDIA_ROOT
As mentioned however, you probably want to read up on how media is handled in Django first.
Read about using settings in python code in the docs.
I figured it out!
You can access like this
modelName.fieldName.field.upload_to

Django serving dynamic Files

I have a problem about serving admin uploaded files in my templates.
I set:
MEDIA_URL='/media/'
MEDIA_ROOT = 'assets/'
and my models are like:
mainPhoto = models.ImageField(upload_to="articles/")
When in my templates, I try:
<img src="{{MEDIA_URL}}{{article.mainPhoto}}" />
The image doesn't show up on the website.
I found one deprecated solution with the django .serve(), but I hope to avoid using it.
I was looking everywhere and didn't find any answer, so I hope someone here will be able to help me.
There are two parts to make this work. First is the Django configuration. There are really two settings for this which you have already mentioned - MEDIA_URL and MEDIA_ROOT. As already noted in the comments the MEDIA_ROOT has to be an absolute path. For example:
MEDIA_ROOT = `/abs/path/to/project/media/`
Second part is actually serving the files. If you are in production, you NEVER want to serve your static or media files through Django so you should configure Apache or nginx or whatever server system you are using to serve the files instead of Django. If you are on the other hand still developing the app, there is a simple way to make Django serve media files. The idea is to modify your urls.py and use the Django's static files server to serve media files as well:
# urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# other patterns
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
More about this approach at Django docs.
Also FYI, you probably should not use {{MEDIA_URL}}{{article.mainPhoto}} to get the url of an image. This approach will break for example if you will no longer use file system storage for static files and will switch to something different like Amazon S3. It is always a good idea for the storage backend to figure out the url:
<img src="{{article.mainPhoto.url}}" />

Cannot load Images from Django ImageField in Template

I have a project developed with Django in which users have the ability to upload an image through a form in a view. That part seems to be working correctly in that I can bind the data to a form and save the image in a designated folder within the directory that I'm using for the project's database. However when I go to render a page, I get something similar to the following line (the uploaded image has the filename "2220.jpg"):
GET http://localhost:8000/Users/.../project/database/user_uploads/08-30/2220.jpg 404 (NOT FOUND)
Here's the line in my template that renders the image:
<img class="image" src="{{ entry.image.url }}"/>
The relevant parts of my settings.py:
PROJECT_DIR = os.getcwd()
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'database', 'user_uploads')
MEDIA_URL = ''
STATIC_ROOT = ''
STATIC_URL = '/static/'
The model containing the image:
def getImagePath(instance, filename):
"""Generates a path to save the file. These are timestamped by the
current date and stored in the databases directory.
Returns:
Path for the file.
"""
date = datetime.date.today().strftime('%Y-%m-%d')
return os.path.join(
os.getcwd(), 'database', 'user_uploads', date, filename)
class Entry(models.Model):
# Other code omitted
image = models.ImageField(upload_to=getImagePath)
I'm guessing there's some URL configuration I'm missing because it seems like it's asking for the image to be served via localhost (or more generally my host name) rather than just a directory on the filesystem. The file location is correct, it just seems to be executing an HTTP request for it instead of just getting it directly. What am I missing? I'm happy to provide any additional information for clarity.
Thank you in advance!
you have to setup media serving.
https://docs.djangoproject.com/en/dev/howto/static-files/#serving-files-uploaded-by-a-user
In addition to montiniz's answer, the following thread helped me out:
Django MEDIA_URL and MEDIA_ROOT
Basically what I was missing was the URL configuration for serving files from MEDIA_ROOT. One other thing is that calling the url() parameter on a Django ImageField returns the fully qualified URL name - that is, the file's full location. All you need to serve the image from the template is its location within MEDIA_ROOT. In my case, this setting was 'database/user_uploads' and the image was located at '2013-09-02/images/2220.jpg'.
Therefore the url I needed was:
'localhost:8080/media/database/user_uploads/2013-09-02/images/2220.jpg'.
Hope this helps anyone with the same issue!

Categories