ImageField doesn't upload - django

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?

Related

Passing HTML tag data- to Django with form submit

I am trying to pass data in HTML tag with a form submit to Django
I currently have a template like this:
{% for item in items %}
<div class="product">
{{ item.item_name }}
<form method="POST">
{% csrf_token %}
<input
type="submit"
value="add to cart"
data-pk="{{item.pk}}"
class="add_product"/>
<form>
</div>
{% endfor %}
I want to pass data-pk with a Django form. How do I do that?
Also I know, I can create a view to handle endpoint to do that, and include pk in the url, is that a better solution?
I am new to Django, and I will be grateful for any input on how to do stuff the right way
Instead of data, use value={{item.pk}} and handle the submit logic in your view.

Django Return redirect working for one view but not for the other

I cannot understand why it is working in one instance but not the other. I am working with django and output in django template. The only difference between the views/functions are in the second one (the one that is not working) I update the field with time. Time updates, saves in the model and displays updated time correctly. It is just the redirect that is not working.
The working redirect code-
Template, this code takes me to the edit page. Name of the url is "update" -
<td><button>Edit</button></td>
The form on the dit page-
{% block content %}
<div class="wrapper">
<h1 class="ok">Entry Form</h1>
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit" value="submit">
</form>
</div>
<br>
{% endblock content %}
url-
path('update_entry/<str:pk>/', views.update, name = "update"),
And views.py-
def update(request, pk):
order=Bank1.objects.get(id=pk)
form = Bank1Form(instance=order)
if request.method == 'POST':
form = Bank1Form(request.POST, instance=order)
if form.is_valid():
form.save()
return redirect('/bank1')
context = {'form':form}
return render(request, 'myapp/entry.html', context)
Now here is the non working code. Template, the line that takes me to the update page. Name of the url is "update_enter_workout.-
<td><button>Start Time</button></td>
Form on the Edit page. Didn't add the entire form since I only need to update the time from this page. Just the submit button.-
{% block content %}
<Button>Close this page and go to Home</Button>
<div class="wrapper">
<h1 class="ok">Start/End the set now?</h1>
<form action="" method="post">
{% csrf_token %}
<input type="submit" value="YES!">
</form>
</div>
{% endblock content %}
url-
path('update_enter_workout/<str:pk>/', views.update_workout, name='update_enter_workout'),
Views.py-
def update_workout(request, pk):
order=WorkOut.objects.get(id=pk)
form=WorkOutForm(instance=order)
if request.method=='POST':
form=WorkOutForm(request.POST, instance=order)
time=datetime.now().strftime('%H:%M:%S')
WorkOut.objects.filter(id=pk).update(start=time)
if form.is_valid():
form.save()
return redirect('/bank1')
context={'form':form}
return render(request, 'myapp/enter_workout.html', context)
As you can see they are written the same way, but in the second instance redirect is not working. Any idea what can be changed. It is so simple, couldn't even find a typo or simple mistake like that.
Any advise?
Are you accepting str for id fields? Primary Keys are integers, not strings. You need to cast to an int path converter:
Instead of:
path('update_enter_workout/<str:pk>/', views.update_workout, name='update_enter_workout'),
Use:
path('update_enter_workout/<int:pk>/', views.update_workout, name='update_enter_workout'),

Django - do not validate the second form

I have this code snippet in template.
<form method="POST" novalidate>
{% csrf_token %}
{{ form }}
{{ form2.as_p }}
<button type="submit" class="btn btn-secondary">Search</button>
</form>
And in forms.py there are two forms (not ModelForm, but only Form).
form searches data in first db and form2 search data in second db and displays the results. The second form has only one field and I'd like to have something like this in
a view.
if request.method == "POST":
if form.is_valid():
# extract data from the first db
if form2.is_valid()
# extract a few more data from the second db
The field in the second form is not required for the user to fill in. If the user fills it in the user gets only more data displayed.
I solved it partially with the novalidate in HTML. But what I'd like to have is the validation of the first form and the second form with its one form field can be empty.
Is there some django feature to achieve this result?
something like this?
<form method="POST">
{% csrf_token %}
{{ form.novalidate }}
{{ form2.as_p }}
<button type="submit" class="btn btn-secondary">Search</button>
</form>

Validating a formset

I am getting this error: ValidationError at /screen-many/
[u'ManagementForm data is missing or has been tampered with'] and I think it is due to the folling code in my view...
# e_pk_list is a list of id's that I got from POST
e_students = Student.objects.filter(pk__in=e_pk_list)
my_iterator = iter(e_students) # Each list item will correspond to a form.
SurveyFormset = formset_factory(SurveyForm, extra=len(e_students))
# Is this the tampering that I can't do??
SurveyFormset.form = staticmethod(curry(SurveyForm, item_iterator=my_iterator))
if request.method == 'POST':
survey_formset = SurveyFormset(request.POST)
if survey_formset.is_valid():
for form in survey_formset:
saved = form.save(commit=False)
saved.surveyset = ss
saved.save()
return HttpResponseRedirect('/')
else:
survey_formset = SurveyFormset()
Thanks
EDIT: I guess I should have mentioned that I already have a managementform in my template....
<form action="" method="POST">{% csrf_token %}
{{ survey_formset.management_form }}
{% for form in survey_formset %}
<div class="item">
{% crispy form %}
</div>
{% endfor %}
<input type="submit" value="Submit" class='button' />
</form>
Its seems that you didn't put management_form in your form .
Put this in your html form where your are displaying SurveyFormset
{{ SurveyFormset.management_form }}
A formset has many forms. Django keeps track of number of forms in formset using management form data. You should add management_form in the template too, which should be posted along with other POST data.
So, you should have:
<form method="POST" action=".">
{{survey_formset.management_form}}
{% comment %}Other form fields{% endcomment %}
</form>

Django URL is being changed by a submit button

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.