I am learning Django and am trying to set up a simple form HTML with form fields which I can send via POST method.
However, if I load HTML page the fields are not visible
The HTML page is create.html
{% extends 'main/base.html' %}
{% block title %}
Create a task
{% endblock %}
{% block content %}
<h1>Create a task</h1>
<form method="post">
{% csrf_token %}
{{ form.title }}
{{ form.task }}
<button type="submit" class="btn btn-success">Add</button>
<span>{{ error }}</span>
</form>
{% endblock %}
<input type="text" placeholder="Enter name" class="form-control"><br>
<textarea placeholder="Enter description" class="form-control"></textarea><br>
My forms.py file is as follows:
from .models import Task
from django.forms import ModelForm, TextInput, Textarea
class TaskForm(ModelForm):
class Meta:
model = Task
fields = ["title", "task"]
widgets = {
"title": TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter name'
}),
"task": Textarea(attrs={
'class': 'form-control',
'placeholder': 'Enter description'
}),
}
and views.py is as this:
from django.shortcuts import render, redirect
from .models import Task
from .forms import TaskForm
def index(request):
tasks = Task.objects.order_by('id')
return render(request, 'main/index.html', {'title': 'Main page of this website', 'tasks': tasks})
def about(request):
return render(request, "main/about.html")
def create(request):
error = ''
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
form.save()
redirect('home')
else:
error = 'The form has incorrect values'
form = TaskForm()
context = {
'form': form,
'error': error
}
return render(request, "main/create.html")
It appears to me that
{{ form.title }}
and
{{ form.task }}
are not working properly. However, I do not know how to adjust the code to make them visible. I browsed similar questions and suspect it's because GET request is not defined in view, but I do not know how to fix it.
Thank you for any ideas.
#John Gordon helped in comments, I was not passing the context into the render call
return render(request, "main/create.html", context)
fixed my issue
Related
recently I encountered a rather weird problem with my Django forms. I am currently working on my todo list project. Everything works fine, except that whenever I add a new task, its title seems to be saved in database with additional square brackets and quotes around it. It looks like one-element list, but it is a string. I kinda solved it by displaying the silced version of the string from the database, but it still shows for example while editing a task. Hope anyone has some idea what might be going on?
models.py:
from django.db import models
class Task(models.Model):
title = models.CharField(max_length=35)
completed = models.BooleanField(default=False)
created_date = models.DateTimeField(auto_now_add=True)
# added_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
author = models.CharField(max_length=50, default='')
def __str__(self):
return self.title
forms.py:
from django import forms
from .models import *
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = '__all__'
widgets = {
'title': forms.TextInput(attrs={'class': 'new_task_text', 'placeholder': 'Add new task'}),
}
class TaskEditForm(forms.ModelForm):
class Meta:
model = Task
fields = ['title', 'completed']
widgets = {
'title': forms.TextInput(attrs={'class': 'new_task_text'}),
}
views.py:
from django.shortcuts import render, redirect
from .forms import *
from django.contrib.auth.decorators import login_required
#login_required
def list_homepage(request):
tasks = Task.objects.filter(author=request.user.username)
for task in tasks:
if "['" and "']" in task.title:
task.title = task.title[2:-2] # CharField returns a string that is looking like one-element list. Have no idea why yet.
# try using form instead of modelform.
form = TaskForm()
if request.method == 'POST':
form = TaskForm({**request.POST, **{'author': request.user.username}})
if form.is_valid():
form.save()
else:
print(form.errors)
return redirect('/list/home')
context = {
'page_title': 'Todo list',
'tasks': tasks,
'form': form,
}
return render(request, 'tasks/list.html', context)
#login_required
def update_task(request, pk):
task = Task.objects.get(id=pk)
form = TaskEditForm(instance=task)
if request.method == 'POST':
form = TaskEditForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('../..')
context = {
'form': form,
'page_title': 'Update task',
}
return render(request, 'tasks/update_task.html', context)
#login_required
def delete_task(request, pk):
task = Task.objects.get(id=pk)
if request.method == 'POST':
task.delete()
return redirect('/list')
context = {
'page_title': 'Delete task',
'task': task,
}
return render(request, 'tasks/delete_task.html', context)
list.html:
{% extends 'tasks/base.html' %}
{% block content %}
<div class="new-task-column">
<form method="POST", action="#"> {% csrf_token %}
{{ form.title }}
<input class="submit" type="submit", value="Create task">
</form>
</div>
<div class="task-column">
{% for task in tasks %}
<div class="item-row">
<div class="task">
{% if task.completed == True %}
<s>{{ task }} </s>
{% else %}
{{ task }}
{% endif %}
</div>
<div class="del_upd_container">
<div class="single-upd-container"><a class="edit_button" href="/list/update_task/{{ task.id }}">Update</a></div>
<div class="single-del-container"><a class="edit_button" href="/list/delete_task/{{ task.id }}">Delete</a></div>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
update_task.html:
{% extends 'tasks/base.html' %}
{% block content %}
<div class="new-task-column">
<form method="POST"> {% csrf_token %}
<span class="update-task-layout">
{{ form }}
<input class="submit" type="submit" name="Update item">
</span>
</form>
</div>
{% endblock content %}
Thank you so much for any help, I really appreciate it!
Had the same problem, solved it by using the method dict() to transform request.POST's weird type (QueryDict) into a normal dict. The rest of the code, like the save() method for example, might need to be a bit adjusted.
I am trying to set default values for my form fields in my Django application, but nothing I do seemed to work. I am using Django 2.2.3.
This is my code in views.py:
def my_view(request, template_name="path/to/template"):
form = MyForm(request.POST, initial={
'field_one': field_one_default,
'field_two': field_two_default,
})
try:
if request.method == 'POST':
if form.is_valid():
field_one = form.cleaned_data['field_one']
field_two = form.cleaned_data['field_two']
my_model.field_one = field_one
my_model.field_two = field_two
my_model.save()
return redirect('redirected_page')
return render(request, template_name, {'form': form})
return render(request, template_name, {'form': form})
except Http404 as e:
return Http404("An error occurred.")
This is my code in forms.py:
class MyForm(forms.Form):
field_one_choices = [
('Choice One', 'Choice One'),
('Choice Two', 'Choice Two'),
('Choice Three', 'Choice Three'),
]
field_one = forms.ChoiceField(choices=field_one_choices, required=True)
field_two = forms.IntegerField(
validators=[MaxValueValidator(100), MinValueValidator(1)],
required=True
)
And this is my code in the template:
{% load fontawesome_5 %}
{% load bootstrap4 %}
<div class="container spacing-top">
<form method="post">{% csrf_token %}
{% bootstrap_form form %}
<input class="btn btn-info" type="submit" value="Save">
<a class="btn btn-secondary" href="{% url 'another_page_url' %}">Cancel</a>
</form>
</div>
I have also tried setting the default values in the forms.py, but that did not work either:
field_one = forms.ChoiceField(choices=field_one_choices, required=True, initial=field_one_default)
field_two = forms.IntegerField(
validators=[MaxValueValidator(100), MinValueValidator(1)],
required=True,
initial=field_two_default
)
Any help is greatly appreciated! Thanks in advance!
So I finally found my mistake. Reading the Django documentation tells me the following:
This is why initial values are only displayed for unbound forms. For bound forms, the HTML output will use the bound data.
This part of the documentation explains the meaning of bound and unbound forms, giving form = NameForm(request.POST) as an example of a bound form.
Therefore, to solve the posted problem, I changed my views.py code as such:
def my_view(request, template_name="path/to/template"):
form = MyForm(request.POST or None, initial={
'field_one': field_one_default,
'field_two': field_two_default,
})
...
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 %}
I have created my first app in Django (1.10.5) / Python 3.4. I have a login page and a register page. Which is working fine.
I can create new user and login with that id. Now after the login I want user to fill a form with some information and click on submit. And the information should get stored in the database.
So I created a model first : Model.py
class UserInformation(models.Model):
firstName = models.CharField(max_length=128)
lastName = models.CharField(max_length=128)
institution = models.CharField(max_length=128)
institutionNumber = models.CharField(max_length=128)
cstaPI = models.CharField(max_length=128)
orchidNumber = models.CharField(max_length=128)
This has created a table in the DB.
forms.py
class UserInformationForm(ModelForm):
class Meta:
model = UserInformation
fields = '__all__'
views.py
def home(request):
form = UserInformationForm()
variables = { 'form': form, 'user': request.user }
return render(request,'home.html',variables)
home.html
{% extends "base.html" %}
{% block title %}Welcome to Django{% endblock %}
{% block head %}Welcome to Django{% endblock %}
{% block content %}
<p> Welcome {{ user.username }} !!! Logout<br /><br /> </p>
<form method="post" action=".">{% csrf_token %}
<table border="0">
{{ form.as_table }}
</table>
<input type="submit" value="Submit" style="position:absolute"/>
</form>
{% endblock %}
But when I click on submit button, It does not insert data into my table.
here is the answer, we need to use the request.POST
def home(request):
if request.method == 'POST':
form = UserInformationForm(request.POST)
form.save()
return HttpResponseRedirect('/home/')
else:
form = UserInformationForm()
variables = { 'form': form, 'user': request.user }
return render(request,'home.html',variables)
the first: you need add urls.py to you app
the second: you need to change your views.py to lool like this
`
info = UserInformation()
lastName = request.POST.get('lastName')
...
info.save()
`
I have two field in my django form as well as model, One is date other is time . I want to submit date and time in database. But I haven't succeeded in it yet. Please suggest some code that can make it possible.
form.py
class dated1(forms.ModelForm):
cur_date=forms.DateField()
cur_time=forms.TimeField(datetime.time)
class Meta:
model=dated
model.py
class dated(models.Model):
cur_date = models.DateField()
cur_time = models.TimeField()
def __unicode__(self):
return self.cur_date
view.py
def datetime1(request):
if request.method =='POST':
form = dated1(request.POST)
if form.is_valid():
f=dated(
cur_date=request.POST('cur_date'),
cur_time=request.POST('cur_time'),
)
f.save()
return HttpResponse("Success")
else:
return HttpResponse("Failure")
else:
form = dated1()
return render(request, 'formdata/dt.html',{'form': form})
instead of
f=dated(
cur_date=request.POST('cur_date'),
cur_time=request.POST('cur_time'),
)
f.save()
try this
f = form.save(commit=False)
f.save()
in the template, I made some changes :
{% extends 'formdata/template1.html' %}
{% block js %}
<script type="text/javascript">
$(function()
{
$( "#id_cur_date" ).datepicker({dateFormat: $.datepicker.ATOM});
});
$(function()
{
$('#id_cur_time').timepicker({timeFormat: 'H:i:s'});
});
</script>
{% endblock %}
{% block content %}
<form id="dtform" method="post" action="#">
{% csrf_token %}
<h3>Date:</h3>
{{ form.cur_date }}
<h3>Time:</h3>
{{ form.cur_time }} <br>
<input type="submit" value="submit">
</form>
{% endblock %}
then I made some changes in views.py
def datetime1(request):
if request.method =='POST':
form = dated1(request.POST)
f=dated(
cur_date=request.POST['cur_date'],
cur_time=request.POST['cur_time']
)
f.save(force_insert=True)
return HttpResponse("Success")
else:
form = dated1()
return render(request, 'formdata/dt.html',{'form': form})
now when I remove "if form.is_valid()" in the views, it has been submitted successfully in standard format I wanted. Also I add a date picker and time picker through jQuery.
with this answer my question is; why the statement "if form.is_valid()" was not working in above case. #abhi #Paul Collingwood