I have a problem in my Django form. When I click the submit button in my form, no data is saved to the database. I found that the data was bound but it did not pass through the form.is_valid() function. Below is the code for forms.py, views.py, urls.py and new-event.html respectively:
forms.py
from django import forms
class EventForm(forms.Form):
name = forms.CharField(label='event-name',
max_length=50,
widget=forms.TextInput(attrs={'class': 'form-control', 'id': 'event-name', 'name': 'event-name'}))
start_datetime = forms.DateTimeField(
widget=forms.DateTimeInput(attrs={'class': 'form-control', 'id': 'start-datetime', 'name': 'start-datetime', 'type': 'datetime-local'}))
end_datetime = forms.DateTimeField(
widget=forms.DateTimeInput(attrs={'class': 'form-control', 'id': 'end-datetime', 'name': 'end-datetime', 'type': 'datetime-local'}))
event_category = forms.ChoiceField(widget=forms.Select(attrs={'class': 'custom-select', 'id': 'event-type'}),
choices=((None, 'Please select an option'), ('Daily Life', 'Daily Life'), ('Study', 'Study'), ('Social', 'Social'), ('Work', 'Work')))
description = forms.CharField(max_length=250, widget=forms.Textarea(attrs={'class': 'form-control', 'id': 'description', 'name': 'description'}), required=False)
views.py
from django.shortcuts import render, redirect
from .models import Entry
from .forms import EventForm
from django.views.decorators.http import require_POST
# request is required that represents HttpResponse
# return value can be response, JSON or template
def index(request):
entries = Entry.objects.order_by('-date_added')
context = {'entries': entries}
return render(request, 'event/list-events.html', context)
def new_event(request):
form = EventForm()
context = {'form': form}
return render(request, 'event/new-event.html', context)
#require_POST
def add_event(request):
if request.method == 'POST':
form = EventForm(request.POST)
if form.is_bound: print('form is bound')
else: print('form is unbound')
if form.is_valid():
print('form is valid')
new_entry = Entry(name=form.cleaned_data['name'], start_datetime=form.cleaned_data['start_datetime'],
end_datetime=form.cleaned_data['end_datetime'], category=form.cleaned_data['event_category'],
description=form.cleaned_data['description'])
new_entry.save()
else:
print('form is invalid')
return render(request, 'event/new-event.html', {'form': form})
return redirect('index')
# else:
# form = EventForm()
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('new-event/', views.new_event, name='new_event'),
path('add-event/', views.add_event, name='add_event')
]
new-event.html
{% extends 'todo/base.html' %}
{% block title %}New Entry{% endblock %}
{% block content %}
<form action="{% url 'add_event' %}" method="POST" class="container-fluid">
{% csrf_token %}
<div class="form-group row">
<label for="event-name" class="col-sm-2 col-form-label">Event</label>
<div class="col-sm-10">
{{ form.name }}
</div>
</div>
<div class="form-group row">
<label for="event-type" class="col-sm-2 col-form-label">Event type</label>
<div class="col-sm-10">
{{ form.event_category }}
</div>
</div>
<div class="form-group row">
<label for="start-datetime" class="col-sm-2 col-form-label">Start Time</label>
<div class="col-sm-10">
{{ form.start_datetime }}
</div>
</div>
<div class="form-group row">
<label for="end-datetime" class="col-sm-2 col-form-label">End Time</label>
<div class="col-sm-10">
{{ form.end_datetime }}
</div>
</div>
<div class="form-group">
{{ form.description }}
</div>
<input type="submit" name="submit" value="Submit" class="btn btn-primary">
</form>
{% endblock %}
The output on my terminal is: form is bound form is invalid... I am sure that I do not fall into the confusion of concepts between bound and instance. Could anyone give me some tips on how this occurs?
I'm not sure why you think that this is a problem. Your form was correctly bound to the POST data; then, that data was validated, and found not to pass the validation.
To see why - and allow the user to correct the issue - you should output {{ form.errors }} on your template, or use the individual errors attributes for each field, eg {{ form.name.errors }} etc.
Related
Good day,
I am making a Django application,
I want to call my data that the user signs up with and to display the information they submitted as:
Name
Email
Then I want to be able to change that data and then I want to save it, and reload back into the dashboard, but when I am updating my 'update_profile.html' the info is not updating, I can; add form data and change it
What am I doing wrong?
My code below:
views.py
from django.shortcuts import render, redirect, HttpResponse
from django.contrib import messages, auth
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from contacts.models import Contact
def register(request):
if request.method == 'POST':
# Get form values
first_name = request.POST['first_name']
last_name = request.POST['last_name']
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
password2 = request.POST['password2']
# Check if passwords match
if password == password2:
# Check username
if User.objects.filter(username=username).exists():
messages.error(request, 'That username is taken')
return redirect('register')
else:
if User.objects.filter(email=email).exists():
messages.error(request, 'That email is being used')
return redirect('register')
else:
# Looks good
user = User.objects.create_user(
username=username, password=password, email=email, first_name=first_name, last_name=last_name) # noqa
# Login after register
auth.login(request, user)
messages.success(request, 'You are now logged in')
return redirect('index')
# user.save()
# messages.success(
# request, 'You are now registered and can log in')
# return redirect('login')
else:
messages.error(request, 'Passwords do not match')
return redirect('register')
else:
return render(request, 'accounts/register.html')
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
messages.success(request, 'You are now logged in')
return redirect('dashboard')
else:
messages.error(request, 'Invalid credentials')
return redirect('login')
else:
return render(request, 'accounts/login.html')
def logout(request):
if request.method == 'POST':
auth.logout(request)
messages.success(request, 'You are now logged out')
return redirect('index')
#login_required(login_url='login')
def dashboard(request):
user_contacts = Contact.objects.order_by(
'-contact_date').filter(user_id=request.user.id)
context = {
'contacts': user_contacts
}
return render(request, 'accounts/dashboard.html', context)
#login_required(login_url='login')
def edit_profile(request, pk):
user = User.objects.get(id=pk)
if request.method == 'POST':
...
user.name = request.GET['name']
user.email_address = request.GET['email_address']
user.save()
return redirect('dashboard')
context = {
'user': user
}
return render(request, 'accounts/dashboard.html', context)
#login_required(login_url='login')
def delete_profile(request, pk):
user = User.objects.get(id=pk)
if request.method == 'POST':
...
user.name = request.GET['name']
user.email_address = request.GET['email_address']
user.delete()
return redirect('index')
context = {
'user': user
}
return render(request, 'index.html', context)
Then my urls
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('register', views.register, name='register'),
path('login', views.login, name='login'),
path('logout', views.logout, name='logout'),
path('dashboard', views.dashboard, name='dashboard'),
path('edit_profile/<int:pk>/', views.edit_profile, name='edit_profile'),
]
Lastly My edit_profile.html
{% extends 'base.html' %}
{% block title %} | Edit Profile {% endblock %}
{% block content %}
<section id="showcase-inner" class="py-5 text-white">
<div class="container">
<div class="row text-center">
<div class="col-md-12">
<h1 class="display-4">User Dashboard</h1>
<p class="lead">Manage your BT Real Estate account</p>
</div>
</div>
</div>
</section>
<!-- Breadcrumb -->
<section id="bc" class="mt-3">
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{% url 'index' %}">
<i class="fas fa-home"></i> Home</a>
</li>
<li class="breadcrumb-item active"> Dashboard</li>
</ol>
</nav>
</div>
</section>
{% comment %} Alerts {% endcomment %}
{% include 'partials/__alerts.html' %}
<section id="dashboard" class="py-4">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>Welcome {{ user.first_name }}
<a class="btn btn-info" href="{% url 'dashboard' %}">
Save Profile
</a>
<a class="btn btn-da nger" href="{% url 'dashboard' %}">
Del;ete Profile
</a>
</h2>
<h3>Account Details: </h3>
<form action="{% url 'contact' %}" method="POST">
{% csrf_token %}
{% if user.is_authenticated %}
<input type="hidden" name="user_id" value="{{ user.id }}">
{% else %}
<input type="hidden" name="user_id" value="0">
{% endif %}
<input type="hidden" name="realtor_email" value="{{ listing.realtor.email }}">
<input type="hidden" name="listing_id" value="{{ listing.id }}">
<div class="form-group">
<label for="property_name" class="col-form-label">Property:</label>
<input type="text" name="listing" class="form-control" value="{{ listing.title }}" >
</div>
<div class="form-group">
<label for="name" class="col-form-label">Name:</label>
<input type="text" name="name" class="form-control" {% if user.is_authenticated %} value="{{ user.first_name }} {{ user.last_name }}" {% endif %} required>
</div>
<div class="form-group">
<label for="email" class="col-form-label">Email:</label>
<input type="email" name="email" class="form-control" {% if user.is_authenticated %} value="{{ user.email }}" {% endif %} required>
</div>
<div class="form-group">
<label for="phone" class="col-form-label">Phone:</label>
<input type="phone" name="phone" class="form-control" {% if user.is_authenticated %} value="{{ user.phone }}" {% endif %} >
</div>
<input type="submit" value="Send" class="btn btn-block btn-secondary">
</form>
</div>
</div>
</div>
</section>
{% endblock %}
PLEASE HELP!
I have a comment model in my forum and when I try to submit it it says:
"Page not found - /POST?csrfmiddlewaretoken".
views.py:
#login_required
def comment(request, pk):
if request.method == 'POST':
form = CommentCreationForm(data=request.POST)
if form.is_valid():
comment.post = get_object_or_404(Post, pk=pk)
comment.writer = request.user
comment = form.save()
messages.info(request, 'comment published')
return JsonResponse({'message': 'Thank you for your comment'}, safe=False)
else:
form = CommentCreationForm()
html file:
<form action="POST"> {% csrf_token %}
{{ form.text.errors }}
<label for="{{ form.text.id_for_label }}">comment:</label>
{{ form.text }}
<button id="comment" type="submit">comment</button>
</form>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
urls.py:
path('<int:pk>/comment/', views.comment, name='comment'),
By the way, can you help me make it in ajax?
You have to add url to the attribute action and POST to method attribute:
<form action="{% url 'comment' post.pk %}" method="POST"> {% csrf_token %}
{{ form.text.errors }}
<label for="{{ form.text.id_for_label }}">comment:</label>
{{ form.text }}
<button id="comment" type="submit">comment</button>
</form>
Also provide post.pk in {% url 'comment' post.pk %}.
I am trying to use a ModelForm to save objects to the database. I have also added an ImageField. Through the admin panel, I am easily able to add objects with an image but every time I submit the ModelForm with the same image it doesn't get saved and returns an error saying "This field is required" (screenshot and code attached).
How do I fix this?
Here's a screenshot of the error:
The models file:
from django.db import models
from django.conf import settings
class Book(models.Model):
rel_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="Posted By")
image = models.ImageField(verbose_name="Image", upload_to="static/Books/img")
title = models.CharField(max_length=256, verbose_name="Title")
description = models.TextField(verbose_name="Description")
price = models.IntegerField(verbose_name="Price")
state = models.CharField(max_length=256, verbose_name="State")
city = models.CharField(max_length=256, verbose_name="City")
neighbourhood = models.CharField(max_length=256, verbose_name="Neighbourhood")
phone = models.IntegerField(verbose_name="Phone Number")
def __str__(self):
return self.title + f" ({self.rel_user.username})"
The forms file:
from django.forms import ModelForm
from Books.models import Book
class BookForm(ModelForm):
class Meta:
model = Book
fields = ['image', 'title', 'description', 'price', 'state', 'city', 'neighbourhood', 'phone']
The views file:
from django.shortcuts import render, redirect
from Books.forms import BookForm
from django.contrib import messages
from Books.models import Book
def sell(request):
if request.method == "GET":
form = BookForm()
else:
form = BookForm(request.POST)
form.instance.rel_user = request.user
if form.is_valid():
form.save()
messages.success(request, "Successfully added!")
return redirect('sell')
else:
messages.error(request, "Please fill in all the fields.")
return render(request, 'Books/sell.html', {"form": form})
The HTML code:
<div class="container" style="padding: 2%">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12"></div>
<div class="col-md-4 col-sm-4 col-xs-12" style="background-color: rgba(256, 256, 256, 0.8);">
{% if messages %}
{% for message in messages %}
<div class="alert alert-primary" role="alert" style="margin-top: 2%;">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="POST" action="{% url 'sell' %}">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Sell A Book</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Submit
</button>
</div>
</form>
</div>
<div class="col-md-4 col-sm-4 col-xs-12"></div>
</div>
</div>
from Books.forms import BookForm
from django.contrib import messages
from Books.models import Book
def sell(request):
if request.method == "GET":
form = BookForm()
else:
form = BookForm(request.POST,request.FILES)
form.instance.rel_user = request.user
if form.is_valid():
form.save()
messages.success(request, "Successfully added!")
return redirect('sell')
else:
messages.error(request, "Please fill in all the fields.")
return render(request, 'Books/sell.html', {"form": form})```
<div class="container" style="padding: 2%">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12"></div>
<div class="col-md-4 col-sm-4 col-xs-12" style="background-color:rgba(256, 256, 256, 0.8);">
{% if messages %}
{% for message in messages %}
<div class="alert alert-primary" role="alert" style="margin-top: 2%;">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="POST" action="{% url 'sell' %}"enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Sell A Book</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Submit
</button>
</div>
</form>
</div>
<div class="col-md-4 col-sm-4 col-xs-12"></div>
</div>
</div>
I have a model.py:
class Author(models.Model):
Author= models.CharField(max_length=500) ##field required
and a form.py:
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
widgets = {
'Author': TextInput(attrs={'class':'form-control', 'placeholder': 'Author...'}),
in template I render whit:
{{ form.Author }}
Form works but if I try to save leave the field empty it not display any error.
I try with
{{ form.Author.errors }}
but nothing appear!
Any idea?
TY
UPGRADE 1
simple view:
#login_required
def auth_reg(request):
if request.method == "POST":
form = AuthorForm(request.POST)
if form.is_valid():
member = form.save()
return redirect('home')
else: form = AuthorForm()
return render(request, auth_reg.html', {'form': form})
and simple template:
{% extends 'base.html' %}
{% block content %}
<div id="page-content-wrapper">
<form method="post">
{% csrf_token %}
<div id="page-title">
<h2>Registration</h2>
</div>
<div class="content-box-wrapper">
<div class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">Author</label>
<div class="col-sm-3">
{{ form.Author}}
</div>
</div>
</div>
</div>
</div>
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">