Upload html in Django - django

Code in template:
<form action="/html/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" id="html_file" name="html_file" />
<input type="submit" value="Upload" />
</form>
and in view
def add_html(request):
if request.POST:
#do something with html
return redirect('/')
else:
return render_to_response('add_html.html')
I need to html-file is loaded and read its contents, not upload to the server.
But I get an error:
csrf token missing or incorrect
How fix?

My guess is that the {% csrf_token %} is empty when your template is rendered.
Per the CSRF documentation you should use the render function instead of the render_to_response function to ensure the RequestContext, which includes the csrf_token, is properly loaded into your template.

You can achieve what you want with the following code:
forms.py:
from django import forms
class ReadFileForm(forms.Form):
file = forms.FileField()
views.py:
from .forms import ReadFileForm
def read_file(request):
form = ReadFileForm()
if request.method == 'POST':
form = ReadFileForm(request.POST, request.FILES)
if form.is_valid():
content = request.FILES['file'].read()
# Do something with content
return render(request, 'read_file.html', locals())
templates/read_file.html:
<html>
<head></head>
<body>
<h3>Read File Content</h3>
<form enctype="multipart/form-data" action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Save">
</form>
</body>
</html>

Related

Why don't my entries get saved in the database in Django?

The post requests from the frontend do not get saved in the database, without any error shown. However, when I manually add entries from the admin panel, it shows on the frontend.
My index.html(form part):
<form class="main__input--form" method="POST">
{% csrf_token %}
<p class="main__input--text">
<textarea name="content" id="content" class="main__input--content" cols="35" rows="8" aria-label="Entry content" placeholder="Enter text here..."></textarea>
</p>
<button class="main__input--submit" type="submit">Vent</button>
</form>
My extension of index which loops through the database entries:
{% for obj in all_vents %}
<div>
<h1>{{obj.vent}}</h1>
</div>
<br />
{% endfor %}
My models.py:
class Vents(models.Model):
vent = models.CharField(max_length=10000)
def __str__(self):
return self.vent
My forms.py:
from django import forms
from .models import Vents
class VentForm(forms.ModelForm):
class Meta:
model = Vents
fields = ['vent']
My views.py:
from django.shortcuts import render, redirect
from .forms import VentForm
from .models import Vents
def ventout(request):
if request.method == "POST":
form = VentForm(request.POST or None)
if form.is_valid():
form.save()
return redirect("ventout")
else:
all_vents = Vents.objects.all()
return render(request, "ventout.html", {"all_vents": all_vents})
Views:
def ventout(request):
all_vents = Vents.objects.all()
if request.method == "POST":
form = VentForm(request.POST or None)
if form.is_valid():
form.save()
return redirect("ventout")
else:
form = VentForm()
context = {"all_vents": all_vents, "form":form}
return render(request, "ventout.html", context)
Template:
<form class="main__input--form" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="main__input--submit">Vent</button>
</form>
you could install/use "crispy_forms_tags" to make the form look better,
https://django-crispy-forms.readthedocs.io/en/latest/index.html
if you want to go further you could install/use "widget_tweaks"
https://pypi.org/project/django-widget-tweaks/
Your index.html from part should have {{ form }} form tag, as I guess.
Try Using following code
<form class="main__input--form" method="POST">
{% csrf_token %}
{{ form }}
<p class="main__input--text">
<textarea name="content" id="content" class="main__input--content"
cols="35" rows="8" aria-label="Entry content" placeholder="Enter text here...">
</textarea>
</p>
<button class="main__input--submit" type="submit" value="Submit">Vent</button>
</form>

django form populate multiple identical field form in one submit

I don't want to use django form class as they will not give me much flexibility.
I have a form where will random number field in easy request. i am trying to populate the multiple value of forms that appears.
this is my models.py
class Profile(models.Model):
name = models.CharField(max_length=100)
photo = models.FileField()
and this my form.html
<form method="POST" action="{% url 'form' %}">
{% csrf_token %}
{% for i in range %}
<input type="text" id="name" name="name"><br>
<input type="file" id="photo" name="photo"><br><br>
{% endfor %}
<input type="submit" value="Submit">
</form>
You may notice I am rendering field with for loop.
that is means, there will be as much field as possible can be appear based on user request.
So I want to populate these models.
my view looks like
def form_view(request):
if request.method == 'POST':
# Need to puplate the form
return render(request, 'form.html', {'range': range(40)})
Can anyone please help me how can i achieve this? i am just struggling to achieve this.
you can use modelformset_factory for this. this way,
in your views.py
from .models import Profile
from django.forms import modelformset_factory
def form_view(request):
form_range = 40 # set the range here
ProfileFormSet = modelformset_factory(Profile, fields=("name", "photo"), extra=form_range, max_num=form_range)
formset = ProfileFormSet(request.POST or None)
if request.method == "POST":
if formset.is_valid():
formset.save()
return render(request, "form.html", {"profile_formset": formset})
and in your form html
<form method="POST" action="{% url 'form' %}">
{% csrf_token %}
{{ profile_formset.as_p }}
<input type="submit" value="Submit">
</form>

