I have model with ImageFile field:
def upload_course_cover(object, filename):
return '/media/courses/%s_%s' % (Course.objects.aggregate(Max('id'))['id__max'] + 1, filename)
class Course(models.Model):
# ...
cover = models.ImageField(upload_to=upload_course_cover, blank=True)
When the image is saved, into cover field will be writen full image path /media/courses/id_filename.ext, but I want store only image name id_filename.ext.
How to do it?
You cannot change what it stores in the database - unless you create your own custom field; or use a CharField.
If you just want to display the filename:
import os
c = Course.objects.get(pk=1)
fname = os.path.basename(c.cover.name)
# if cover's name is /hello/foo/bar.html
# fname will be bar.html
However, since you have image field - you can get lots of benefits out of it, for example - to get the URL to display the image in an img tag:
<img src="{{ c.cover.url }}"
alt="cover image for {{ c.name }}"
/>
You can also get some other benefits, for example:
class Course(models.Model):
# ....
cover_height = models.IntegerField()
cover_width = models.IntegerField()
cover = models.ImageField(upload_to=upload_course_cover,
height_field=cover_height,
width_field=cover_width,
# your other options...
)
Now you can do:
<img src="{{ c.cover.url }}" height="{{ c.cover_height }}" width="{{ c.cover_width }}">
"When the image is saved, into cover field will be writen full image path /media/courses/id_filename.ext"
To be precise, this is not true. Only the relative path from your MEDIA_ROOT is saved in the database. See https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.FileField.upload_to
(ImageField has the same properties as FileField)
To save only the filenames, you could
Add a new CharField to store the names
Use os.split() to get just the filename when called
Related
I created a separate model for users to upload a profile pic.
models.py
class Image(models.Model):
profilepic = models.ImageField(upload_to='images/', null = True)
def __str__(self):
return self.title
html
<img src="/images/{{ image.profilepic }}"/>
all I am getting back is a empty canvas with an image icon
I should note the images are uploading to the folder just not displaying
I think need to add .url like this
<img src="/images/{{ image.profilepic.url }}"/>
So I originally had the user create a post in admin and be able to leave image field blank and Django would set a default image.
My problem is;
If a user uploads an image, then deletes the image in admin, I get an error: The 'image' attribute has no file associated with it. when accessing solo.html in browser.
How can I make the default image reappear and specifically come from static folder?
My code:
settings.py
STATIC_URL = '/static/'
STATIC_DIRS = os.path.join(BASE_DIR, 'static')
models.py
# FIXME: If default image is changed to user's upload but then deleted. Make default image reappear.
# Recipe Field
class Recipe(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to='recipes/images/', blank=True)
def get_image(self):
if not self.image:
return f'{settings.STATIC_URL}default.png'
return self.image.url
solo.html
<h2>{{ recipe.title }}</h2>
<h3>{{ recipe.category }}</h3>
<h3>{{ recipe.meal }}</h3>
<img src="{{ recipe.image.url }}">
I'm just starting with Django so I apologize in advance if it's all a mess.
Thank you in advance!
What's happening is that the file itself is being deleted, but recipe.image is not being set to None.
I need to past in template a filename of file which uploaded in instance imagefield.
My class:
def conference_directory_path(instance, filename):
return 'dialogues/conferences/conference_{0}/avatar/{1}'.format(instance.id, filename)
class Dialogue(models.Model):
...
avatar = models.ImageField(upload_to=conference_directory_path, blank=True)
...
Template:
<img src="/static/dialogues/conferences/conference_{{ dialogue.id }}/avatar/{{ dialogue.avatar.filename }}" alt="">
But dialogue.avatar.filename is empty string after rendering. What's wrong? dialogue is an instance of Dialogue model.
What is stored in the database is in fact the filename and not the data. How to access it is described here:
https://docs.djangoproject.com/en/1.10/ref/models/fields/#filefield
All that will be stored in your database is a path to the file
(relative to MEDIA_ROOT). You’ll most likely want to use the
convenience url attribute provided by Django. For example, if your
ImageField is called mug_shot, you can get the absolute path to your
image in a template with {{ object.mug_shot.url }}.
so we have
<img src="{{ dialogue.avatar.url }}" alt="">
I need create a image upload with django, the problem is, django always saving in a global project(called linkdump) folder, I want save it on the project folder(linktracker).
setting.py:
STATIC_URL = '/static/'
model:
class Link(models.Model):
link_description = models.CharField(max_length=200)
link_url = models.CharField(max_length=200)
link_image = models.ImageField(upload_to= './static/')
def __str__(self):
return self.link_description
class Admin:
pass
now in the view:
<img src="{% static link.link_image %}" alt="{{ link.link_description }}">
it returns
http://127.0.0.1:8000/static/static/o-BLUE-LIGHT-SLEEP-facebook.jpg
and the upload is in the project folder(linkdump), not inside the app.
You can specify a function to return a custom path for the ImageField:
def get_upload_path(instance, filename):
return 'your/custom/path/here'
class Link(models.Model):
. . .
link_image = models.ImageField(upload_to=get_upload_path)
Now you can use information from the model instance to build up the path to upload to.
Additionally, you don't want to use the {% static %} template tag to specify the path to the image. You would just use the .url property of the field:
<img src="{{ link.link_image.url }}" alt="{{ link.link_description }}" />
I have following field:
photo = models.ImageField(null=True,blank=True,upload_to="product_images")
I have defined the following layout in forms.py for this field:
self.fields['photo'].label = "Asset Image"
self.helper.layout = Layout(
'photo',
HTML("""{% if form.photo.value %}
<img height="80"
width="160"
class="pull-left"
src="{{ MEDIA_URL }}{{ form.photo.value }}">
{% endif %}""", ),
Now I can upload images associated with this particular field just fine. However when I try to update the image I see the following in my template:
Is there any way I can change the layout so that only the browse button and existing image are shown when the image field is not empty? In other words, remove the text Currently: product_images/km_2.jpeg Clear Change:
I'm pretty sure ImageField uses ClearableFileInput in order to render the HTML.
So to get rid of the "Currently: ... Clear" stuff you need to subclass the ClearableFileInput and modify the template_with_clear and/or template_with_initial members.
from django.forms import ClearableFileInput
class MyClearableFileInput(ClearableFileInput):
template_with_initial = '%(input_text)s: %(input)s'
Subsequently you use MyClearableFileInput, e.g.:
class MyForm(ModelForm):
class Meta:
model = MyModel
widgets = {
"file": MyClearableFileInput(),
}
I tested this with a FileField, but I'm pretty sure it will also work with an ImageField.