upload via admin using FileField in django - django

I have something very weird. I am on win7 Django 1.4.
I have the following media_root/url settings :
MEDIA_ROOT = 'c:\project\uploads'
MEDIA_URL = '/media/'
My url.py includes :
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))
I have a model with the the field :
file = models.FileField(upload_to=MEDIA_ROOT, blank = True)
Now, I am uploading the file via the admin site, the file is uploaded successfully. however , the when accessing the file via the admin I see the link to the file is :
http://127.0.0.1:8000/media/c:\project\uploads\[filename]
I have no clue what I am doing wrong.

I think your model is wrong:
file = models.FileField(upload_to=MEDIA_ROOT, blank = True)
upload_to expects a relative path which is added to the MEDIA_ROOT, so now it expects the file to be at MEDIA_ROOT/MEDIA_ROOT which makes no sense.
Try something like:
file = models.FileField(upload_to='files', blank = True)
docs:
FileField.upload_to A local filesystem path that will be appended to
your MEDIA_ROOT setting to determine the value of the url attribute.

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 Admin FileFile not open from listview

in my model class i have an attribute like this one:
c_cv = models.FileField(upload_to='mysite/static/docs', max_length=254, validators=[FileExtensionValidator(['pdf']),validate_fsize], verbose_name="CV")
in my admin.py:
list_display = ('c_data', 'c_sur', 'c_name', 'c_dob', 'c_en', 'c_de', 'c_cv')
but when i open from admin my list page, if i click on my c_cv field in list i get an error because link does not start from 127.0.0.1:8000/mysite/static/docs/file.pdf but instead from 127.0.0.1:8000/admin/cv_list/...
How can i force in admin looking my c_cv field using root of domain instad actual path as prefix?
So many thanks in advance
Have you defined a URL for viewing media ? What have you set your MEDIA_URL , MEDIA_ROOT to in the settings.py ?
I have done something like this to access uploaded files:
1.In settings.py :
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
2.Defined a url which is used to serve uploaded media files :
In urls.py:
#login_required
def protected_serve(request, path, document_root=None, show_indexes=False):
return serve(request, path, document_root, show_indexes)
re_path(r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], protected_serve, {'document_root': settings.MEDIA_ROOT}),
This way I can also stop directory indexing of the list of the files that are uploaded.You can try this

FileNotFoundError for the media folder after deploying Django app on Apache

I have a Django app that I just added to the already deployed Django web on Apache.
Because it is ran by Apache, path of the media folder seems to be different.
My app lets the user upload an excel file which then changes numbers and save as csv file.
(only showed relevant folders/code snippets)
Current directory
converts\
_init_.py
apps.py
forms.py
models.py
converter.py
urls.py
views.py
main\
settings.py
urls.py
wsgi.py
meida\
excels\
example.xlsx
csvs\
example.csv
static\
manage.py
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
main\urls.py
urlpatterns = [
path('', RedirectView.as_view(url='/converts/')),
path('converts/', include('converts.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The part that causes the problem is the following in converts/converter.py:
def convertExcel(name):
path = 'media/excels/'
key = path + name
wb = load_workbook(key)
Originally in development, a function in view calls convertExcel(example.xlsx) and the workbook, via media/excels/example.xlsx, finds the correct file to work with the loaded workbook. But in production server, it gives
FileNotFoundError: [Errno 2] No such file or directory: 'media/excels/example.xlsx'
My Question is:
Do I have to back track from where apache2.conf is to find the path? Or is there a way to set path to my django project so i can just set path in my convertExcel() as 'media/excels'? Or is there any other way I can call the uploaded workbook?
Any kind of help/comment would be appreciated.
Please comment if additional information is needed.
My guess is that you should use MEDIA_ROOT variable because it points to the uploaded files. So you would have
def convertExcel(name):
from django.conf import settings
path = os.path.join(settings.MEDIA_ROOT, 'excels')
key = os.path.join(path, name)
wb = load_workbook(key)

MEDIA_URL Page 404 Error Django

I am running on a local server and when I go to http://127.0.0.1:8000/media/ in my browser it says page not found.
Settings:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
Root URL:
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^polls/', include('mysite.polls.urls')),
url(r'^admin/', admin.site.urls),
url(r'^submit/', include('mysite.uploads.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Model for User Upload:
from django.db import models
class Document(models.Model):
description = models.CharField(max_length=255, blank=True)
document = models.FileField(upload_to='documents/')
uploaded_at = models.DateTimeField(auto_now_add=True)
Following the Django documentation:
Serving files uploaded by a user during development
During development, you can serve user-uploaded media files from MEDIA_ROOT using the django.contrib.staticfiles.views.serve() view.
This is not suitable for production use! For some common deployment strategies, see Deploying static files.
For example, if your MEDIA_URL is defined as /media/, you can do this by adding the following snippet to your urls.py:
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)
https://docs.djangoproject.com/en/1.10/howto/static-files/
As pointed above in the comments by Alasdair, This is the normal behaviour of Django. If you visit the full file path like 127.0.0.1/media/file.jpg, Django will render the file instead of raising a 404 error.
Why is this happening?
If you look at the source of the view that serves the media/static files, you'll find these lines:
if os.path.isdir(fullpath):
if show_indexes:
return directory_index(newpath, fullpath)
raise Http404(_("Directory indexes are not allowed here."))
What it does is, it checks if the path requested is a directory or not. If yes, then it checks if the variable show_indexes is True, then it will return the index of the files inside the media directory. Since, show_indexes is False by default, it raises 404.
To set show_indexes to True, you can do this:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT, show_indexes=True)
This won't raise the 404 and will display a list of files inside media dir.
P.S.: I don't think displaying file indices is a good idea, unless, of course, that's something you really want. It puts server under extra load to generate the indices. And someone can download the files recursively using a program like wget etc. Even those files that are meant to be private.

Django - uploading static image as default ImageField file

This is my models.py:
def get_profileImage_file_path(instance, filename):
return os.path.join('%s/uploadedPhotos/profileImages' % instance.user_id, filename)
class UserExtended(models.Model):
user = models.OneToOneField(User)
profileImage = models.ImageField(upload_to=get_profileImage_file_path, default='/static/images/myProfileIcon.png')
Now, I want the default image (which is in my static folder) to save to the path given in the
get_profileImage_file_path
function. In my settings.py, I have defined media_root and media_URL as:
MEDIA_ROOT = '/home/username/Documents/aSa/userPhotos'
MEDIA_URL = '/media/'
For some reason, when I pass the user object in the template and in the template, if I do:
<img class='profilePic' src="{{ user.userextended.profileImage.url }}" height='120px' alt="" />
No image shows up and when I open up the 'inspect element' section in chrome, it gives a 404 error saying:
GET http://127.0.0.1:8000/home/username/Documents/djcode/aS/aSa/static/images/myProfileIcon.png 404 (NOT FOUND)
even though that is the correct file path to the image. (I'm also not sure why it's giving the entire file path, isn't it just supposed to start from /static/? Even when I 'view source', the entire url is there.) How do I make it so that the default image which is located in the static folder uploads to the path provided in the
get_profileImage_file_path
function?
In general we use the config as follows for media :
BASE_DIR = dirname(dirname(abspath(__file__)))
MEDIA_ROOT_DIR = 'media'
MEDIA_ROOT = normpath(join(BASE_DIR, MEDIA_ROOT_DIR))
MEDIA_URL = '/media/'
For, development purposes set :
DEBUG = True
And in urls.py add the following :
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Upload the image again and validate the Image, it should work now.