How to display images from an ImageField in Django? - django

Before I explain, I have a question. I am making a blog and the posts have a heading image. I upload this image using admin when I create a post for my blog. Is this image 'static' or 'media'?
Anyway, I have my project set up as follows:
mysite is my project, blog is my app. I have a folder named static inside blog. Inside this static folder are four more folders- css, images, fonts, js.
In settings.py, I have this set up:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
My models.py looks like this:
class Post(models.Model):
...
header_image = models.ImageField('article_header_image', upload_to = 'blog/static/images/articleimages')
Now when I try to load this image in a template, it doesn't show up.
I am doing this the following way:
{% for post in posts %}
<img src="{{post.header_image.url}}">
{% endfor %}
Another thing, how can I use the upload_to argument to upload images into the app's static folder without explicitly stating it? I think thats where the issue is. If I use upload_to = 'static/images/articleimages', a new static folder is created in the mysite folder containing manage.py.
Any help is greatly appreciated!

You can import the STATIC_ROOT from settings file, and use that to biuld the path. In addition to that, you can use a callable, and build path there instead:
import os.path
from django.conf import settings
def generate_upload_path(instance, filename):
return os.path.join(settings.STATIC_ROOT, 'images/articleimages/')
class Post(models.Model):
...
header_image = models.ImageField('article_header_image', upload_to = generate_upload_path)
Ok, if you want to upload images to static directory of your app, you can use __path__ attribute of your app:
import blog
def generate_upload_path(instance, filename):
return os.path.join(blog.__path__, 'static/images/articleimages/')

Related

Why cannot I see the image file in django?

I tried to load an image file, but it didn't work. I uploaded the image file by admin. Thanks for the help!
here is my code
in urls.py
path('main/archive/<int:video_id>/', views.loadphoto, name='loadphoto'),
in views.py
def loadphoto(request, video_id):
target_img=get_object_or_404(Record, pk=video_id)
context={'target_img':target_img.picture}
in models.py
class Record(models.Model):
record_text = models.CharField(max_length=50)
pub_date = models.DateTimeField('date published')
picture=models.ImageField(blank=True)
def __str__(self):
return self.record_text
in img.html
<img src="target_img">
Main
First You Need To Join Your Media directory to your app
Here is the Way You Can Do That:
First You Need To Add This in Your Setting.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASEDIR,'your folder directory')
#for example app/media or something
Then You Need To Create Media Url Here is The Way:
Then You Need To Add in your urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('main/archive/<int:video_id>/', views.loadphoto,name='loadphoto'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Then You Need To Add This in Your Html File
<img src='{{ target_img.url }}'>
You Can See More Details Here:
https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.fields.files.FieldFile.url
ImageField is derived from FileField. In order to display the image in your template, you should provide its url, see https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.fields.files.FieldFile.url
The source attribute should instead by populated as follow:
<img src="target_img.url">

Django MEDIA_ROOT, MEDIA_URL etc

This is my first time using MEDIA_ROOT/MEDIA_URL and I'm a little confused by the configuration. I have an image upload form which saves the original image plus a resized copy. I want to save both images to my MEDIA folder, but separate them. Current structure:
project/
----apps/
--------appOne/
------------static/
------------templates/
------------__init__.py
------------models.py
------------urls.py
------------views.py
--------__init__.py/
----MEDIA/
----project/
--------__init__.py
--------settings.py
--------urls.py
----manage.py
I would like to save the original uploaded image to MEDIA/ and the resized image to a folder inside the MEDIA folder, like MEDIA/media/. Right now, it's nesting 3 times:
original image goes to ---> MEDIA/media/
resized image goes to ---> MEDIA/media/media
I'm almost positive I have my settings wrong but I've been fiddling with it for too long and nothing is working. It seems every tutorial configures things differently and I'm just not sure what the preferred structure is or why my current config isn't working the way I expect.
Here is my settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR,'MEDIA')
MEDIA_URL = "media/"
models.py:
from django.conf import settings
from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor
class Image(models.Model):
client = models.ForeignKey(Client, null=True, blank=True)
model_pic = fields.ImageField(upload_to=settings.MEDIA_URL, dependencies=[
FileDependency(processor=ImageProcessor(
format='PNG', scale={'max_width': 500, 'max_height': 500}))
])
views.py:
def upload(request):
form = ImageUploadForm(request.POST, request.FILES)
if form.is_valid():
client = Client.objects.get(id=request.session['id'])
image = Image.objects.create(client=client, model_pic=form.cleaned_data['image'])
return redirect(reverse('cphh:gallery'))
def show_images(request):
context = {
'images': Image.objects.all().order_by('-created_at'),
'media_url': settings.MEDIA_URL,
}
return render(request,'cphh/gallery.html', context)
The triple-nested uploaded images do render properly on my template:
{% for image in images %}
<img class="gallery-image" src="{{media_url}}{{ image.model_pic }}"
{% endfor %}
As per the documentation
MEDIA_ROOT is the Absolute filesystem path to the directory that will hold user-uploaded files.
Your code that pushes the uploaded Images to the root should have settings.MEDIA_ROOT/<sub-folder> instead of settings.MEDIA_URL
MEDIA_URL on the other hand is a placeholder for the url a client should hit to access your media. This is useful when you don't want to keep your media on your local filesystem, but to an external storage like amazon s3.
Using {{MEDIA_URL}} in your templates gives you a good way of not hard-coding the eventual media location.
first of all in the settings.py MEDIA_URL must be like this:
MEDIA_URL = "/media/"
Then delete MEDIA folder. Only media folder is enough.
and also if you need thumbnails for your uploaded images you can use Django easy_thumbnails package for this