How do you render form from views in template without model?

I have a problem with my Django Code.I'm trying to render a form from views to template and i'm just seeing the submit button. I noticed that we can use forms dynamically by introducing it like this {{ form }}, but when I use it, I just see the "submit" button on the page(Sorry I don't know how to upload a local image here). I join my four files: views.py, home.html, forms.py and urls.py
Thank you in advance
home.html
<form method="POST" novalidate action="/config">
{% csrf_token %}
<fieldset>
<legend class="border-bottom mb-4">Home</legend>
{{ form.as_p }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Sign Up</button>
</div>
</form>
views.py
def inputHome(request):
form = InputHomeForm()
if request.method == 'POST':
form = InputHomeForm(request.POST)
if form.is_valid():
mk = form.cleaned_data['mk']
return HttpResponseRedirect('blog-config')
else:
form = InputHomeForm()
return render(request, 'blog/home.html', {'form': form})
forms.py
class InputHomeForm(forms.Form):
mk = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
urls.py
urlpatterns = [
path('home/', blog_views.home, name='blog-home'),
]
I don't have an error message so i don't have an idea of the problem.
You are missing form tag in html.
HTML should be,
<form method='post'>
{% csrf_token %}
<fieldset>
<legend class="border-bottom mb-4">Home</legend>
{{ form.as_p }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Sign Up</button>
</div>
</form>
Slightly unrelated (cf Nishant's answer for the main issue), but here:
if request.method == 'POST':
form = InputHomeForm(request.POST)
if form.is_valid():
mk = form.cleaned_data['mk']
return HttpResponseRedirect('blog-config')
else:
form = InputHomeForm()
In the else clause, you're replacing the bound invalid form (which carries the validation errors) with an unbound form, so you'll never get the error messages. Just remove the whole else clause.

How to generate a form in Django like in the admin?

I'm using the app geoposition and when I enter in the admin I can see a form like this one:
http://i.imgur.com/kb3Fqm3.png
This is the repo of the app that I'm using: https://github.com/philippbosch/django-geoposition
When I create the form it appears empty in the browser, this my code:
views.py
from geoposition.forms import GeopositionField
def add_route(request):
form = GeopositionField()
args = {}
args = dict(form=form)
return render_to_response("gestion/add_route.html", args)
add_route.html
<form method="POST" action="">{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
</form>
How I can solve it?
views.py
from django import forms
from geoposition.forms import GeopositionField
from django.shortcuts import render_to_response
class TestForm(forms.Form):
geo_position_field = GeopositionField()
def add_route(request):
form = TestForm(request.POST)
return render_to_response("gestion/add_route.html", {'form': form})
add_route.html:
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
also you can use this document to know more about django forms basics.

Django CSRF verification failed on post method

I dont understand this one...
the token is in the template and the 'django.middleware.csrf.CsrfViewMiddleware' is define in MIDDLEWARE_CLASSES
views.py:
from django.shortcuts import render_to_response
from ezmapping.models import *
from django.forms.models import modelformset_factory
def setMapOptions(request):
ezMapFormSet = modelformset_factory(ezMap, fields=('map_name', 'zoom_level', 'center_lat', 'center_long', 'map_width', 'map_height'))
if request.method == 'POST':
formset = ezMapFormSet(request.POST, request.FILES)
if formset.is_valid():
formset.save()
else:
formset = ezMapFormSet(queryset=ezMap.objects.filter(map_name ='first test'))
return render_to_response("ezmapping/manage_mapOptions.html", {'formset': formset,})
template:
<html>
<head>
<title>Manage Map Options</title>
</head>
<body>
<h1>Define map options</h1>
<form method="post" action="">{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
<input type="submit" value="Submit" />
</form>
</body>
</html>
You need to use RequestContext to use the CSRF tags.
https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext
context = RequestContext(request, {
'foo': 'bar',
})
# or
render_to_response('foo.html', {}, context_instance=RequestContext(request))
RequestContext takes the request object and loads all kinds of variables automatically, including CSRF.