how to access Django form fields through HTML - python

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>

Related

Django form errors not showing when use id_<field-name>

I'm a beginner in Django, I try to use for="id_<field-name>" method to create a signup form interface, but the default validation like "This field is required." or "This username already exists" is not showing. I don't want to use {{ form.as_p }} because I want to separate the field. The registration still working if i input the true the valid things.
HTML
<form method="POST" class="register-form" id="register-form" enctype="multipart/form-data" >
{% csrf_token %}
<div class="form-group">
<label for="id_username"><i class="zmdi zmdi-account material-icons-name"></i></label>
<input type="text" name="username" id="username" placeholder="Username"/>
</div>
<div class="form-group">
<label for="id_email"><i class="zmdi zmdi-email"></i></label>
<input type="email" name="email" id="email" placeholder="Your Email" />
</div>
<div class="form-group">
<label for="id_password"><i class="zmdi zmdi-lock"></i></label>
<input type="password" name="password" id="password" placeholder="Password"/>
</div>
<div class="form-group">
<input type="checkbox" name="agree-term" id="agree-term" class="agree-term" />
<label for="agree-term" class="label-agree-term"><span><span></span></span>I agree all statements in Terms of service</label>
</div>
<div class="form-group form-button">
<input type="submit" name="signup" id="signup" class="form-submit" value="Register"/>
</div>
</form>
views.py
def register(request):
registered = False
if request.method == 'POST':
# Get info from "both" forms
# It appears as one form to the user on the .html page
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
# Check to see both forms are valid
if user_form.is_valid() and profile_form.is_valid():
# Save User Form to Database
user = user_form.save()
# Hash the password
user.set_password(user.password)
# Update with Hashed password
user.save()
# Now we deal with the extra info!
# Can't commit yet because we still need to manipulate
profile = profile_form.save(commit=False)
# Set One to One relationship between
# UserForm and UserProfileInfoForm
profile.user = user
# Check if they provided a profile picture
if 'profile_pic' in request.FILES:
print('found it')
# If yes, then grab it from the POST form reply
profile.profile_pic = request.FILES['profile_pic']
# Now save model
profile.save()
# Registration Successful!
registered = True
else:
# One of the forms was invalid if this else gets called.
print(user_form.errors,profile_form.errors)
else:
# Was not an HTTP post so we just render the forms as blank.
user_form = UserForm()
profile_form = UserProfileInfoForm()
# This is the render and context dictionary to feed
# back to the registration.html file page.
return render(request,'basic_app/registration.html',
{'user_form':user_form,
'profile_form':profile_form,
'registered':registered,
})
forms.py
from django import forms
from django.contrib.auth.models import User
from .models import UserProfileInfo, TeaProfileInfo
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','email','password')
My signup page interface
A quick way to validate your form by adding the following to your form.py
def clean(self):
super(UserForm, self).clean()
username = self.cleaned_data.get('username')
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if username == "" or email == "" or password == "":
raise forms.ValidationError(['This field is required.'])
In your HTML make sure to add the following after/before each field
{{ username.errors }}
{{ email.errors }}
{{ password.errors }}

How to pass data from a template to the Django side

I just started to code Python Django. I just wanted to make a basic login project. I tried to pass login variables from the HTML side to file views.py.
Here is my HTML code:
<form action="/index" method="post">
{% csrf_token %}
<div class="form-group">
<label for="username">Username</label>
<input class="form-control" id="username" type="email"/>
</div>
<div class="form-group">
<div class="d-flex justify-content-between">
<label for="password">Password</label><a class="fs--1">Forgot Password?</a>
</div>
<input class="form-control" id="password" type="password" />
</div>
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="card-checkbox" checked="checked"/>
<label class="custom-control-label" for="card-checkbox">Remember me</label>
</div>
<div class="form-group">
<button class="btn btn-primary btn-block mt-3"
type="submit"
id= "login"
name="submit">Log in</button>
</div>
</form>
My urls.py file:
urlpatterns = [
path('', views.loginPage, name="login"),
path('index', views.home, name="index")
]
My forms.py file:
from django import forms
class LoginForm(forms.Form):
username = forms.EmailField(label="Username"),
password = forms.CharField(label="Password")
And my views.py file:
def home(request):
context = {}
if request.method == 'POST':
form = LoginForm(request.POST)
print('form:', form)
if form.is_valid():
print('niceee')
else:
return render(request, 'index.html', context)
else:
form = LoginForm()
I just want to see username and password values into views.py. However, I can't see variables into views.py. How can I fix this?
def home(request):
if request.method == 'POST':
form = LoginForm(request.POST)
print('form:', form)
if form.is_valid():
print('username:', form.cleaned_data.get('username'))
print('password:', form.cleaned_data.get('password'))
print('niceee')
else:
form = LoginForm()
context = {}
return render(request, 'index.html', context)
Check the server for username and password values.
You are a halfway there! Once the form has been validated by Django, you can access the form's variables in its cleaned_data attribute:
def home(request):
context = {}
if request.method == 'POST':
form = LoginForm(request.POST)
print('form:', form)
if form.is_valid():
print('You submitted this username:', form.cleaned_data['username'])
print('You submitted this password:', form.cleaned_data['password'])
else:
return render(request, 'index.html', context)
else:
form = LoginForm()
However, consider reusing django.contrib.auth.views.LoginView because then you won't have to write any Python code at all. Just customize the registration/login.html template.

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>

