I am developing an application with django for uploading a file on the server. I have defined a form and a model in forms.py and models.py files separately as below(respectively):
from django import forms
class DocumentForm(forms.Form):
docfile = forms.FileField(
label=''
)
and in models.py:
from django.db import models
# Create your models here.
class Document(models.Model):
docfile = models.FileField(upload_to='targetdir')
in my HTML file and my form is:
<form class="myclass" action="submit" method="post">
{% csrf_token %}
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<br />
<input font-size="50px" style="zoom:1.5" class="myclass" dir="rtl" type="submit" value="upload" id="button" class="top-menu" onclick="pythonhandler()" />
now, whenever I submit my form and I wanna to receive my uploaded file on the server via below codes, I got "
raise MultiValueDictKeyError(repr(key))
MultiValueDictKeyError: "'docfile'""
error. my views.py file:
def pythonhandler(request):
if request.method == 'POST':
try:
data = request.FILES.get('docfile')
with open(os.getcwd()+'/mydirectory/'+request.FILES['docfile'].name, 'wb+') as destination:
for chunk in request.FILES['docfile'].chunks():
destination.write(chunk)
I did the mentioned steps in this , this and this question, but I receive this error again!
in your view function
def pythonhandler(request):
data = DocumentForm(request.POST, request.FILES)
and in your html file
<form class="myclass" action="submit" enctype="multipart/form-data" method="post">
{% csrf_token %}
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<input type="submit" value="upload" id="button" class="top-menu" onclick="pythonhandler()" />
I have missed enctype="multipart/form-data" command in my form tag in my HTML file. So, my form in the HTML file must be such as bellow:
<form class="myclass" action="submit" enctype="multipart/form-data" method="post">
{% csrf_token %}
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<input type="submit" value="upload" id="button" class="top-menu" onclick="pythonhandler()" />
Related
Im on investigation Django framework and now trying to create custom procedure of resetting password.
I use this URL path
path('password_reset_confirm/<uidb64>/<token>',
PasswordResetConfirmView.as_view(
template_name='user_account/reset_password/password_reset_confirm.html',
success_url='/account/password_reset_complete/'),
name="password_reset_confirm"),
In template i use crispy form
<form class="login-form p-4 rounded" method="post">
{% csrf_token %}
<h1 class="h4 mb-4 font-weight-bold">Change your password</h1>
<p>Use the form below to change your password.</p>
{{ form|crispy }}
<button type="submit" value="Change">
Submit
</button>
</form>
So now this form do not showing in template, and if if type {{ form }} instead of {{ form.as_p }} or crispy form, that showing me None in form place.
I'm trying to create a button on the framework django that let me delete my own article on my blog. I tried to create a code for this functionality, but it doesn't work.
views.py
if(request.GET.get('delete')): #if the button is clicked
delete_article = get_object_or_404(Article, id=id)
if request.POST:
form = DeleteNewForm(request.POST, request.FILES)
if form.is_valid():
delete_article.delete()
return HttpResponseRedirect("/")
template.html
<form enctype='multipart/form-data' action="." method="post" class="form" autocomplete="off" autocorrect="off">
{% csrf_token %}
<div class="form-group">TITRE
{{ form.title.errors }}
{{ form.title }}
</div>
<div class="form-group">CONTENU
{{ form.media }}
{{ form.contenu.errors }}
{{ form.contenu }}
</div>
<div class="form-group">
{{ form.image.errors }}
{{ form.image }}
</div>
<input type="submit" class="btn btn-default" value="Edit Article"/>
<input type="submit" class="btn btn-default" value="Delete Article" name="delete">
</form>
Here is what happen when I submit the form : I am not redirected on the index as it should redirect me and the article has not been deleted.
Is there a problem which don't let me delete my article in these lines?
I have no idea what you're doing in your views or in your template. But if I want to delete something, I just define a separate view for that.
# views.py
from django.views.generic.base import View
class DeleteView(View):
def post(self, request *args, **kwargs):
article = get_object_or_404(id=request.POST['article_id'])
# perform some validation,
# like can this user delete this article or not, etc.
# if validation is successful, delete the article
article.delete()
return HttpResponseRedirect('/')
Your template should be like this:
<form action="/url/to/delete/view/" method="POST">
{% csrf_token %}
<input type="hidden" value="{{ article.id }}">
<input type="submit" value="Delete">
</form>
I'm trying to get together code that uploads and deletes photos from a django/bootstrap carousel, as well as a database. However, I can't seem to get past this error:
TypeError at /alzheimers/delete
delete() takes exactly 2 arguments (1 given)
Can anyone help me? I'm kind of a noob at django, and writing this code is like pulling teeth, so any help would be greatly appreciated.
My code:
Carousel.html:
{% load staticfiles %}
{% load filename %}
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<div class="carousel-inner" role="listbox">
{% for document in documents %}
<div class="item {% if forloop.first %} active {% endif %}">
<div class="row">
<div class="col">
<li>{{document.docfile.name}}</li>
<img src = "{{STATIC_URL}}img/{{document|filename}}" >
<p align="center"><form style="text-align:center" action="{% url 'webportal:delete' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.Document.label_tag }} {{ form.Document.help_text }}</p>
<p>
{{ form.Document.errors }}
{{ form.Document.docfile }}
</p>
<p><input type="submit" value="Delete" /></p>
</form></p>
</div>
</div>
</div>
{% endfor %}
</div>
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="sr-only">Next</span>
</a>
</div>
<!-- /.carousel -->
</div>
</div>
<form action="{% url 'webportal:carousel' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
</div>
Views.py:
from django.shortcuts import render
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import authenticate, login
from webportal.views.authentication import LoginForm
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.conf import settings
from webportal.forms.forms import DocumentForm
from webportal.models import Document, DeleteForm
is_server = True
def delete(request, my_id):
Deleted=get_object_or_404(Document, docfile=my_id)
if request.method=='POST':
form=DeleteForm(request.POST, instance=Deleted)
if form.is_valid():
Deleted.delete()
return HttpResponseRedirect('http://127.0.0.1:8000/alzheimers/')
else:
form=DeleteForm(instance=Deleted)
return render_to_response(
'webportal/index.html',
{'documents': documents, 'form': form,},
context_instance=RequestContext(request)
)
# Redirect to the document list after POST
def carousel(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect('http://127.0.0.1:8000/alzheimers/')
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
#documents=DocumentForm().
# Render list page with the documents and the form
return render_to_response(
'webportal/index.html',
{'documents': documents, 'form': form,},
context_instance=RequestContext(request)
)
Models.py:
class Document(models.Model):
docfile = models.ImageField(upload_to='webportal/static/img/')
class DeleteForm(ModelForm):
class Meta:
model=Document
fields=[]
Forms.py:
class DocumentForm(forms.Form):
docfile = forms.ImageField(label='Select a file', help_text='max. 42 megabytes')
urls.py:
url(r'^delete', views.delete, name="delete"),
You are POSTing your object id through a form while your delete view expects it as an argument (my_id). Change it to:
def delete(request):
if request.method=='POST':
my_id = request.POST.get('id')
Deleted=get_object_or_404(Document, id=my_id)
...
As a side note, the Python convention is to use lowercase names for objects. Consider renaming Deleted to deleted.
Update: You also seem to have omitted to include the id of the object to be deleted in your form. Put the following line somewhere between your <form> and </form> tags:
<input type="hidden" name="id" value="{{ document.id }}" />
I'm trying to implement login/registration views in Flask that support both regular login (through Flask-Security) and OAuth login (through Flask-Social).
My website uses CSRF protection, but when I implement a link to the OAuth login page (as per the Flask-Social example project) I get a CSRF error. Here is the template:
{% extends "base.html" %}
{% from "security/_macros.html" import render_field_with_errors, render_field %}
{% block title %}Login{% endblock %}
{% block body %}
<h1>Login</h1>
{% include "security/_messages.html" %}
<form action="{{ url_for_security('login') }}" method="POST"
name="login_user_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email,
class="form-control", placeholder="Your email") }}
{{ render_field_with_errors(login_user_form.password,
class="form-control", placeholder="Password") }}
{{ render_field(login_user_form.remember) }}
{{ render_field(login_user_form.next) }}
{{ render_field(login_user_form.submit, class="btn btn-primary") }}
</form>
<form action="{{ url_for('social.login', provider_id='google') }}"
name='google_login_form' method="POST">
<input class="btn btn-primary btn-large" type="submit"
name="login_google" value="Login with Google" >
</form>
{% include "security/_menu.html" %}
{% endblock %}
The problem seems to be that the second form does not have a CSRF field; what can I do about this?
You should follow the Flask-WTF docs on using templates without forms.
As per the docs, in the app
from flask_wtf.csrf import CsrfProtect
CsrfProtect(app)
and in the template
<form method="post" action="/">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>
Your second form would be
<form action="{{ url_for('social.login', provider_id='google') }}"
name='google_login_form' method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input class="btn btn-primary btn-large" type="submit"
name="login_google" value="Login with Google" >
</form>
I have a database with users information and IP's. What I would like to do is to dynamically create, and then open, a *.vnc file with their IP.
In my views.py file I have this:
def view_list(request):
template_name = 'reader/list.html'
cust_list = xport.objects.all()
#if request.method == 'POST':
#<a href=link to created *.vnc file>Connect to client</a>
return render(request, template_name, {'xport': cust_list})
The commented out portion is just what I've been playing with and what I currently think I need to do.
My template file is list.html and looks like this:
{% extends "base.html" %}
{% load url from future %}
{% block content %}
<h1> Customer List </h1>
<ul>
{% for c in xport %}
{% if c.ip %}
<li>{{ c.firstName }} {{ c.lastName }}</li>
<form method="POST" action=".">{% csrf_token %}
<input type="submit" name="submit" value="Create VNC to {{ c.ip }}" />
</form>
{% endif %}
{% endfor %}
</ul>
{% endblock %}
What I would like to do is to click on the "Create VNC" button and then that create and open the *.vnc file.
This should give you an idea:
url(r'^file/vnc/$', 'myapp.views.vnc', name='vnc-view'),
views.py
from django.views.decorators.http import require_POST
#require_POST
def vnc(request):
ip = request.POST.get('ip', None)
response = HttpResponse(ip, content_type='application/octet-stream')
# If you don't want the file to be downloaded immediately, then remove next line
response['Content-Disposition'] = 'attachment; filename="ip.vnc"'
return response
template
<form method="POST" action="{% url 'vnc-view' %}">{% csrf_token %}
<input type="hidden" name="ip" value="127.0.0.1" />
<input type="submit" name="submit" value="Create VNC to 127.0.0.1" />
</form>