I'm working on a single page site which is to have 3 different forms on the same page:
Tour form
flight form
bookform
I created the forms using model form, but how do I display the forms such that my site will know which form I'm submitting data to ?
you need pass your forms in your views.py
from your_app.forms import TourForm, FlightForm, BookForm
def your_view_name(request):
if request.method == 'POST':
tour_form = TourForm(request.POST or None)
flight_form = FlightForm(request.POST or None)
book_form = BookForm(request.POST or None)
# so you have 3 different forms
if tour_form.is_valid():
tour_form.save()
return redirect('some_url')
elif flight_form.is_valid():
flight_form.save()
return redirect('some_url')
elif book_form.is_valid():
book_form.is_save()
return redirect('some_url')
else:
return redirect('some_url')
else:
tour_form = TourForm()
flight_form = FlightForm()
book_form = BookForm()
context = {
'tour_form': tour_form,
'flight_form': flight_form,
'book_form': book_form
}
return render(request, 'your_template_name.html', context)
then simply in your template add your forms
<form method='post'>
{% csrf_token %}
{{ tour_form }}
<button class='btn btn-primary' type='submit'>submit</button>
</form>
<form method='post'>
{% csrf_token %}
{{ flight_form }}
<button class='btn btn-primary' type='submit'>submit</button>
</form>
<form method='post'>
{% csrf_token %}
{{ book_form }}
<button class='btn btn-primary' type='submit'>submit</button>
</form>
Related
My form is not saving to the database or at least i know the form is not valid i just dont know why? because it will always skip to the else in the if form.is_valid() (print("didnt work!"))
the view.py:
def index(request):
component = Component.objects.all()
form = ComponentModelForm()
if request.method == 'POST':
form = ComponentModelForm(request.POST)
if form.is_valid():
form.save()
return redirect('/maintenance')
else:
form = ComponentModelForm()
print("didnt work!")
context = {
'components': component,
'form': form,
}
return render(request, 'maintenance/index.html', context)
forms.py:
class ComponentModelForm(forms.ModelForm):
note = forms.CharField(widget=forms.Textarea)
image = forms.ImageField(error_messages = {'invalid':("Image files only")}, widget=forms.FileInput)
class Meta:
model = Component
fields = ("name",
"manufacturer",
"model",
"serial_number",
"price",
"note",
"image",
"parent",)
the template form:
{% load widget_tweaks %}
<form class="component-update-grid" enctype="multipart/form-data" method='POST' action=''>
{% csrf_token %}
<div class="component-form-data">
<span class="component-label-text">Name</span>
{% render_field form.name class="component-form-data-inputs" %}
<span class="component-label-text">Manufacturer</span>
{% render_field form.manufacturer class="component-form-data-inputs" %}
<span class="component-label-text">Model</span>
{% render_field form.model class="component-form-data-inputs" %}
<span class="component-label-text">Serial Number</span>
{% render_field form.serial_number class="component-form-data-inputs" %}
<span class="component-label-text">Price</span>
{% render_field form.price class="component-form-data-inputs" %}
<span class="component-label-text">Note</span>
{% render_field form.note class="component-form-data-inputs" %}
{% render_field form.parent class="component-form-data-inputs " %}
<input type="submit" class="button1" value='Create Component' />
</div>
<div class="component-form-img">
<img class="maintenance-component-img" src='{%static 'imgs/sidebar/logo.png'%} ' />
{% render_field form.image %}
</div>
</form>
You should not construct a new form when the form fails: a failed form will render the errors, such that the user knows what is going wrong, so:
def index(request):
component = Component.objects.all()
form = ComponentModelForm()
if request.method == 'POST':
form = ComponentModelForm(request.POST)
if form.is_valid():
form.save()
return redirect('/maintenance')
else:
# Don't create a new form!
print("didnt work!")
context = {
'components': component,
'form': form,
}
return render(request, 'maintenance/index.html', context)
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>
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.
My file is being uploaded in the correct path but I have an issues with it:
Whenever I refresh my HTML page the file gets uploaded again and again. How do I solve this? Also
Please help me with the code or suggest me.
Thanks in advance:)
My views.py
def about_experiment(request, ex_link_name):
researcher = None
study = None
posts = None
exp = get_object_or_404(Experiment,link_name = ex_link_name)
high_scores = ScoreItem.objects.filter(experiment=exp,active=True)
context = {
'request': request,
'exp':exp,
'high_scores': high_scores,
'awards':AwardItem.objects.filter(experiment=exp,visible=True),
}
if exp.about_file:
context['about_file'] = settings.EXPERIMENT_DIRS+exp.about_file.get_include_path()
return render(request, 'about_experiment.html', context)
if request.method == 'POST':
form = AboutHelp(request.POST, request.FILES)
posts = Help.objects.filter().order_by('-date')[0]
documents = Help.objects.all()
if form.is_valid():
obj = form.save(commit = False)
obj.save()
researcher = form.cleaned_data['researcher']
study = form.cleaned_data['study']
document = form.cleaned_data['document']
else:
form = AboutHelp()
posts = Help.objects.filter().order_by('-date')[0]
documents = Help.objects.all()
return render(request, 'about_experiment.html', {'posts': posts})
return render(request, 'about_experiment.html', {'posts': posts})
Source page
<form action="{% url 'lazer.views.about_experiment' exp.link_name %}" method="POST" name="form" enctype="multipart/form-data">
{% csrf_token %}
<label>Researcher Name(s):
<input type="text" name="researcher"><br>
<lable>Study Summary
<textarea rows="10" cols="50" placeholder="Start typing..." maxlength="500" class="form-control" name="study"></textarea>
<br>
<label>Upload your IRB approval letter:
<input type ="file" id="irb-file" class="file_input" name="document"></label>
<br>
<input type = "submit" value="Submit" class="btn btn-primary" />
</form>
destination page
<div class="tab-pane" id="irb">
<h4> List of file(s) uploaded:</h4>
<!--File upload-->
{% if documents %}
<ul>
{% for file in documents %}
<li> {{ file.document.name }} </li>
{% endfor %}
</ul>
{% else %}
<p>No such documents available.</p>
{% endif %}
<!--File upload ends-->
</div>
{% if high_scores %}
{% for hs in high_scores %}
<div class="tab-pane" id="{{ hs.link_name }}">
{% high_score request exp.link_name hs.link_name %}
</div>
{% endfor %}
{% endif %}
As #almost a beginner pointed out, you should be redirecting to some other view, if your form is submitted successfully. If not, (in your case), when the page reloads, the code for POST request is executed again. ie, your form is submitted again. I could suggest some changes in your view,
def about_experiment(request, ex_link_name):
exp = get_object_or_404(Experiment,link_name = ex_link_name)
high_scores = ScoreItem.objects.filter(experiment=exp,active=True)
context = {
'request': request,
'exp':exp,
'high_scores': high_scores,
'awards':AwardItem.objects.filter(experiment=exp,visible=True),
'posts':Help.objects.filter().order_by('-date')[0],
'documents':Help.objects.all()
}
if exp.about_file:
context['about_file'] = settings.EXPERIMENT_DIRS+exp.about_file.get_include_path()
if request.method == 'POST':
form = AboutHelp(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit = False)
obj.save()
return redirect(reverse('lazer.views.about_experiment', kwargs={ 'ex_link_name':obj.link_name }))
else:
form = AboutHelp()
return render(request, 'about_experiment.html', context)
Here, I merely assumed your obj has a field link_name. You may need to change that according to your models.
I am trying to authenticate a user(using the simple authenticate() function) in django.
def auth(request):
if request.method == 'POST':
auth_form = AuthenticationForm(request.POST)
if auth_form.is_valid():
auth_form.save()
user = authenticate(username=request.POST['id_username'],password=request.POST['id_password'])
if user is not None:
login(request,user)
return redirect('/profile/home/')
else:
return redirect('/')
else:
return redirect('/')
def register(request):
if request.method == 'POST':
form = SimpleUserCreation(request.POST)
if form.is_valid():
form.save()
user = authenticate(username=request.POST['id_username'],password=request.POST['id_password1'])
login(request,user)
return redirect('/profile/home/')
else:
return redirect('/')
This is the template displaying the forms - Just wanted to display login and register forms in the same page(for this example)
{% extends 'base.html' %}
{% load bootstrap_toolkit %}
{% block content %}
<div class="row">
<div class="span4 offset1 login">
<form class="form-signin" action="/auth/" method="POST">
{% csrf_token %}
{{ auth_form|as_bootstrap }}
<br>
<center>
<button class="btn btn-large btn-primary" type="submit">
Sign In
</button>
</center>
</form>
</div>
<div class="span4 offset2 signup">
<form action="/register/" method="POST">
{% csrf_token %}
{{ form|as_bootstrap }}
<br>
<center>
<button class="btn btn-large btn-primary" type="submit">
Register
</button>
</center>
</form>
</div>
</div>
{% endblock %}
I am getting an error like this:
ValueError at /auth/
The view SimpleUserAuth.auth.views.auth didn't return an HttpResponse object.
Any idea where i am going wrong?? I think its the authenticating function's inability to find the correct id for the fields...maybe i am wrong. I am a Noob :|
Cheers
In your auth method, if auth_form.is_valid() returns False, you do not return a response object.
The same is the case in def register(request): . If it is a GET request, the method does not return a response object.
Hence the error(s)
I made the mistake in these lines -
1) AuthenticationForm takes argument as follows:
AuthenticationForm(data=request.POST)
2) u can't save AuthenticationForm.
auth_form = AuthenticationForm(request.POST)
if auth_form.is_valid():
auth_form.save()
Thanks for the help karthik :)