hey guys I have a specific issue.
I have a view:
class Upload(CreateView):
model = Banner
fields = ["image"]
success_url = '/url/'
def form_valid(self, form):
#some specifics operations...
This image are uploading to /upload
And in other place (e.g. /other_place, image in this dict are not uploading) I have a directory with other images. I get path to this images:
for file in glob.glob("*.jpg"):
l.append(file)
And in template:
{% for i in l %}
<img src="{{MEDIA_URL}}other_place/{i}}">
{%endfor%}
And I have nice template with all of this image. But now I need to upload selected image. specifically I need to call Upload view to upload selected image. Do you know what I mean? :D
Related
I have a requirement where if a user doesn't upload the image, the default image should be saved in DB for this I am using the default attribute in FileField but default image is not saving in DB.
file = models.FileField(upload_to='photos/',default='NoImage.jpg')
You can do like this. Give the full path prepending MEDIA_ROOT like
file = models.FileField(upload_to='photos/',default='settings.MEDIA_ROOT/photos/NoImage.jpg')
But I would suggest keep it null because in a case if lots of your user are not uploading any image. You are unnecessarily inserting those number of repetitive default image in database.
In you django-template you can handle
{% if not file %}
<img src= "{{ MEDIA_URL }}photos/NoImage.jpg">
{% endif %}
I think you should leave the field blank if no image is uploaded. It would make easier for auditing and filtering. I would just throw a property:
#property
def image_url(self):
if self.image:
return self.file.url
else:
return "default/image/path/default.jpg"
I have a model which contains a number of user uploaded files that other than the file itself also contain a description and some other meta information.
class ArchiveFile(models.Model):
archive_file = models.FileField(upload_to=grab_archive_folder, default=None, blank=False)
description = models.CharField(max_length=255)
What I want is for a user to (1) upload new files. And (2) be able to edit the descriptions of all files associated with the user, including the recently uploaded. The uploading of new files is done via AJAX / JQuery and new forms (as part of a formset) are generated dynamically.
In order to do be able to edit the descriptions in an efficient matter, it would help for a user to know of what file it is changing the description, and so I would like the filename to be displayed.
My initial solution was the following:
forms.py
class ArchiveDataForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['archive_file'].widget.attrs['disabled'] = True
class Meta:
model = ArchiveFile
fields = ['archive_file','description']
views
def archive_data_update(request):
if request.method == 'GET':
ArchiveDataFormSet=modelformset_factory(ArchiveFile, form=ArchiveDataForm, extra=0)
archive_formset = ArchiveDataFormSet(queryset=ArchiveFile.objects.filter(user_id=request.user.id)
template = 'archive_data_edit.html'
template_context = {
'archive_formset': archive_formset,
...
}
return render(request, template, template_context)
if request.method == 'POST':
ArchiveDataFormSet=modelformset_factory(ArchiveFile, form=ArchiveDataForm, extra=0)
archive_formset = ArchiveDataFormSet(request.POST, queryset=ArchiveFile.objects.filter(user_id=request.user.id)
if archive_formset.is_valid():
for archive_form in archive_formset:
archive_form.save()
return HttpRespone('ok')
template
{% for archive_form in archive_formset %}
{{ archive_form.archive_file.value }}
{{ archive_form.description }}
{% endfor %}
My issue is that I am getting validation errors on the dynamically created forms, saying that no file is present. Which I suppose is correct since all I do is inject the filename to the dynamically created form via my AJAX/JQuery. Is there a way I can ignore this validation for the purpose of this form only? or is there an easier/different way to display the filenames?
Some comments:
If you only want to edit the descriptions you should not include as a form field the archive_file field.
You could instead pass in your view the instance of the form to the context of the request. And then interpolate the title of the file in the template.
If you could provide your view code, we can discuss an actual implementation.
UPDATE:
Looking at the source code of model form, you hava always available the instance of the object of the form. why don't you try using that?
As in:
# template
{% for archive_form in archive_formset %}
{{ archive_form.instance.archive_file.filename }}
{{ archive_form.description }}
{% endfor %}
I am using following template tags to display thumbnails in my templates
{% load thumbnail %}
{% thumbnail obj.image 250x250 crop %}
thumbnail template tag returns relative urls to thumbnail image files as expected. But I would like it to return absolute urls. Normally easy-thumbnails has THUMBNAIL_MEDIA_URL = '' setting which allows thumbnail's storage to build absolute urls but it does not work with django-filer.
Is there any other way to achieve what I want?
You can extract the thumbnail properties using as
{% thumbnail obj.image 250x250 as thumb %}
{{thumb.url}}
See http://easy-thumbnails.readthedocs.org/en/latest/usage/#thumbnail-tag
EDIT:
If by "absolute" you mean including the website, I would recommend doing the logic elsewhere.
Considering image to be a FilerImageField, create a property in the models.py. Example:
from django.contrib.sites.models import Site
from easy_thumbnails.files import get_thumbnailer
#property
def thumbnail_absolute_url(self):
if self.image:
thumbnailer_options = {'size': (250, 250), 'crop': True}
thumb = get_thumbnailer(self.image).get_thumbnail(thumbnailer_options)
thumb_url = thumb.url
site = Site.objects.get_current()
return site.domain + thumb_url
return None
See https://github.com/SmileyChris/easy-thumbnails#manually-specifying-size--options
I have a django applications that uses multi-users. Users can upload pictures on the system.I have created a picture model that has a foreignKey of a users to know which user uploaded which picture.
class Picture(models.Model):
picture = models.ImageField(upload_to='pictures')
uploader = models.ForeignKey(User)
#other specific fields like date etc
I have set up my settings file to use the MEDIA_URL and MEDIA_ROOT
settings.py
MEDIA_URL ='/media/'
MEDIA_ROOT = 'path/to/media/'
So I am able to access a picture in www.mydomain.com/media/pictures/picture.jpg. But I guess having a common MEDIA_ROOT means that any user can see this picture right?Not just the user who uploaded it. In my webpages I use
<img src={{image.picture}}>
to show images of a user. How can I prevent a user from seeing a picture a different user has uploaded(a forbidden message)? Can this be done on setup?
Your view function probably looks something like this:
#login_required
def theview(request):
...
image = Picture.objects.get(*args)
...
return render(request, 'template', {'image': image})
The point being that you can easily only pass the image along if it's the logged in user that have uploaded it. For instance
image = get_object_or_404(Picture, uploader=request.user, other_filters)
Or even
image = Picture.objects.get(*args)
image = image if image.uploader == request.user else None
Then in the django template
{% if image %}
<img ....>
{% endif %}
You can try like this:
in views:
def allpicture(request):
.....
#for all pictures
images= Picture.objects.filter(uploader=request.User)
return render(request, '/sometemplate', {'images': images})
def onepicture(request, pic_id):
....
#for one picture
image= Picture.objects.filter(id= pic_id, uploader=request.User) #url for this view should be like url(r'^pictures/(?P<pic_id>\d+)/$'
render render(request, '/sometemplate', {'image': image})
This is my models.py:
class UserImages(models.Model):
user = models.ForeignKey(User)
photo = models.ImageField(upload_to=get_file_path)
and this is my view which uploads images:
def uploadImageView(request):
if request.method == 'POST':
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
return redirect('/')
else:
form = UploadImageForm()
return render(request, 'image.html', {'form': form})
and this is my view which displays user's images:
def displayImageView(request):
user = request.user
img = UserImages.objects.filter(Q(user__username=user))
return render(request, "displayImage.html", {"img": img})
and this is my displayImage.html template:
{% load staticfiles %}
{% for image in img %}
<img src="{% static image.photo.url %}" alt="" />
{% endfor %}
and when I go to the URL which loads the template, it displays four images. I remember that while testing the uploadImageView, I uploaded 4 images for the viewer. The location Django saves the images was
/home/images/static
and I went to that folder and deleted two images. I then refreshed the template page and it still displayed 4 images rather than two, so then I figured that I had to delete it from the actual database rather than the folder. I then did
python manage.py shell
>>> from app.models import UserImages
>>> from django.contrib.auth.models import User
>>> a = User.objects.get(username='testUser')
>>> b = UserImages(user=a)
>>> b
<UserImages: UserImages object>
>>> b.photo
<ImageFieldFile: None>
amd as you can see, only one ImageFieldFile shows up for the user who I uploaded 4 images for. How come I can only see one?
EDIT:
my UploadImageForm() is just this:
class UploadImageForm(forms.ModelForm):
class Meta:
model = UserImages
fields = ['photo']
Your problem is here:
>>> b = UserImages(user=a)
>>> b
<UserImages: UserImages object>
>>> b.photo
<ImageFieldFile: None>
This code snippet is creating a new instance of UserImages, setting the user attribute to the object a. It is not searching the database. Since you haven't attached any images to this new instance, b is None.
To search, you need to do this instead:
>>> b = UserImages.objects.filter(user=a)
You also shouldn't upload anything to the same folder that is pointed to by STATICFILES_DIRS, as this folder is managed by django and your files here will be overwritten. I hope /home/images/static isn't listed here.
User uploads are saved in a subdirectory pointed to by MEDIA_FILES and accessed using MEDIA_URL.
When you save images in the database they will be saved in there as well as in a new location in your /static/ directory, etc.. Usually Django attaches a image_1.jpg for example if the image was originally image.jpg.
Do your images have a many-to-many relationship to the User model? Earlier, you said that there were 4 images saved to the User, then you said 1. Your UserImages model has one field, so possibly you are not looping through it correctly in the terminal shell in order to check all images. Perhaps it needs to be b.photos.all() if b = UserImages(user=a) or something to that extent?