I have an UpdateView with an object which has a FileField. If the model has a file uploaded, I show the link to the file, and also a file input in case the user wants to update it.
<form method="post" enctype="multipart/form-data">
{% if object.file %}Download{% endif %}
<input type="file" name="{{ form.file.name }}">
<input type="text" name="{{ form.other_field.name }}">
</form>
which works fine if the object is new and does not have a file, in which case the Download link does not show or if it has a file, in which case the Download link shows up.
But, if I select a file to upload, and the form is invalid, the object.file field exists, and it points to a non-existent file.
Is there a way to tell in an invalid form if the file is real?
You should use enctype
<form method="post" enctype="multipart/form-data">
Related
I am trying to use jQuery file upload plugin to upload files
I am having a form containing text field and other inputs as well as the fileupload plugin specified file input as below
<form method="post" action="{% url 'compose' %}" id="fileupload" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="t1"/>
<input data-bfi-disabled='' multiple='' name='files[]' type='file'>
<input type="submit">
</form>
Then in Django view I am trying to access the files uploaded with the following
attachment = request.FILES.getlist("files[]")
But on submit clicking I am getting blank filelist.
Where am I doing wrong?
I dont need ajax submission of individual files.
I need to submit all files upload along with other input contents to the view.
UPDATE:
when I checked in the UI by removing css classes of file upload button i could see "No FILE CHOSEN" but I could see list of files like below
I am confused how to use this plugin to submit my form with the selected files and other fields
Why don't you use a Form models:
class FileUploadForm(forms.Form):
file_source = forms.FileField()
Then:
<form action="/upload/" method="post" id="file-upload-form" enctype="multipart/form-data"> {% csrf_token %}
{{ form }}
<button type="submit" class="btn btn-primary" id='upload-btn'>Upload</button>
And your view:
def upload_view(request):
if request.is_ajax():
form = FileUploadForm(request.POST)
if form.is_valid():
print 'valid form'
I'm very new to Django and not super familiar with web programming in general, so it's very likely that there is an easy fix to my problem that I'm just unaware of.
My web app is a photo gallery. People can click on a photo to see an enlarged version with buttons on either side for older or newer pictures. In addition, the photos in the gallery can be sorted by tags, which are passed along as URL parameters.
My problem is that when I click on one of the submit buttons, Django replaces the parameters in my URL with the name of the button, thus destroying my reference to what tag I was using. For example, "127.0.0.1:8000/gallery/view/6/?tag=people" upon clicking next, gets converted to "127.0.0.1:8000/gallery/view/6/?older=Older" when it's trying to process the URL.
Code from my HTML:
<form action="/gallery/view/{{ photo.id }}/?tag={{ tag }}" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
In my view.py I pass in the tag plus other information in a render_to_response, but I'm not sure how to/if I can reclaim it while handling the buttons.
render_to_response('item/view.html', {'photo':photo, 'tag':tag, 'related_tags': related_tags, 'related_photos': related_photos, 'has_newer': has_newer, 'has_older': has_older}, context_instance=RequestContext(request))
Here's the view.py code for processing the buttons:
if 'newer' in request.GET:
if has_newer:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(newer[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
if 'older' in request.GET:
if has_older:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(older[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
<form action="/gallery/view/{{ photo.id }}/" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<!--This will append a tag parameter with given value to the querystring -->
<input type="hidden" name="tag" value="{{ tag }}">
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
Note that the query string is removed from action (as it won't be used) and the older and newer parameters will still be sent along.
In my template, I display a list of users a user follows. I would like the user to be able to delete one of the users he follows thanks to a button.
I have a function remove_relationship that deletes a relationship.
Here is the function in my models.py:
class UserProfile(models.Model):
(...)
def remove_relationship(self, person):
Relationship.objects.filter(
from_person=self,
to_person=person).delete()
return
I would like to pass this function into my template:
{% for user in following % }
<form method="post">
{% csrf_token %}
<input type="submit" value="delete" onclick="remove_relationship"/>
</form>
{%endfor%}
The thing is that I can't pass argument in my template. So how can I do so that each button deletes the relationship with the right user?
I saw an other question on this topic, abut it looks like it doesn't solve my problem (http://stackoverflow.com/questions/1333189/django-template-system-calling-a-function-inside-a-model)
Thank you for your help.
It looks as though you are confusing client-side code (JavaScript) with server-side (Django).
To get the relevant user ID submitted you could add an additional hidden field to the form:
{% for user in following % }
<form method="post" action="{% url views.remove_relationship %}">
{% csrf_token %}
<input type="hidden" name="user_id" value="{{ user.id }}">
<input type="submit" value="delete" />
</form>
{%endfor%}
Then create a remove_relationship view that does the deletion on the server side, based on the user id you'll now find in request.POST['user_id']
I have been trying to implement a image upload for changing avatar for individual users. The problem I have right now is that it never uploads to the folder. It works from the admin but it doesn't work on the template I've created
views.py
if 'avatar_upload' in request.POST:
avatar_form = UserAvatarForm(request.POST, request.FILES, instance=request.user.get_profile())
if avatar_form.is_valid():
avatar_form.save()
return HttpResponse(request.POST['avatar'])
return HttpResponse("Failed")
I've changed the code for viewing the outputs. I get the file name in the POST. But I don't have anything in the request.FILES. So I'm guessing it is a problem there, and I haven't found out so far what the problem could be. Or could it be some problem elsewhere?
template*
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for item in avatar_form %}<p>{{ item.label }}: {{ item }}</p>
{% endfor %}
<input type="submit" value="Upload avatar" name="avatar_upload">
</form>
Have you set enctype="multipart/form-data" in form in the template?
So, I'm using django.contrib.comments. I've installed it OK but rather than the unwieldy default comment form, I'd like to use a custom form template that just shows a textarea and submit button.
The rationale behind this is that user only see the form if they area already authenticated, and I'd like the keep the form simple and pick up their username etc automatically.
I've implemented a custom form, but am getting an error when I try to submit it.
Here's what I have in my template for the page with the comment form (entry is the object passed from the view):
{% load comments %}
{% render_comment_form for entry %}
And here's my HTML in /templates/comments/form.html:
{% if user.is_authenticated %}
<p>Submit a comment:</p>
<form action="/comments/post/" method="post">
<textarea name="comment" id="id_comment" rows="2" style="width: 90%;"></textarea>
<input type="hidden" name="options" value="{{ options }}" />
<input type="hidden" name="target" value="{{ target }}" />
<input type="hidden" name="gonzo" value="{{ hash }}" />
<input type="hidden" name="next" value="{{ entry.get_absolute_url }}" />
<span style="float:right;"><input type="submit" name="post" value="Add"></span>
</form>
{% else %}
<p>Please log in to post a comment.</p>
{% endif %}
It renders okay initially, but when I try to submit the comment form, I get the following Django error:
Comment post not allowed (400)
Why: Missing content_type or object_pk field.
Can anyone help?
The comment model uses a generic foreign key to map to the object for which the comment was made such as a blog entry. These are required hidden fields included in the standard comment form.
From django.contrib.comments.models
...
class CommentSecurityForm(forms.Form):
"""
Handles the security aspects (anti-spoofing) for comment forms.
"""
content_type = forms.CharField(widget=forms.HiddenInput)
object_pk = forms.CharField(widget=forms.HiddenInput)
...
If you haven't changed the form class and only want to change the html template then you can include these fields by adding a for loop over all the hidden fields.
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
Fixed the problem by copying from Theju's app - in particular, see Joshua Works' comment on part 2.