Pictures are not getting updated in database even after submitting using DJANGO Model Forms

I intend to make a user profile model with profile picture in django.
Everything works fine but I can't update the profile picture of the user.
The form is being displayed on the website but on clicking submit, no changes are visible in the database and the image is also not getting uploaded.
Below is my code for the form in HTML.
<form method="POST" action="{% url 'profile' %}" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<br><br>
<div class="mb-3"><button class="btn btn-primary btn-sm" name="_picture" type="submit">Change Photo</button></div>
</form>
Below is the code models.py, for creating user profile model.
class UserProfileInfo(models.Model):
# Create relationship (don't inherit from User!)
user = models.OneToOneField(User, on_delete=models.CASCADE)
isInstructor = models.BooleanField(default=False)
department = models.ForeignKey(Department,on_delete=models.CASCADE)
role = models.ManyToManyField(Role)
profile_picture = models.FileField(upload_to='static/profile_pic/'+str(time.time()),default='d.jpeg')
address = models.TextField(max_length=256)
city = models.TextF
class UpdateProfilePic(ModelForm):
class Meta:
model = UserProfileInfo
fields = ['profile_picture']
Below is the code for views.py
#login_required
def profile(request):
current_user_profile = UserProfileInfo.objects.get(user=request.user)
current_user = request.user
form = UpdateProfilePic(instance=current_user_profile)
context = {'current_user':current_user,'current_user_profile':current_user_profile,'form':form}
if request.method=='POST':
if '_user' in request.POST:
temp_user = request.user
temp_user.username = request.POST.get('username')
temp_user.email = request.POST.get('email')
temp_user.first_name = request.POST.get('first_name')
temp_user.last_name = request.POST.get('last_name')
temp_user.save()
context = {'current_user':current_user,'current_user_profile':current_user_profile,'form':form}
return render(request,'instructor_app/profile.html',context)
if '_profile' in request.POST:
temp_user_profile = UserProfileInfo.objects.get(user=request.user)
temp_user_profile.address = request.POST.get('address')
temp_user_profile.city = request.POST.get('city')
temp_user_profile.pincode = request.POST.get('pincode')
temp_user_profile.save()
context = {'current_user':current_user,'current_user_profile':current_user_profile,'form':form}
return render(request,'instructor_app/profile.html',context)
if '_picture' in request.POST:
print("in picture")
form = UpdateProfilePic(request.POST, instance=UserProfileInfo.objects.get(user=request.user))
form.save()
context = {'current_user':current_user,'current_user_profile':current_user_profile,'form':form}
return render(request,'instructor_app/profile.html',context)
else:
return render(request,'instructor_app/profile.html',context)
Help me with the code, please!
You can edit your model by creating a model form or a simple Django form as shown below and by using the action attribute of form for passing the files.
You can try this:
form.py
from django import forms
class UpdateProfilePic(forms.Form):
image = forms.ImageField()
In your views.py
if '_picture' in request.POST:
form = UpdateProfilePic(request.POST, request.FILES)
if form.is_valid():
m = UserProfileInfo.objects.get(user=request.user)
m.profile_picture = form.cleaned_data['image']
m.save()
return redirect('/profile')
And your HTML file
<form action="{% url 'profile' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="input-group">
<div class="custom-file">
<input type="file" class="custom-file-input" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04" name="image">
<label class="custom-file-label" for="inputGroupFile04">Choose file</label>
</div>
<div class="input-group-append">
<button class="btn btn-primary" type="submit" name="_picture" id="inputGroupFileAddon04">Upload</button>
</div>
</div>
</form>

Django save data from forms to database

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>

Categories

Resources