I cannot get my Django form to raise a ValidationError when I try to create a custom field validation. I can see the new hidden input field, but when I try to enter a value it doesn't seem to detect an error.
I also tried def clean(self) instead of clean_honeypot() and that didn't work either.
What am I doing wrong?
forms.py:
from django import forms
class SuggestionForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
suggestion = forms.CharField(widget=forms.Textarea)
honeypot = forms.CharField(required=False, widget=forms.HiddenInput, label="Leave Empty")
def clean_honeypot(self):
honeypot = self.cleaned_data['honeypot']
if len(honeypot) > 0:
raise forms.ValidationError(
'Honeypot should be left empty. Bad bot!'
)
return cleaned_data
views.py:
from django.contrib import messages
from django.core.mail import send_mail
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render
from . import forms
def hello_world(request):
return render(request, 'home.html')
def suggestion_view(request):
form = forms.SuggestionForm()
if request.method == 'POST':
form = forms.SuggestionForm(request.POST)
if form.is_valid():
send_mail(
'Suggestion from {}'.format(form.cleaned_data['name']),
form.cleaned_data['suggestion'],
'{name} <{email}>'.format(**form.cleaned_data),
['leigh.christopher2#gmail.com'])
messages.add_message(request, messages.SUCCESS,
"Thanks for your suggestion")
return HttpResponseRedirect(reverse('suggestion'))
return render(request, 'suggestion_form.html', {'form': form})
template:
{% extends "layout.html" %}
{% load static %}
{% block title %}Suggest an idea!{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<form action="" method="POST">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" class="button">
</form>
</div>
</div>
{% endblock %}
Related
I am working on a Django project and I want to fill out a form and save the data in the db database and then be able to show it on another page, I managed to create the form, following some tutorials, but it does not write me anything in the database. Here's how I currently have things:
forms.py
from django import forms
from .models import AusenciasForm
from django.contrib.auth.models import User
class AusenciasForm(forms.ModelForm):
class Meta:
model = AusenciasFormulario
fields = '__all__'
widgets = {'fecha': forms.DateInput(attrs={'type': 'date'})}
models.py
from django.db import models
from django.utils import timezone
import datetime
from django.contrib.auth.models import User
from django.urls import reverse
class AusenciasFormulario(models.Model):
#razon = models.ModelChoiceField(label="Razón", queryset=razones.object.all())
fecha = models.DateField(("Date"),default=datetime.date.today)#label="Fecha", required=True
razon = [
('Estudios/Examen','Estudios/Examen'),
('Enfermedad','Enfermedad'),
('Lesión','Lesión'),
('Motivos personales','Motivos personales'),
('Motivos familiares','Motivos familiares'),
('Otros','Otros')
]
motivo = models.CharField(max_length=100, choices=razon, default='Otros')
comentarios= models.CharField(max_length=200,blank=True)
jugador = User
views.py
class FormularioAusenciaView(HttpRequest):
def index(request):
ausencias_formulario = AuForm.objects.all()
return render(request, 'blog/ausencias.html', {'ausencias_formulario':ausencias_formulario})
def procesar_formulario(request):
#if request.method == 'POST':
form = AusenciasForm(request.POST)
if form.is_valid():
form.save()
form = AusenciasForm()
return HttpResponseRedirect('ausencias/') #Add your route name, where you want to go after form save
else:
form = AusenciasForm()
return render(request, 'blog/formularioAusencia.html', {'form':form})
Urls.py
from django.urls import path
from .views import PostListView, PostDetailView, PostCreateView, PostUpdateView, PostDeleteView,UserPostListView, FormularioAusenciaView, ausencias
from .import views
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('', login_required(PostListView.as_view()), name='blog-home'),
path('user/<str:username>',login_required( UserPostListView.as_view()), name='user-posts'),
path('post/<int:pk>/',login_required( PostDetailView.as_view()), name='post-detail'),
path('post/new/',login_required( PostCreateView.as_view()), name='post-create'),
path('post/<int:pk>/update/',login_required( PostUpdateView.as_view()), name='post-update'),
path('post/<int:pk>/delete/',login_required( PostDeleteView.as_view()), name='post-delete'),
path('about/', views.about, name='blog-about'),
path('formularioAusencia/',login_required( FormularioAusenciaView.index), name='formularioAusencia'),
#path('asistencia_done/',formularioAusencia, name='asistencia_done'),
path('ausencias/',login_required( views.ausencias), name='ausencias'),
]
the template
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.email }}</p>
</div>
</div>
{% if user.is_authenticated %}
<p></p><a class="mr-2">Rellenar si no vas a poder acudir a un próximo entrenamiento o partido</a></p>
<!--<label><input type="checkbox" id="cbox1" value="first_checkbox"></label><br>-->
<form method="POST" action="{% url 'ausencias' %}">{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-danger btn-sm mt-1 mb-1" type="submit">Enviar</button>
</form>
</div>
<div class="form-group">
</div>
{% endif %}
</div>
{% endblock content %}
In forms.py:
You have imported wrong model name:
change this
from .models import AusenciasForm
To this:
from .models import AusenciasFormulario
And in views.py file:
You have not added any orm query so that's why it is not saving in db.
views.py :
Do this:
def index(request):
ausencias_formulario = AusenciasFormulario.objects.all() #Here i have retrieved data using orm
return render(request, 'blog/formularioAusencia.html', {'ausencias_formulario':ausencias_formulario})
def procesar_formulario(request):
if request.method == 'POST':
form = AusenciasForm()
if form.is_valid():
form.save()
return HttpResponseRedirect('/home/') #Add your route name, where you want to go after form save
else:
form = AusenciasForm()
return render(request, 'blog/formularioAusencia.html', {'form':form})
And in your templates:
formularioAusencia.html
<form method='post'>
{{form}}
<input type="submit" /> #Added new code here
</form>
After submitting above form, using below code, you will get that fields.
Add below code after the form tag.
To display all the fields to templates add the below code in template:
{% for field in ausencias_formulario %}
{{field.fecha}}
#Add remaining fields here to display
{% endfor %}
I am building an todo app with Register, Login, Logout functionalities, I created a TaskForm to let user create their tasks, but when is click add it gives an
IntegrityError at / NOT NULL constraint failed: tasks_task.user_id
I tried many different approaches but it gives the same error
it works when i add user in fields in TaskForm but it creates a Dropdown list of All users
tasks/models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Task(models.Model):
name = models.CharField(max_length=200)
completed = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="tasks")
def __str__(self):
return f"{self.name}:{self.user}"
tasks/forms.py
from django import forms
from .models import Task
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = [
'name',
]
tasks/views.py
from django.shortcuts import render, redirect
from .forms import TaskForm
from .models import Task
from django.contrib.auth.decorators import login_required
# Create your views here.
#login_required
def home(request):
tasks = Task.objects.all()
if request.method == "POST":
form = TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
form = TaskForm()
context = {
'tasks': tasks,
'form': form,
}
return render(request, "tasks/home.html", context )
tasks/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name= 'home' )
]
home.html
{% extends 'users/layout.html' %}
{% load crispy_forms_tags %}
{% block body %}
<div class="container pt-5 ">
{% if user.is_authenticated %}
<p style="text: 'center'">User: {{ user.get_username }}</p>
<div class="container">
<form method="post">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4" >Create Task</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add</button>
</div>
</form>
</div>
{% else %}
Login Here
{% endif %}
<div class = "container">
<ul>
{% for task in tasks %}
{% if task in user.tasks.all %}
<li>{{ task.name }}</li>
{% endif %}
{% empty %}
<li>No Tasks for Today</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}
forms.py
from django import forms
from .models import Task
class TaskForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
task = super(TaskForm, self).__init__(*args, **kwargs)
self.fields['user'].required = False
class Meta:
model = Task
fields = [
'name',
'user'
]
views.py
# You can save the user with form object then
#login_required
def home(request):
tasks = Task.objects.all()
if request.method == "POST":
form = TaskForm(request.POST)
if form.is_valid():
form_obj = form.save(commit=False)
form_obj.user = request.user
form.save()
return redirect('home')
form = TaskForm()
context = {
'tasks': tasks,
'form': form,
}
return render(request, "tasks/home.html", context )
def login(request):
if request.method=='POST':
user = auth.authenticate(username=request.POST['username'],password=request.POST['password1'])
if user is not None:
auth.login(request,user)
return redirect('../')
else:
return render(request,'login.html',{'error':'username or password is wrong'})
else:
return render(request,'login.html')
You need to define your login form that is to be passed to the template.
For example:
forms.py
class LoginForm(forms.Form):
username = forms.CharField(label='Your Email/Username', max_length=100)
password = forms.CharField(label='Your Password', max_length=100)
Then in your views.py, you can define a view function as:
views.py
from .forms import LoginForm
def login(request):
if request.method == "POST":
if form.is_valid:
user = auth.authenticate(username=request.POST['username'],password=request.POST['password1'])
if user is not None:
auth.login(request,user)
return redirect('../')
else:
return render(request,'login.html',{'form': form, 'error':'username or password is wrong'})
else:
form = LoginForm()
return render(request,'login.html', {'form': form})
Then in your template, you can render the form as:
<form method="post">
{% csrf_token %}
{{ form.as_p }} <--render the form in other ways as preferred-->
{% for error in form.errors %} //for displaying the fields where errors have occured
{{ error }}
{% endfor %}
<button type="submit">Login</button>
</form>
you can use django inbuilt loginview:-
in urls.py
from django.contrib.auth.views import LoginView
urlpatterns =[
path('login/' , LoginView.as_view(template_name='login.html') , name ='login')
]
in ur login.html
<h1> login page!! </h1>
<form method='POST'>
{% csrf_token %}
{{ form.as_p }}
<input type='submit' value='Login'>
</form>
I am trying to get data from a model form and then put it into a database. I have figured out how to make the form, but when clicking the submit button it doesn't seem to be put anywhere in my database. Am I doing anything wrong or am I not looking in the correct place in the database.
forms.py
from django import forms
from sxsw.models import Account
class AccountForm(forms.ModelForm):
class Meta:
model = Account
fields = ['firstName', 'lastName', 'email']
views.py
from django.shortcuts import render
from django.shortcuts import redirect
from .forms import AccountForm
from .models import Account
def sxsw(request):
if request.method == 'POST':
form = AccountForm(request.POST)
if form.is_valid():
form.save()
else:
print form.errors
else:
form = AccountForm()
return render(request, 'sxsw/sxsw.html', {'form': form})
def formSubmitted(request):
return render(request, 'sxsw/formSubmitted.html',{})
models.py
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Account(models.Model):
firstName = models.CharField(max_length = 50)
lastName = models.CharField(max_length = 50)
email = models.EmailField()
def __unicode__(self):
return self.firstName
class Module(models.Model):
author = models.ForeignKey(Account, on_delete = models.CASCADE)
nameOfModule = models.CharField(max_length = 150) #arbitrary number
moduleFile = models.FileField(upload_to = 'uploads/')#Not exactly sure about the upload_to thing
public = models.BooleanField()
def __unicode__(self):
return self.nameOfModule
sxsw.html
{% extends "base.html" %}
{% block content %}
<div class="container-fluid">
<div class="jumbotron text-center">
<h3>SXSW Form</h3>
</div>
</div>
<div align="center">
<h1>New Form</h1>
<form role='form' action="/sxsw/formSubmitted/" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
</div>
</div>
{% endblock %}
formSubmitted.html
{% extends "base.html" %}
{% block content %}
<div class="container-fluid">
<div class="jumbotron text-center">
<h3>Form Successfully submitted</h3>
</div>
</div>
<div align="center">
Submit Another Response
</div>
</div>
{% endblock %}
Your form is posting to what I presume is the wrong url
<form role='form' action="/sxsw/formSubmitted/" method="post">
should use the url for the sxsw view
<form role='form' action="/sxsw/" method="post">
Once submitted, you'll likely want to redirect to the submitted view
return redirect('/sxsw/formSubmitted/') # Preferably use the url pattern name here
It looks like your form's action is set to /sxsw/formSubmitted/ that always simply return the submitted page, instead of the url that will call the sxsw view where the form's save method is called.
I am working on a little project on Django, I have had some issues on rendering ModelForm. In main.html tag {{form.ad_p}} doesn't seem working. I only see "Save" button and don't see any ModelForm fields.
If I put below code to shell
form = AddPath()
form.as_p()
I see:
form.as_p()
u'<p><label for="id_name">Name:</label> <input id="id_name" maxlength="200" name="name" type="text" /></p>\n<p><label for="id_route_data">Route data:</label> <textarea cols="40" id="id_route_data" name="route_data" rows="10">\r\n</textarea></p>'
Can you explain, what am I doing wrong?
I already searched on stackoverflow, but same problem hasn't been resolved. I hope, I'll be more lucky
models.py:
from django.db import models
from django.contrib.auth.models import User
class Path(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length='200')
route_data = models.TextField()
def __unicode__(self):
return self.name
views.py:
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.core.context_processors import csrf
from google_maps.forms import AddPath
def index(request):
args = {}
args.update(csrf(request))
form = AddPath()
return render_to_response('main.html', args)
def add_path(request):
#me = request.user
me = 'test'
if request.method == 'POST':
form = AddPath(request.POST)
if form.is_valid():
tmpForm = form.save(commit=False)
tmpForm.user = me
tmpForm.save()
return HttpResponse('Saved')
else:
return HttpResponse(form.errors)
main.html
{% extends 'basis.html' %}
{% block leftbar %}
<form action={% url 'add_path' %} method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="hidden", id="coordinate" name="coordinate"/>
<input type="submit" name="submit" value="Save"/>
</form>
{% endblock %}