I'm trying to create Django REST app, however I cannot manage to allow the url of the image to be accessible.
I managed to get the upload done, however when I have the URL there is no way to access the photo from browser. I stored them in folder profile_pictures and I was thinking of loading the image from localhost:8000/profile_pictures/image_name.jpg but I'm not sure how to setup this, as I tried linking static files to the urls but nothing seems to work.
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_URL = '/profile_pictures/'
MEDIA_ROOT = os.path.join(BASE_DIR,"profile_pictures")
urls.py
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
However, it says that the static name is not defined even tho I import it using:
from django.conf import settings
from django.conf.urls.static import static
I upload the images with Simple REST API which I only created for testing:
class UploadPictureAPI(generics.GenericAPIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
x = AdditionalUser(user=request.user, profile_picture=request.data['profile_picture'])
x.save()
print(x)
return Response({"message": "uploaded"})
and I store them in a database as such:
class AdditionalUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile_picture = models.ImageField(upload_to='profile_pictures')
user_bio = models.CharField(max_length=300)
user_instagram = models.CharField(max_length=300)
They get uploaded to the DataBase and in the folder, but I cannot get access to them from the url(which I get as profile_picture.url) of the database, it says page not found
Related
I have been looking on the internet all over the place for this
and it seems that everything is in check, also media images are very well displayed
so I have a django web app that has a FileField where you can upload pdfs and now I am trying to display thouse pdfs but they get displayed with the error as the image below shows.
settings.py
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
X_FRAME_OPTIONS = 'SAMEORIGIN'
show_pdf.html
<iframe
src="{{pdf.url}}"
frameBorder="0"
scrolling="auto"
height="1200px"
width="1200px"
></iframe>
models.py
class File_pdf(models.Model):
title = models.CharField(max_length=50)
pdf = models.FileField(upload_to='portfolio/pdfs')
main_resume = models.BooleanField(default=False,help_text="set only one pdf as the main pdf for the main page")
def __str__(self):
return self.title
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('portfolio.urls')),
path('blog/',include('blog.urls'))
]
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
views.py
def pdf_view(request,pdf_id,resume):
dic = {}
if resume == "yes":
pdf_files = File_pdf.objects.filter(main_resume=True)
pdf_file = pdf_files[0]
dic['pdf'] = pdf_file.pdf
dic['title'] = pdf_file.title
else:
pdf_files = get_object_or_404(File_pdf,pk=pdf_id)
pdf_file = pdf_files[0]
dic['pdf'] = pdf_file.pdf
dic['title'] = pdf_file.title
The error looks like this:
this is actually the correct link
In your settings.py add the following code:
X_FRAME_OPTIONS = 'ALLOW-FROM <your localhost URL>'
for example
X_FRAME_OPTIONS = 'ALLOW-FROM http://127.0.0.1:8000/'
it turns out that everything was correct but the brave cache somehow was in conflict with the X_FRAME_OPTIONS updating itself. so after deleting brave's cache it was enough :)
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
I have a ImageField in my user_accounts/models.py file which i use to store the profile picture of users.It has a upload_to field which calls a function and uploads the file to a media folder in myproj/media/.. . The Image Field also has a default field which is used to set the default profile image from the static folder.
This is an entry of User Table in development server.
In The image the avatar field shows static url but when clicked it /media/ gets attached to the url before /static/ as follows:
In The image the url bar shows /media/ attached before the static url.When i manually remove the /media/ from the url the defaultProfileImage is shown.
This is my project structure
|-myproj
|-myproj
|-__init__.py
|-settings.py
|-urls.py
|-wsgi.py
|-static
|-user_accounts
|-images
|-defaultrofileImage.png
|-user_accounts
|-__init__.py
|-models.py
|-admin.py
|-tests.py
|-views.py
|-urls.py
Models.py File
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import AbstractUser
def get_upload_url(instance , filename):
return 'userProfileImages/%s/%s'%(instance.username , filename)
class User(AbstractUser):
mobileNumber = models.IntegerField(blank = True , null = True)
avatar = models.ImageField(upload_to = get_upload_url , default = '/static/user_accounts/images/defaultProfileImage.png')
def __str__(self):
return self.username
I have the following lines added in my settings.py file
AUTH_USER_MODEL = 'user_accounts.User'
STATIC_URL = '/static/'
STATICFILES_DIRS =[
os.path.join(BASE_DIR,'static'),
]
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
This is my urls.py file
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-auth/', include('rest_framework.urls')),
url(r'^user/',include('user_accounts.urls')),
] + static(settings.MEDIA_URL , document_root = settings.MEDIA_ROOT)
How should i correct the url so that when i click the url in my admin panel it shows the correct url in url bar and i get to see the defaultProfileImage??
ImageField default value refers to 'MEDIA_URL', therefore you should create media folder, place your defaultProfileImage there and use default = 'defaultProfileImage.png' in the model field, as in your example it resolves the picture path as MEDIA_URL + default so you get /media/static/....
You probably could omit default= from the model field and override save method to programmatically define the path to the avatar field.
Usually, user-uploaded media files reside in the MEDIA_ROOT and static assets in STATIC_DIRS.
You can find more info here and read about FileField which is the base class of ImageField here.
I'm trying to use Django 2.0. I'm using the development 'runserver' right now, so please keep in mind that I'm not in production yet. I am familiar with the differences between the two with regard to static files.
I have a Blog Post model. In the admin, I want to be able to add an image to my model using ImageField. I'd like it to be optional, and provide a default image if none is added.
I am able to load images in admin. I am unable to render my image in my template. The console shows that Django is trying to GET my image, but my configurations have not worked so far.
Here's my model and relevant field:
from PIL import Image
class Post(models.Model):
....
thumbnail = models.ImageField(default='/img/default.png', upload_to='img', blank=True, null=True)
....
My model works well aside from the ImageField. My View works well, and I don't think there is any issue there.
Here is my urls.py
....
from django.conf.urls.static import static
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from . import views
urlpatterns = [
....
path('posts/', views.PostListView.as_view(), name='post_list'),
path('post/<int:pk>/', views.PostDetailView.as_view(), name='post_detail'),
path('post/random/', views.random_post, name='random_post'),
]
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I'm not at all sure about how to handle static files vs. media files in my urls.py, especially with changes to Django in version 2.0.
Here's my relevant settings.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
TEMPLATES = [
{
...
'OPTIONS': {
'context_processors': [
....
'django.contrib.messages.context_processors.media',
....
]
},
},
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/')
MEDIA_URL = '/media/'
I am equally unsure of what to put in my settings.py concerning media. My static CSS files are working just fine. I have a logo image in my static files that is rendering in my base template.
Here is my template tag for the ImageField:
<img class="card-image mr-3" src="{{ post.thumbnail.url }}" alt="Generic placeholder image">
Lastly, my /static folder and my /media folder are in the same directory. These are both in my app directory, /blog.
Can anyone see any blaring errors here, or can they make suggestions? My issue is the default image is not loading. The default image IS in the correct directory /media/img/. The console warning says "Not Found: /media/img/default.png".
Thanks in advance. Any suggestions will be helpful.
Django ImageField for Admin Panel
There is important thing you have to define your MEDIA_URL in urls.py.
Without this definition framework doesn't gives to you permission to access image
Setting.py
MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
urls.py
if settings.DEBUG: # new
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Models.py
class Product(models.Model):
title = models.CharField(max_length=150)
image=models.ImageField(blank=True,upload_to='images/')
def __str__(self):
return self.title
def image_tag(self):
return mark_safe('<img src="{}" height="50"/>'.format(self.image.url))
image_tag.short_description = 'Image'
Admin.py
class ProductAdmin(admin.ModelAdmin):
list_display = ['title','image_tag']
readonly_fields = ('image_tag',)
Printing the media root helped me solve this issue. Thanks Alasdair.
I don't think there was any issue with my model field above.
The urls.py code that I ended up using is directly from Django docs for Django 2.0 in handling static files https://docs.djangoproject.com/en/2.0/howto/static-files/.
The changes I made to Settings were done thanks to printing my MEDIA_ROOT in the console. I changed the syntax and the direction of a slash (blog\media). I also deleted the context processor shown above in my TEMPLATES options.
Here's what works for me:
models.py
thumbnail = models.ImageField(default='img/default.png', upload_to='img', blank=True, null=True)
urls.py
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [...] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'blog\media')
MEDIA_URL = '/media/'
print(MEDIA_ROOT)
Template tag
<img class="card-image mr-3" src="{{ post.thumbnail.url }}" alt="Generic placeholder image">
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.