I am new to Django and looking to build a quick form with a response.
I am trying to build a form which would ask the user to input his name when the user clicks submit the page should reload and just say "Hello .
urls.py
class Question1Form(forms.Form):
n = forms.CharField(max_length=100,
widget=forms.TextInput(
attrs={'placeholder': 'Number', 'class': 'form-control'}))
views.py
def home(request):
if request.method == 'POST':
form = Question1Form(request.POST)
if form.is_valid():
result = [Question1Form.ans()]
return HttpResponse(Question1Form.n)
else:
form = Question1Form()
return render(request, 'index.html', {'form': form})
index.html
<form action="" method="post" class="form">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="form-row form">
<div class="col-sm-4">
{{ form.n.errors }}
{{ form.n }}
</div>
<input class="btn btn-primary" type="submit" value="Submit" />
</div>
</form>
So how the code s
You should call instance field, not class field and get value from validated(cleaned) data (see documentation):
return HttpResponse(form.cleaned_data['n'])
If you want to reload the same template with n value:
return render(request, 'index.html', {'form': form, 'n': form.cleaned_data['n']})
and at the template add:
{% if form.is_valid %}
<p> Hello {{ n }} </p>
{% endif %}
if request.method == 'POST':
form = Question1Form(request.POST)
if form.is_valid():
result = form.save()
return render(request, 'index.html', {'created': True})
Then in your HTML you can say
{% if created %}
<p> Hello </p>
{% endif %}
edit I see now you have no action in your form.
So you need to point to that view in your URLS.py.
for example.
from myapp import views as app_views
from django.conf.urls import url
urlpatterns =[
url(r'^my_form/$', app_views.home, name='save_form'),
]
And then add the action to your form.
<form action="{% url 'save_form' %}" method="post" class="form">
Related
why this context not rendering in my html template:
return render(request, 'index.html',{'message_name':name})
This context will print user name after successful submit my contact form. here is my code:
views.py
#csrf_exempt
def home_view(request,*args,**kwargs):
name = None
if request.method == "POST":
contact_form = ContactForm(request.POST)
if contact_form.is_valid():
name = request.POST['name']
email = request.POST['email']
subject = request.POST['subject']
message = request.POST['message']
save_details = Contact(name=name,email=email,subject=subject,message=message)
save_details.save()
return HttpResponseRedirect("http://127.0.0.1:8000/")
return render(request, 'index.html',{'message_name':name})
else:
print("not submitted")
else:
contact_form = ContactForm()
return render(request, 'index.html',{'form':contact_form})
app urls.py
from django.urls import path
from pages import views
urlpatterns = [
path('', views.home_view, name="home"),
]
root urls.py
from django.contrib import admin
from django.urls import path,include
from pages import urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('pages.urls')),
]
index.html
<!--===== CONTACT =====-->
<section class="contact section" id="contact">
<h2 class="section-title">Contact</h2>
{% if message_name %}
<div class="centerTest">
<h1> Thanks {{ message_name }} for your message. We will get back to you very soon</h1>
</div>
{% else %}
<div class="contact__container bd-grid">
<form action="#contact" method = "POST" class="contact__form">
{% for error in form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endfor %}
<label>Name:</label>
{{ form.errors.name }}
<input type="text" placeholder="Name" name="name" class="contact__input" {% if form.is_bound %}value="{{ form.name.value }} {% endif %}">
<label>Email:</label>
{{ form.errors.email }}
<input type="mail" placeholder="Email" name="email" class="contact__input" {% if form.is_bound %}value="{{ form.email.value }} {% endif %}">
<label>Subject:</label>
{{ form.errors.subject }}
<input type="text" placeholder="optional" name="subject" class="contact__input" {% if form.is_bound %}value="{{ form.subject.value }} {% endif %}">
<label>Message:</label>
{{ form.errors.message }}
<textarea name="message" placeholder="message" id="" cols="0" rows="10" class="contact__input" >{% if form.is_bound %}{{ form.message.value }} {% endif %}</textarea>
<input type="submit" value="Send" class="contact__button button">
{% endif %}
if I remove the HttpResponseRedirect then it showing context in my html template
But the problem is it resubmitting my from again and again on refresh. After adding HttpResponseRedirect it stop resubmitting the form but not printing the context.
You can't pass context directly in redirect or HttpResponseRedirect in django. You need to be use session method. Try this:
#csrf_exempt
def home_view(request,*args,**kwargs):
name = None
if request.method == "POST":
contact_form = ContactForm(request.POST)
if contact_form.is_valid():
name = request.POST['name']
email = request.POST['email']
subject = request.POST['subject']
message = request.POST['message']
save_details = Contact(name=name,email=email,subject=subject,message=message)
save_details.save()
request.session['name'] = name
return redirect(home_view)
else:
print("not submitted")
else:
contact_form = ContactForm()
return render(request, 'index.html',{'form':contact_form})
Pass this {{ request.session.name }} in your index.html for show your context.
As a basic Python concept (and probably any other programming language), you cannot have two return sentences, one above the other in a function as the first one will make the second one unreachable.
Example:
def say_hello(name, age):
return f"hello {name}"
return f"your age is {age}"
If you execute this function, you will only get "hello john doe" as the second return statement is never executed.
In your case, if you keep the return HttpResponseRedirect(), the return render() will never be executed, therefore you will never see the context.
If you want to redirect the user to a specific route you should do it conditionally in order to have the chance to execute one return or the other.
This code is for my signup page as you can see action is set for signup
{% block content %}
<form class="form-horizontal" action="signup" method="post">
{% csrf_token %}
{{ form }}
<br />
<input type="submit" value="Sign up" class="btn btn-default" />
</form>
{% endblock %}
This is my views.py in the same app
from django.shortcuts import render
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('app:home')
# log the user in
else:
form = UserCreationForm()
return render(request, 'accounts/signup.html', {'form': form})
This is my url for which doesn't work
path('signup/', accounts_views.signup, name='signup')
I have setup register page by Django. The URL of register input on IE, register page is ok, but I cliked 'register' button on page, no register form display.
enter image description here
users\urls.py
urlpatterns = [
# register page
re_path('^register/$', views.register, name='register'),
]
users\views.py
def register(request):
"""register new user"""
if request.method != 'POST':
# display blank register form
form = UserCreationForm()
else:
# deal filled form
form = UserCreationForm(data=request.POST)
if form.is_valid():
new_user = form.save()
# auto login, and redirect to home page
authenticated_user =authenticate(username=new_user.username,password=request.POST['password1'])
login(request, authenticated_user)
return HttpResponseRedirect(reverse('learning_logs:index'))
context = {'form': form}
return render(request, 'users/register.html', context)
register.html
{% extends "learning_logs/base.html" %}
{% block content %}
<form method="post" action="{% url 'users:register' %}">
{% csrf_token %}
{{ form.as_P }}
<button name="submit">register</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}
These are three methods to render the form.
{{ form.as_table }} will render them as table cells wrapped in tags
{{ form.as_p }} will render them wrapped in tags
{{ form.as_ul }} will render them wrapped in li
You can manually render the form with HTML also but fields name should be the same as the registration form.
Im new with Django and Im trying to include my own form
My forms.py
class MyOwnForm(forms.ModelForm):
class Meta:
model = Album
fields = ['username']
My views.py
def testing_Form(request):
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
username = form.cleaned_data['username']
return render(request, 'form.html', {'form': form})
my form.html
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
and the last one form_template.html
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2" >{{ field.label_tag }}</label>
<div class="col-sm-10">{{ field }}</div>
</div>
{% endfor %}
When I open the Form Webpage, I get a empty entry field and the submit button. But when I click this button. The page is reloading and nothing more.
what do i have to do that i can work with the entered data?
But when I click this button. The page is reloading and nothing more.
Because of this, I'm assuming that you intend to show some information after the form is submitted. Here's a simple example that just displays an acknowledgement after the form is submitted.
{% if submitted %}
<div class="jumbotron contactainer">
<h1 class="display-4">Submitted</h1>
<hr class="my-4">
<p class="lead">{{ username }}'s album has been submitted</p>
</div>
{% else %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
{% endif %}
views.py
def testing_Form(request):
submit = False
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.username = request.user
album.save()
submit = True
username = form.cleaned_data['username']
return render(request, 'form.html', {'username':username, 'submitted':submit})
else:
return render(request, 'form.html', {'form': form, 'submitted':submit})
You can do anything you wish with the username variable or add new variables, just remember to add them to the context dictionary if you wish to display them. The submit variable I've added is used in the template to determine what to show. Hope this helps :)
Not quite sure what you are exactly trying to achieve. However if you want to show the value of your previous submit on your screen for example as: Previous submitted username: <input username>, you can use the defined form in your template, including the values if there was a submit before.
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
You can always add extra context to your template by assigning it to the context dictionary in the similar way you did with the {'form': form} as {'form': form, 'hello': "My hello string"} in your view.
In your template you could now use {{ hello }} as an variable.
Note that you are also using commit=False in your form to add more request data to the model after (user). Currently you left it in the unsaved state. To save the new form entry, you need to call album.save() after the modifications.
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.save() # now commit
The username = form.cleaned_data['username'] has been defined, but never been used. Which with the example above is no longer required.
You can fetch the album objects when the user is authenticated and pass them to the template to work with as context like:
(bad practice style, but just to give you an idea within the scope of your code)
if request.user.is_authenticated:
return render(request, 'login.html')
else:
form = AlbumForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
albums = Album.objects.all()
return render(request, 'formhandle/form.html', {'form': form, 'albums': albums})
Which you could show in your form template as:
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
<ul>
{% for album in albums %}
<li>{{ album.user.username }}</li>
{% endfor %}
</ul>
trying to create a registration form, and I am facing an issue. so, below are my python pages:
form.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(ModelForm):
class Meta:
model = User
fields = ('username','password','email')
models.py
from django.db import models
#from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
class Registration(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
urls.py
urlpatterns = [
url(r'^register/$', views.SignUpFormView, name= 'register'),
]
test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form }}
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
<input type="submit" value="Submit" />
</form>
{% endblock %}
{% endblock %}
views.py
def SignUpFormView(request):
template_name = 'test.html'
try:
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
email = form.cleaned_data.get('email')
return render(request, template_name, {'form':form})
except ValueError:
print("Oops! That was not a valid entry, try again...")
else:
SignUpForm()
return render(request, 'user_info/about.html')
The issue is, my "SignUpFormView" function in views.py is not entering the "if" statement, its directly going to "else". I seem to be lost here.
I have 'about.html'. I do not see any error as well. Which I find very weird. Please help.
Note: I am using Django's default in-built "User" model, and I do not wish to create any custom model.
Modified views.py
def SignUpFormView(request):
user_form = 'SignUpForm'
template_name = 'test.html'
if request.method == 'POST':
form = user_form(request.POST)
if form.is_valid():
form.save()
#username = form.cleaned_data.get('username')
#password = form.cleaned_data.get('password')
#email = form.cleaned_data.get('email')
#user.save()
return render(request, template_name, {'form':form})
else:
SignUpForm()
return render(request, 'user_info/about.html')
Modified forms.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(forms.ModelForm):
#password = forms.Charfield(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username','password','email')
modified test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
{% for error in form.errors %}
{{ form.errors | default_errors }}
{% endfor %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% for field in form %}
<p>
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit" value="Submit">sign up </button>
</form>
{% endblock %}
{% endblock %}