Django save data from forms to database - python

Hi i am relatively new to Django. I am currently trying to store values into database. Timesheet.html is basically my form and i have tried to do the validation but it doesn't work. I have searched everything i can but the data being filled out wont be saved into database. Is there anywhere to check that the checkbox has been ticked before user can submit it ?
timesheet.html
<form method="POST" onsubmit="return validation()" action="">
{% csrf_token %}
<div class="content-wrapper">
<div class="sub-content">
<div>
<p>Student ID: {{timesheet.studentID}}</p>
<input id="sid" type="field" name="studentid">
</div>
</div>
<div class="sub-content">
<div>
<p>Student Name: {{timesheet.studentName}}</p>
<input id="sname" type="field" name="studentname">
</div>
</div>
<div class="sub-content">
<div>
<p>Start Date: {{timesheet.startDate}}</p>
<input id="sdate" type="date" name="startdate">
</div>
</div>
<div class="sub-content">
<div>
<p>End Date: {{timesheet.endDate}}</p>
<input id="edate" type="date" name="enddate">
</div>
</div>
</div>
<div class="end-content">
<div class="center-align">
<div class="checklist">
<p>By checking this box I agree that I have satisfied all requirements to continue receiving my scholarship
allowance.</p>
<input id="agree" type="checkbox" name="checkbox" class="tick-att">
</div>
<br>
<div class="align-right">
<input type="submit" class="button" name="submit" value="submit" >
</div>
</div>
</div>
</form>
models.py
class Timesheet(models.Model):
studentID = models.CharField("Student ID", max_length=8, primary_key=True, default="")
studentName = models.CharField("Student Name", max_length=500, default="")
startDate = models.DateField("Start Date", max_length=8)
endDate = models.DateField("End Date", max_length=8)
def __str__(self):
return self.studentID
class TimesheetForm(forms.ModelForm):
class Meta:
model = Timesheet
fields = '__all__'
views.py
def timesheet(request):
if request.method == "POST":
form = TimesheetForm(request.POST)
if form.is_valid():
timesheet = form.save(commit=False)
timesheet.studentID = request.POST.get('studentID')
timesheet.studentName = request.POST.get('studentName')
timesheet.startDate = request.POST.get('startDate')
timesheet.endDate = request.POST.get('endDate')
timesheet.save()
return HttpResponseRedirect(reverse('hrfinance/timesheet.html'))
#if the form is not valid, redirect the student to the same page
else:
form = TimesheetForm()
return render(request, 'hrfinance/timesheet.html', {'form': form})
else:
form = TimesheetForm()
return render(request, 'hrfinance/timesheet.html', {'form': form})

There are lots of very strange things here.
Firstly, there is no need to set the fields manually on save. That is exactly what form.save() does in the first place. (And if you ever did need to set something manually, you should always get it from form.cleaned_data rather than request.POST.)
Secondly, you re-instantiate the form if it fails validation. That means that the users can never see the errors that are preventing it from validating.
Thirdly, you should show errors in the template. Along with that, you should let Django itself output your fields so that they are automatically prepopulated when the form is invalid.
Finally, you should add your checkbox as a field on the form, so that it is validated along with everything else.
class TimesheetForm(forms.ModelForm):
checkbox = forms.BooleanField()
class Meta:
model = Timesheet
fields = '__all__'
...
def timesheet(request):
if request.method == "POST":
form = TimesheetForm(request.POST)
if form.is_valid():
timesheet = form.save()
return HttpResponseRedirect(reverse('hrfinance/timesheet.html'))
else:
form = TimesheetForm()
return render(request, 'hrfinance/timesheet.html', {'form': form})
...
<form method="POST" onsubmit="return validation()" action="">
{% csrf_token %}
{{ form.errors }}
<div class="content-wrapper">
<div class="sub-content">
<div>
<p>Student ID: {{timesheet.studentID}}</p>
{{ form.studentID }}
</div>
</div>
</div>
.... etc...
<div class="checklist">
<p>By checking this box I agree that I have satisfied all requirements to continue receiving my scholarship
allowance.</p>
{{ form.checkbox }}
</div>