Django - ImageField, upload, store and serve image in development server

I'd like to have an ImageField in the admin form for my model (say, for an individual's profile). And I'd like to display this image in a view later on.
This is the model I have :
class Individual(models.Model):
ind_name = models.CharField(max_length=100)
ind_photo = models.ImageField(default="default.jpg")
def __str__(self):
return self.ind_name
This is what I have in the settings for my website :
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_URL = '/static/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,"static/media")
These are the urls of my app:
urlpatterns = [
url(r'^$', views.index, name="index")
]
I know how to use static files (e.g. CSS, Javascript), and to get them to work in both development and production.
But I have no clue how to get images to work. I've read Managing static files and Deploying static files, but I still don't get it.
With the code above the image gets saved in the proper folder (i.e. /static/media at the level of my site). But I have no clue :
1) how to display it in a template,
2) whether it would be best to keep these images in my app's static folder,
3) and (if 2) whether I would need to run collectstatic every time someone uploads an image in the admin.
Sorry if I'm unclear, but this way more obscure than I thought it would be.
In order for the image to be uploaded and served during development, I had to move the media folder out of the static folder (i.e. create a media folder at the root of my project's folder).
And in my main urls.py, I had to add :
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)
as suggested by MicroPyramid.
To display it in a template, for a given Individual "somebody" (from a queryset), I use :
<img src="{{ somebody.ind_photo.url }}">
It is good practice to separate both staticfiles and media files. Yes, you have to do collectstatic all the time when you upload if you store the images in static folder. We can get the image full url from the object like the following.
{{obj.ind_photo.url}}
For more info on files https://docs.djangoproject.com/en/1.10/topics/files/

django 1.4.3 file structure?how to access the images?

i am using django 1.4.3 version and i am not able set the media path so that i can access my images.i have searched in the Google but nothing is helped me to solve this. My project structure is like below
indianstartup
indianapp
admin.py
models.py
views.py
templates/
index.html
h.html
media/
abc.jpg
indianstartup
settings.py
urls.py
now in models.py i am using imagefield like below
pic=models.ImageField(upload_to="media/")
the above one is not working, how can i save or upload a image to my media folder which is in "indianapp" folder and how can i show the same image in the html file?
Settings file
MEDIA_ROOT = os.path.join(SITE_ROOT, 'media')
MEDIA_URL = '/media/'
added view.py
views.py
def singlepost(request, year, month, slug2):
posts, pagedata = init()
img=posts.get
post = posts.get(date_created__year=year,
date_created__month=int(month),
slug=slug2,)
pagedata.update({'post': post})
return render_to_response('singlepost.html', pagedata)
so iam trying to get the image by post.pic in like
<img src="{{post.pic}}">
but not working

upload images to template directory

I have a model with this field:
image=models.ImageField(upload_to='company-category')
company-category is a folder in uploads folder,but I want to upload images to template directory .I think this way users that visit my website can't access images and download them.
in settings:
TEMPLATE_DIRS = (
"C:/ghoghnous/HubHub/Theme"
)
how can I do this?
Here I'm giving two solutions. The one you asked and then my suggestion.
Use the following code to set the upload location to your templates folder.
from django.conf import settings
image=models.ImageField(upload_to = settings.TEMPLATE_DIRS[0])
The above code will upload image to your template directory.
My Suggestion:
Upload images to your media folder. Then use the MEDIA_URL to allow users to download them. Use the following code to define them.
settings.py
MEDIA_ROOT = 'C:/ghoghnous/HubHub/media'
MEDIA_URL = 'site_media'
urls.py
from django.conf import settings
urlpatterns += patterns('',
url(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
)
models.py
class SampleModel(models.Model):
image = models.ImageField(upload_to = 'images')
If you use this, the images will be uploaded to the folder C:/ghoghnous/HubHub/media/images/. Then get your required images by using objects.get or objects.filter.
record = SampleModel.objects.get(id = 1)
If I print record.image, the output will be images/filename.jpg.
Pass this to your template. Then you can display the image or give download link as follows:
<a href="{{ record.image.url }}/" >Download</a> #Download link
<img src="{{ record.image.url }}/" /> #To display image
<a href="/site_media/images/file.jpg" >Download</a> #Download static files
I suggest you using the second method, since saving images in templates folder is not adviced.
Template directory is not a preferred place to store media as per Django good practices.
Also, any images that you display on the web page will have a path and can be downloaded. Some people use scripting to stop right clicks and stuff like this but as far as I understand source code always give you image paths.
Oh, I think you'd like to upload the file to a temporary folder and then do something with it. Right?
You need to override method clean_image in forms. Then you can write your own code with any path you want using File storage