Related

Recover data from a Django Form

It's my first time doing a Django Form challenge.
The challenge for now is just from a HTML Template get the last_name information and store into DB from views. So I have a scenario below:
models.py:
class Person(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
an HTML template, I will put below only the form part:
<form action="{% url 'store' %}" method="post">
{% csrf_token %}
<div class="form-group row">
<label for="last_name" class="col-sm-2 col-form-label">Last Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="last_name" placeholder="Last Name">
</div>
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Send Last Name</button>
</div>
</div>
</form>
And the views.py itself... I created a InsertLastName ModelForm to store the data from the form, but didn't work. For some reason, when I tryed to call form.cleaned_data I reveived an error about the is_valid() verification. Seens like that I'm not getting the information from label.
class InsertLastName(forms.ModelForm):
class Meta:
model = Person
fields = ['last_name']
exclude = ['first_name']
def index(request):
persons = Person.objects.all()
context = {'persons': persons}
return render(request, '/index.html', context)
def store(request):
form = InsertLastName(request.POST or None)
print(form.cleaned_data['last_name'])
return HttpResponse("Storing a new Last Name object into storage")
What is the correct way to get the information from last_name label in my form?
I'm following that documentation and coding from a challenge template.
Your just set attr name for your input html tag
Example:
<input type="text" name="first">
And for get input in function store in view.py:
request.POST.get("first")
Add this to your html template in your form
{{persons}}

Django Form is Not saving to Database

I have searched the site for a solution, many related questions, but no direct response given. I have 3 apps on my projects, and 2 worked pretty well, except for this app, which is not writing to the database.
Yes, the other 2 apps write to the postgres database, and I can view the table, but this return empty rows, and I don't see any problem. I hope someone can help me, see below my Model, Form and View.py.
MY View.py
from django.shortcuts import render, redirect
from .forms import EngForm
def EngineerList(request):
return render(request, "Engineers/elist.html")
def EngineerForm(request):
if request.method == "GET":
form = EngForm()
return render(request, "Engineers/eform.html", {'form':form})
else:
form = EngForm(request.POST)
if form.is_valid():
form.save()
return redirect('/engineer/') #pointing to urls.py paths
My Forms.py
from django import forms
from .models import Engineers
class EngForm(forms.ModelForm):
class Meta:
model = Engineers
fields = '__all__'
labels = {
'workarea' : 'Zone',
'face' : 'Picture',
}
def __init__(self, *args, **kwargs):
super(EngForm, self).__init__(*args, **kwargs)
self.fields['position'].empty_label='Select'
self.fields['workarea'].empty_label='Select'
self.fields['face'].required = False
My Model.py
from django.db import models
class Engineers(models.Model):
position = (
('NOC', 'NOC'),
('Supervisor', 'Supervisor'),
('Site Manager','Site Manager'),
('Site Engineer', 'Site Engineer'),
)
region = (
('SS','South-South'),('SW','SW'),('SE','SE'),
('NE','NE'),('NW','NW'),('NC','NC'),
)
firstname = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
email = models.EmailField(max_length=50)
username = models.CharField(max_length=20)
phone = models.IntegerField()
position = models.CharField(max_length=20, choices=position)
workarea = models.CharField(max_length=20, choices=region)
face = models.ImageField(upload_to='', height_field=15, width_field=9)
My HTML
{% extends "Dashboard/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<form method="POST" action="" autocomplete="off">
{% csrf_token %}
<div class="row">
<div class="col-md-12">
{{form.face|as_crispy_field}}
</div>
<p>
<hr>
<p>
<div class="col-md-6">
{{form.firstname|as_crispy_field}}
</div>
<div class="col-md-6">
{{form.lastname|as_crispy_field}}
</div>
<div class="col-md-6">
{{form.username|as_crispy_field}}
</div>
<div class="col-md-6">
{{form.position|as_crispy_field}}
</div>
<div class="col-md-6">
{{form.phone|as_crispy_field}}
</div>
<div class="col-md-6">
{{form.workarea|as_crispy_field}}
</div>
<div class="col-md-12">
{{form.email|as_crispy_field}}
</div>
</div>
<hr>
<div>
<button type="submit" class="btn btn-success"><i class="fas fa-save"></i> Submit</button>
</div>
</form>
{% endblock content %}
My problem is, the database table is returning empty row.
Solved. Applied #GwynBleidD suggest, I reviewed the doc, and then rearranged the code as such.
def EngineerForm(request):
if request.method == "POST":
form = EngForm(request.POST)
if form.is_valid():
form.save()
return redirect('/engineer/') #pointing to urls.py paths
else:
form = EngForm()
return render(request, "Engineers/eform.html", {'form':form})

Passing username (and viewing as uneditable in html) in form Django

I have a form where I would like to have a username and production line send along. The thing is that the username should be taken from current logged user (and viewed as uneditable field) but the production line should be selected via dorpdown.
It works by somehow since when I click on "User" dropdown it shows only the logged user.
views:
def order(request):
storage = PartNumber.objects.all()
username = request.user.username
if request.method == 'POST':
order_form = OrderForm(username=username, data=request.POST)
if order_form.is_valid():
order_form.save()
return redirect('order')
elif request.method == 'GET':
order_form = OrderForm(username=username)
return render(request, 'dashboard/order.html', {"form": order_form, "username": username})
forms:
class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ('end_user_id', 'production_line_id')
def __init__(self, *args, **kwargs):
username = kwargs.pop('username', None)
super(OrderForm, self).__init__(*args, **kwargs)
self.fields['end_user_id'].queryset = User.objects.filter(username=username)
models:
class Order(models.Model):
end_user_id = models.ForeignKey(User, on_delete=models.CASCADE)
production_line_id = models.OneToOneField(ProductionLine, on_delete=models.CASCADE)
date_ordered = models.DateTimeField(auto_now_add=True, null=True)
date_completed = models.DateTimeField(auto_now=True, null=True)
def __str__(self):
return str(self.status)
html:
{% extends 'dashboard/main.html' %}
{% load static %}
{% load bootstrap %}
{% block content %}
<h3>Zamowienie</h3>
<br>
<!--{{ form|bootstrap }}-->
<form role="form" action="" method="post">
{% csrf_token %}
<div class="form-group">
<label>Uzytkownik </label>
<!--<input class="form-control" placeholder="{{user}}" readonly>-->
{{ form.end_user_id }}
</div>
<br>
<div class="form-group">
<label>Linia produkcyjna </label>
{{ form.production_line_id }}
</div>
<br>
<div class="text-center">
<button type="submit" class="btn btn-primary">Przeslij</button>
</div>
</form>
{% endblock content %}
Now if you look at the html above, the commented line :
<!--<input class="form-control" placeholder="{{user}}" readonly>-->
actually gives me the look I want but doesn't send the username (doesn't work)
I was trying different solutions from different posts that I found here but nothing seems to work for me.
Any ideas ?
You are passing username to the template using the variable username.
In the template you are trying to get the username by using the variable user.
<input class="form-control" placeholder="{{user}}" readonly>
Should be :
<input class="form-control" placeholder="{{username}}" readonly>

how to access Django form fields through HTML

I have created models.py, forms.py, views.py & registeration.html.
At the moment in registeration.html I am directly importing the django form like {{reg_form.as_p}}, I can also do it in following two ways: {{ form.as_table }} or {{ form.as_ul }}. what I want is to have a real control over the fields to be displayed. Meaning to say some fields may be tabular, some may be list etc with specific css.
What I tried in html to access the field is mentioned below:
id={{form.id_FullName}} name={{form.FullName}}
In models.py I have:
FullName = models.CharField(max_length = 100)
The above way didnt work, I want some way to access the django fields in HTML.
Add name and pass the modelname ,
Change like this,
<input type="text" id="id_FullName" value="" name="FullName" />.
and submit your form.
Example , lets say signup form :
forms.py,
class SignUpForm(forms.ModelForm):
email = forms.CharField(label='email', max_length=100)
password = forms.CharField(label='password', max_length=100)
def __init__(self, *args, **kargs):
super(SignUpForm, self).__init__(*args, **kargs)
class Meta:
model = User
fields = '__all__'
views.py,
def signup(request):
form = SignUpForm(request.POST or None)
if request.method == 'POST':
form = SignUpForm(request.POST or None)
if not form.is_valid():
print form.errors
return render(request, 'signup.html', {'form': form})
else:
email = form.cleaned_data.get("email")
password = form.cleaned_data.get("password")
new_user = User.objects.create_user(email=email,
password=password,
)
new_user.is_active = True
new_user.save()
return redirect('login')
else:
return render(request, 'signup.html', {'form': form})
urls.py
url(r'^signup', views.signup, name='signup'),
Finally in your templates ie signup.html,
<form action="." method="post"> {% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" name="email" id="inputUsernameEmail" placeholder="Email">
</div>
<div class="form-group">
<input type="password" name="password" class="form-control" id="inputPassword" placeholder="Password">
</div>
<input type="submit" name="Sign up" value="Sign up" id="Sign_up" class="button_drop outline">
</form>
You can render the field manually.[Documentation]
Here is a sample taken from the docs for a subject field
<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
</div>

form.is_valid(): always returns false

Form.is_valid() always returns false. Here's my code.
#urls.py
url(r'^create/', "app.views.createpost", name="createpost"),
My models.py
class Post(models.Model):
"""docstring for Post"""
post_image = AjaxImageField(upload_to='posts', max_width=200, max_height=200, crop=True, null= False, default='site_media/media/BobMarley/bob1.jpg')
poster = models.ForeignKey(User, null= False, default=User.objects.get(username="admin")
Here's my forms.py
#forms.py
class AjaxImageUploadForm(forms.Form):
image = forms.URLField(widget=AjaxImageWidget(upload_to='posts'))
view.py
#views.py
def createpost(request):
if request.method == 'POST':
form = AjaxImageUploadForm(request.POST, request.FILES)
if form.is_valid():
newpost = Post(post_image = request.FILES['image'])
newpost.poster = request.user
newpost.save()
return HttpResponseRedirect('/create/')
else:
form = AjaxImageUploadForm() # An empty, unbound form
posts = Post.objects.all()
return render_to_response('create.html',{'posts': posts, 'form': form},context_instance=RequestContext(request))
The Template
#create.html
{% block extra_head %}
{{ form.media }}
{% endblock %}
{% block body %}
<form method="POST" enctype="multipart/form-data" action="{% url "createpost" %}">
{% csrf_token %}
{{ form.errors}}
{{ form.as_p }}
<button type="submit" name='image'>Upload</button>
</form>
{% endblock %}
The form is never valid and the error printed is "This field is required."
And this is the form widget begin created
<tr><th><label for="id_image">Image:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul>
<div class="ajaximage"><a class="file-link" target="_blank" href=""> <img class="file-img" src=""></a> <a class="file-remove" href="#remove">Remove</a>
<input class="file-path" type="hidden" value="" id="id_image" name="image" /> <input type="file" class="file-input" name="image"/> <input class="file-dest" type="hidden" name="image" value="/ajaximage/upload/posts/0/0/0"> <div class="progress progress-striped active"> <div class="bar"></div></div>
</div>
</td></tr>
I am using the django package called django-ajaximage and their custom widget (AjaxImageWidget) is probably a custom text widget
class AjaxImageWidget(widgets.TextInput):
Thank you for you help
You do not need the init on your model class. Also, null=False is the default. I'm not sure the text 'admin' will default to the user with username admin. You would need to do:
default=User.objects.get(username="admin")
You can also include the poster assignment in the creation of the object like so:
newpost = Post(post_image=request.FILES['image'], poster=request.user)
To make the form validate you need to put blank=True in the field like so:
poster = models.ForeignKey(User, blank=True, default=User.objects.get(username="admin")
I would also make the form be a ModelForm:
class AjaxImageUploadForm(forms.ModelForm):
class Meta:
model=Post
exclude=['poster',]

Categories

Resources