How to render error or validation messages to ModelForm in 2022 - django

I've spent several hours researching on the internet, especially the official Django documentation, but still it is not clear to me which is the best option in 2022 (since almost all questions I read on SO are > 6 yo)
and there are diverse opinions on whether crispy forms is better or not.
Is still crispy forms a recommended option?
How can I (and what is the most recommended way to) get the typical validation error messages?
Like: "this field is mandatory" or "this input accepts numbers only"? I've seen some Django pages using those default messages but I don't know how to show them in my ModelForm fields.
Lets say I have the following model:
class Project(models.Model):
project_name = models.CharField(max_length=250, null=False, blank=False)
status = models.CharField(
max_length=250,
null=True,
blank=True,
default=PROJECT_STATUS_DEFAULT,
choices=PROJECT_STATUS,
)
creation_date = models.DateField(max_length=250, null=False, blank=False)
project_code = models.IntegerField(null=True, blank=True)
notes = models.CharField(max_length=250, null=True, blank=True)
And for the Project model I have the following ModelForm:
class CreateNewProjectForm(ModelForm):
creation_date = forms.DateField(widget=forms.DateInput(format = '%d/%m/%Y'), input_formats=settings.DATE_INPUT_FORMATS) #UK Date format
class Meta:
model = Project
fields = '__all__'
The view, when I try to create a new object Project:
def add_new_project(request):
context = {}
if request.method == 'POST':
form = CreateNewProjectForm(request.POST)
if form.is_valid():
form.save()
return redirect('project_page')
else:
print (form.errors)
form = CreateNewProjectForm()
context['form'] = form
return render(request, 'new_project.html', context)
HTML part:
<div class="card h-100">
<div class="card-header project-page-header">
<h3>Create A New Project</h3>
</div>
<div class="card-body px-0 new-project-card-body">
<div class="cardItem">
<div class="row">
<div class="col">
<div class="row">
<div class="tab-pane fade show active" id="general">
<form id="newProjectForm" method="POST" action="new_project">
{% csrf_token %}
<div class="accordion accordion-flush" id="accordionGeneral">
<div class="accordion-item">
<h2 class="accordion-header" id="general-headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#general-collapseOne" aria-expanded="false" aria-controls="general-collapseOne">
Details
</button>
</h2>
<div id="general-collapseOne" class="accordion-collapse collapse show" aria-labelledby="general-headingOne" data-bs-parent="#accordionGeneral">
<div class="accordion-body">
<div class="row">
<div class="col-5">
<ul class="list-unstyled">
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Project Name
</div>
<div class="col-sm">
<input type="text" name="project_name" class="form-control" aria-label="Project Name">
</div>
</div>
</li>
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Status
</div>
<div class="col-sm">
<select name="status" class="selectpicker show-tick w-100" aria-label="Status">
{% for status in project_status %}
{% if forloop.first %}
<option value="{{ status.id }}" selected>{{ status.text }}</option>
{% else %}
<option value="{{ status.id }}">{{ status.text }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
</li>
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Creation Date
</div>
<div class="col-sm">
<input type="text" name="creation_date" class="form-control">
</div>
</div>
</li>
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Project Code
</div>
<div class="col-sm">
<input type="text" name="project_code" class="form-control">
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="general-headingThree">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#general-collapseThree" aria-expanded="false" aria-controls="general-collapseThree">
Note
</button>
</h2>
<div id="general-collapseThree" class="accordion-collapse collapse" aria-labelledby="general-headingThree" data-bs-parent="#accordionGeneral">
<div class="accordion-body"><textarea name="notes" class="form-control" rows="7"></textarea></div>
</div>
</div>
<button type="submit" id="projectEditBtn" form="newProjectForm" class="btn btn-info rounded-0">Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I saw solutions like this, but the problem is that my form fields are spread over different accordions, I can't use something like {% if form.errors %}, I need something more specific for each field.

First update your views like this
def add_new_project(request):
context = {}
if request.method == 'POST':
form = CreateNewProjectForm(request.POST)
if form.is_valid():
form.save()
return redirect('project_page')
else:
print (form.errors)
context['form'] = form
return render(request, 'new_project.html', context)
context['form'] = CreateNewProjectForm()
return render(request, 'new_project.html', context)
You can specify error for each field like this
{% if form.field_name.errors %}
{{ form.field_name.errors }}
{% endif %}

Related

Image not getting uploaded in Django

I tried to save a record using two different methods but both are not working.
Django Form
Models (create method)
1 I have created a ModelForm
class ProductForm(ModelForm):
class Meta:
model= ProductDetails
fields= ("name","category","subcategory","price","mrp","product_details","main_img","img1","img2","img3")
labels={
"name":"Product Name",
"product_details":"Description",
"category":"Category",
"subcategory":"Sub-Category",
"price":"Price",
"mrp":"MRP",
"main_img":"Main Image",
"img1":"Image 1",
"img2":"Image 2",
"img3":"Image 3",
}
widgets = {
'name':forms.TextInput(attrs={'class':'form-control validate',}),
'product_details':forms.TextInput(attrs={'class':'form-control validate',}),
'category':forms.TextInput(attrs={'class':'custom-select tm-select-accounts',}),
'subcategory':forms.TextInput(attrs={'class':'custom-select tm-select-accounts',}),
'price':forms.TextInput(attrs={'class':'form-control validate',}),
'mrp':forms.TextInput(attrs={'class':'form-control validate',}),
'main_img':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
'img1':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
'img2':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
'img3':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
}
Models File
# For Product details
class ProductDetails(models.Model):
name= models.CharField(max_length=100)
price= models.FloatField()
mrp= models.FloatField()
main_img = models.ImageField(upload_to='product_img')
img1 = models.ImageField(upload_to='product_img')
img2 = models.ImageField(upload_to='product_img')
img3 = models.ImageField(upload_to='product_img')
category = models.ForeignKey(Category, related_name='produits', on_delete=models.CASCADE)
subcategory = models.ForeignKey(SubCategory, related_name='produits', on_delete=models.CASCADE)
product_details = RichTextField(blank=True, null=True)
trending = models.BooleanField(default=False)
def __str__(self):
return self.name
Method 1
Save record using form.save()
getting Form validation error
I have tried by removing main_img,img1,img2,img3 from all place (Forms.py, template, views,py). Then there is not validation error and record is getting saved successfully.
The validation error is just because of some issue with the image uploading
print(form.errors)= <ul class="errorlist"><li>main_img<ul class="errorlist"><li>This field is required.</li></ul></li><li>img1<ul class="errorlist"><li>This field is required.</li></ul></li><li>img2<ul class="errorlist"><li>This field is required.</li></ul></li><li>img3<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
def add_product(request):
if request.method == "POST":
form = ProductForm(request.POST or None, request.FILES or None)
print(form.errors )
if form.is_valid():
category_id = request.POST.get('category')
subcategory_id = request.POST.get('subcategory')
category= Category.objects.get(id=int(category_id))
subcategory= SubCategory.objects.get(id=int(subcategory_id))
form.category = category
form.subcategory = subcategory
form.save()
return redirect("/dashboard/products")
form = ProductForm()
categories=Category.objects.all()
subcategories=SubCategory.objects.all()
return render(request, "01-add-product.html", "form":form,"categories":categories,"subcategories":subcategories})
Method 2
Tried Saving records using models.save()
The record is getting saved but image is not getting uploaded to the media folder
On saving record from Django-admin the image is getting uploaded to proper place i.e. /media.product_img/...
But From this outside HTML its showing the file name in Django-admin but the file is not available in media folder
I already added urlpattern + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) in my project/urls.py.
Also tried adding the same in urls.py of this app
Note = I have mentioned upload_to=product_img in my model (this may be important to know)
def add_product(request):
if request.method == "POST":
name = request.POST['name']
product_details = request.POST['product_details']
category_id = request.POST.get('category')
subcategory_id = request.POST.get('subcategory')
category= Category.objects.get(id=int(category_id))
subcategory= SubCategory.objects.get(id=int(subcategory_id))
price = request.POST['price']
mrp = request.POST['mrp']
main_img = request.POST['main_img']
img1 = request.POST['img1']
img2 = request.POST['img2']
img3 = request.POST['img3']
product = ProductDetails.objects.create(name=name,product_details=product_details,category=category,subcategory=subcategory,price=price,mrp=mrp,main_img=main_img,img1=img1,img2=img2,img3=img3)
product.save()
Here is my template
{% extends '01-admin-base.html' %}
{% load static %}
{% block content %}
<div class="container tm-mt-big tm-mb-big">
<div class="row">
<div class="col-xl-9 col-lg-10 col-md-12 col-sm-12 mx-auto">
<div class="tm-bg-primary-dark tm-block tm-block-h-auto">
<div class="row">
<div class="col-12">
<h2 class="tm-block-title d-inline-block">Add Product</h2>
</div>
</div>
<div class="row tm-edit-product-row">
<div class="col-xl-6 col-lg-6 col-md-12">
<form action="" method="post" class="tm-edit-product-form">
{% csrf_token %}
{{form.media}}
<div class="form-group mb-3">
<label
for="name"
>Product Name
</label>
{{form.name}}
</div>
<div class="form-group mb-3">
<label
for="category"
>Category</label
>
<select
class="custom-select tm-select-accounts"
id="category" name="category"
>
<option selected>Select category</option>
{% for category in categories %}
<option value="{{category.id}}">{{category.name}}</option>
{% endfor %}
</select>
</div>
<div class="form-group mb-3">
<label
for="subcategory"
>Sub Category</label
>
<select
class="custom-select tm-select-accounts"
id="subcategory" name="subcategory"
>
<option selected>Select sub-category</option>
{% for subcategory in subcategories %}
<option value="{{subcategory.id}}">{{subcategory.name}}</option>
{% endfor %}
</select>
</div>
<div class="row">
<div class="form-group mb-3 col-xs-12 col-sm-6">
<label
for="price"
>Price
</label>
{{form.price}}
</div>
<div class="form-group mb-3 col-xs-12 col-sm-6">
<label
for="mrp"
>MRP
</label>
{{form.mrp}}
</div>
</div>
<div class="form-group mb-3">
<label
for="description"
>Description</label
>
{{form.product_details}}
</div>
</div>
<div class="col-xl-6 col-lg-6 col-md-12 mx-auto mb-4">
<div class="custom-file mt-3 mb-3">
<label>Main Image</label>
{{form.main_img}}
</div>
<br><br>
<label>Images</label>
<div class="custom-file mt-3 mb-3">
{{form.img1}}
</div>
<div class="custom-file mt-3 mb-3">
{{form.img2}}
</div>
<div class="custom-file mt-3 mb-3">
{{form.img3}}
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary btn-block text-uppercase">Add Product Now</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
Please help me to get solution for this.
You need to add enctype="multipart/form-data"> in Html form so:
<form action="/" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname"><br><br>
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname"><br><br>
<input type="submit" value="Submit">
</form>

My for loop does not work as expected - Data does not show up in my django template

I am trying to use a for loop in my Django template to show the data stored in the models of a table but for some reason , the data does not show up in the template.
Views.py
def add_part(request):
parts = Parts.objects.all()
context = {
"parts": parts
}
return render(request, 'admintemplate/add_parts_template.html', context)
def add_part_save(request):
if request.method != "POST":
messages.error(request, "Method Not Allowed!")
return redirect('add_part')
else:
part_name = request.POST.get('part_name')
part_type = request.POST.get('part_type')
supplier_id = request.POST.get('suppliers')
suppliers = Suppliers.objects.get(id=supplier_id)
try:
part = Parts(part_name=part_name, part_type=part_type, supplier_id=supplier)
part.save()
messages.success(request, "Part Added Successfully!")
return redirect('add_part')
except:
messages.error(request, "Failed to Add Part!")
return redirect('add_part')
models.py
The parts and the services model are exactly the same with different column names, so I think the functionality for both should be the same.
Suppliers models
class Suppliers(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=20)
Parts model
class Parts(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=20)
part_type = models.CharField(max_length=20)
supplier_id = models.ForeignKey(Suppliers, on_delete=models.CASCADE)
Services model
class Services(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=20)
service_type = models.CharField(max_length=20)
supplier_id = models.ForeignKey(Suppliers, on_delete=models.CASCADE)
Part template
{% extends 'admintemplate/base_template.html' %}
{% block page_title %}
Add Parts
{% endblock page_title %}
{% block main_content %}
{% load static %}
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<!-- general form elements -->
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Add Parts</h3>
</div>
<!-- /.card-header -->
<!-- form start -->
<form role="form" method="POST" action="{% url 'add_part_save' %}">
{% csrf_token %}
{% comment %} Display Messages {% endcomment %}
{% if messages %}
<div class="form-group">
<div class="col-12">
{% for message in messages %}
{% if message.tags == "error" %}
<div class="alert alert-danger alert-dismissible fade show" role="alert" style="margin-top: 10px;">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% elif message.tags == "success" %}
<div class="alert alert-success alert-dismissible fade show" role="alert" style="margin-top: 10px;">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
<div class="card-body">
<div class="form-group">
<label>Part Name </label>
<input type="text" class="form-control" name="part_name" placeholder="Part Name">
</div>
<div class="form-group">
<label>Part Type </label>
<input type="text" class="form-control" name="part_type" placeholder="Part Type">
</div>
<div class="form-group">
<label>Supplier Name</label>
<select class="form-control" name="suppliers">
{% for supplier in suppliers %}
<option value="{{ supplier.id }}">{{ supplier.name }}</option>
{% endfor %}
</select>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="submit" class="btn btn-primary">Add Part</button>
</div>
</form>
</div>
<!-- /.card -->
</div>
</div>
</div><!-- /.container-fluid -->
</section>
{% endblock main_content %}
Now the services in parts template does not show up at all. There is no choices on the form. But, for the add services template, it does populate. I have no idea why this happens because I have used the exact same code for both templates.
Changing the view to this solved the issue
def add_part(request):
parts = Parts.objects.all()
context = {
"suppliers": suppliers
}
return render(request, 'admintemplate/add_parts_template.html', context)

Display & Update in same Django form

[A newbie Question] I have a form that shows the student details (query filtered by learner_code). I have an edit button that removes the "disabled" tag from fields & let user edit the form details. I have a Save button as well. I want to save the update back to the same entry in Student model.
My views.py :
query = None
if 'learner_code' in request.GET:
query = request.GET['learner_code']
try:
student_details = Student.objects.get(learner_code=query)
except:
messages.error(request, f'Student Not Found !')
return redirect('viewstudent')
else:
context = { 'student_details' : student_details}
return render(request, 'students/viewstudent.html', context)
elif 'learner_code' in request.POST :
# Save the data back to the table
else:
return render(request, 'students/createstudent.html')
My model looks like :
class Student(models.Model):
pay = (('FULL', 'FULL'),('EMI', 'EMI'))
learner_code = models.CharField(max_length=15, null=False, primary_key=True)
certificate_name = models.CharField(max_length=150, null=False)
contact1 = models.CharField(max_length=10, null=False)
contact2 = models.CharField(max_length=10)
batch = models.CharField(max_length=10)
doj = models.DateField(null=False, default=localtime(now()).date())
payment_method = models.CharField(choices=pay, max_length=4, default='FULL')
total_paid = models.IntegerField(default=0)
def __str__(self):
return self.learner_code
My forms.py is :
class StudentCreationForm(forms.ModelForm):
class Meta:
model = Student
fields = '__all__'
My Template looks like :
{% block content %}
<div class="container mx-auto mt-3">
{% block form %}
<form class="form-row mr-auto" action="" method="get">
<input type="text" class="form-control" name="learner_code" id="search" placeholder="Learner Code" style="width: 20pc;">
<button class="btn btn-success" type="submit">Search</button>
</form>
{% if messages %}
{% for message in messages %}
<div class="container-fluid">
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
</div>
{% endfor %}
{% endif %}
<hr>
<h2>STUDENT DETAILS</h2>
<div class="row my-2">
<div class="col-6">
<label for="id"><h6>LEARNER CODE : </h6></label>
<input type="text" name="id" id="id" placeholder="{{ student_details.learner_code }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="name"><h6>CERTIFICATE NAME : </h6></label>
<input type="text" name="name" id="name" placeholder="{{ student_details.certificate_name }}" disabled style="width: 20pc;">
</div>
</div>
<div class="row my-2">
<div class="col-6">
<label for="contact1"><h6>CONTACT NUMBER : </h6></label>
<input type="number" name="contact1" id="contact1" placeholder="{{ student_details.contact1 }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="contact2"><h6>ALT. CONTACT NO. : </h6></label>
<input type="number" name="contact2" id="contact2" placeholder="{{ student_details.contact2 }}" disabled style="width: 20pc;">
</div>
</div>
<div class="row my-2">
<div class="col-6">
<label for="batch"><h6>BATCH : </h6></label>
<input type="text" name="batch" id="batch" placeholder="{{ student_details.batch }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="doj"><h6>DATE OF JOINING : </h6></label>
<input type="text" name="doj" id="doj" placeholder="{{ student_details.doj }}" disabled style="width: 20pc;">
</div>
</div>
<div class="container-fluid mx-auto mt-5">
<button onclick="edits()">Edit</button>
<form action="" method="post">
{% csrf_token %}
<button type="submit">Save</button>
</form>
</div>
<hr>
<h2>FINANCIAL INFORMATION</h2>
<div class="row my-2">
<div class="col-6">
<label for="tenure"><h6>PAYMENT TENURE : </h6></label>
<input type="text" name="tenure" id="tenure" placeholder="{{ student_details.payment_method }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="paid"><h6>TOTAL PAID : </h6></label>
<input type="number" name="paid" id="paid" placeholder="{{ student_details.total_paid }}" disabled style="width: 20pc;">
</div>
</div>
{% endblock form %}
</div>
<script>
function edits()
{
document.getElementById("id").removeAttribute("disabled")
document.getElementById("id").setAttribute("value","{{ student_details.learner_code }}")
document.getElementById("name").removeAttribute("disabled")
document.getElementById("name").setAttribute("value","{{ student_details.certificate_name }}")
document.getElementById("contact1").removeAttribute("disabled")
document.getElementById("contact1").setAttribute("value","{{ student_details.contact1 }}")
document.getElementById("contact2").removeAttribute("disabled")
document.getElementById("contact2").setAttribute("value","{{ student_details.contact2 }}")
document.getElementById("batch").removeAttribute("disabled")
document.getElementById("batch").setAttribute("value","{{ student_details.batch }}")
document.getElementById("doj").removeAttribute("disabled")
document.getElementById("doj").setAttribute("value","{{ student_details.doj }}")
}
</script>
{% endblock content %}
You can use django model form and instance of the query to pre-populate the form to display and update in the same form
def your_view(request):
form = StudentCreationForm()
if request.method == "POST":
student_details = Student.objects.get(learner_code=query)
# To pre-populate the form with values using instance
form = StudentCreationForm(request.POST, instance=student_details)
if form.is_valid():
form.save()
return redirect('your_url')
return render(request, "students/createstudent.html", {'form': form })

Django Threaded Comments template

I code a social media site using Django. have a model for commenting my articles
class ArticleComment(models.Model):
parent = models.ForeignKey('self',
null=True,
blank=True,
related_name='replies',
on_delete=models.CASCADE)
article = models.ForeignKey(
Article,
on_delete=models.CASCADE,
related_name="comments")
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
# sort comments in chronological order by default
ordering = ('created_at',)
def __str__(self):
return 'Comment by {}'.format(self.user.username)
Now I try to render my threaded comments in my template. But i can not figure how to render my sub-comments in the same level. This is how I ended but this means only first level of replies.
<ul class="comments-list style-3" id="articleComments">
{% for comment in comments %}
<li class="comment-item has-children moreList">
<div class="comments-content">
<p>{{comment.content}}</p>
//toggle answer reply form
<a data-toggle="collapse" href="#{{comment.id}}"class="reply" role="button" aria-expanded="false" aria-controls="collapseExample">{% trans 'Reply' %}</a>
Report
<div>
<form id="{{comment.id}}" class="collapse" method="post">
<br>
{% csrf_token %}
<input type="hidden" name="parent" value="{{comment.id}}">
<div class="crumina-module crumina-heading with-title-decoration">
<h5 class="heading-title">{% trans 'Write a Reply' %}</h5>
</div>
<div class="row">
<div class="col col-6 col-xl-6 col-lg-6 col-md-6 col-sm-6">
<div class="form-group label-floating is-empty">
<label class="control-label">{% trans 'Reply Comment' %}</label>
<textarea class="form-control" placeholder="" name="content"></textarea>
</div>
<button class="btn btn-primary btn-lg full-width" type="Submit">{% trans 'Post your Reply' %}</button>
</div>
</div>
</form>
</div>
</div>
//try to loop comments with parent
{% if parent %}
<ul class="children first-children-level">
{% for reply in comment.replies.all %}
<li class="comment-item">
<div class="comments-content">
<p>{{reply.content}}</p>
Report
</div>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
can you guide me how to loop through sublevels ?
Thanks

Django forms using html elements with different name from moels field

In my django project i have this model:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,)
u_fullname = models.CharField(max_length=200)
u_email = models.EmailField()
u_profile = models.CharField(max_length=1)
u_job = models.CharField(max_length=100, null=True, blank=True, default='D')
u_country = models.CharField(max_length=20, null=True, blank=True, default='Italy')
u_regdata = models.DateTimeField(auto_now=True)
stripe_id = models.CharField(max_length=100, null=True, blank=True)
activation_code = models.CharField(max_length=10)
u_picture = models.ImageField(upload_to='profile_images', blank=True)
u_active = models.BooleanField(default=False)
u_terms = models.BooleanField(default=False)
def __unicode__(self):
return self.u_profile
and a forms.py like this one:
from a_profile.models import UserProfile
class ProfileModelForm(ModelForm):
class Meta:
model = UserProfile
fields = ['u_fullname',
'u_job',
'u_country',
'u_email',
'u_terms',
]
def clean(self):
cleaned_data = super(ProfileModelForm, self).clean()
u_fullname = cleaned_data.get('u_fullname')
u_job = cleaned_data.get('u_job')
u_country = cleaned_data.get('u_country')
u_email = cleaned_data.get('u_email')
u_terms = cleaned_data.get('u_terms')
if not u_terms:
raise forms.ValidationError("Please read and accept our Terms of Service")
if not u_fullname and not u_job and not u_country and not u_terms:
raise forms.ValidationError('You have to write something!')
return cleaned_data
well, now in html i have to use different names for element related to form fields:
<form action="" method="POST">
{% csrf_token %}
{{ form.errors }}
<div class="row">
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="text" name="u_fullname_C" id="u_fullname_c"
placeholder="Company Name">
<i class="la la-building"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_country_c" id="u_country_c"
value="{{ form.u_country }}">
<option selected="selected">Italy</option>
<option>Spain</option>
<option>USA</option>
<option>France</option>
</select>
<i class="la la-globe"></i>
<span><i class="fa fa-ellipsis-h"></i></span>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_job_c" id="u_job_c" value="{{ form.u_job }}">
<option selected="selected">Technology</option>
<option>Healthcare</option>
<option>Building</option>
<option>Aerospace</option>
</select>
<i class="la la-industry"></i>
<span><i class="fa fa-ellipsis-h"></i></span>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="text" name="u_email_c" id="u_email_c"
placeholder="Enter a valid email"
value="{{ form.u_email }}">
<i class="la la-envelope"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="u_password_c" id="u_password_c"
placeholder="Password">
<i class="la la-lock"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="repeat-password_c"
id="repeat-password_c"
placeholder="Repeat Password"
onfocusout="return checkPass('C')">
<i class="la la-lock"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="checky-sec st2">
<div class="fgt-sec">
<input type="checkbox" name="u_terms_c" id="u_terms_c">
<label for="u_terms_c"><span></span></label>
<span></span>
</label>
<small>Yes, I understand and agree to the workwise Terms &
Conditions.</small>
</div><!--fgt-sec end-->
</div>
</div>
<div class="col-lg-12 no-pdd">
<button type="submit" name="company" value="submit"
onclick="return checkUserRegForm('C')">Get Started
</button>
</div>
</div>
</form>
at this point when i run my code and enter data into form, when i Submit i get a form error because forms don't see value into my fields:
ERROR-> {'u_fullname': [ValidationError(['This field is required.'])], 'u_email': [ValidationError(['This field is required.'])], 'all': [ValidationError(['Please read and accept our Terms of Service'])]}
How can i link my form fields name to my html element name value?
So many thanks in advance
Here's a link to docs on the subject rendering fields manually.
I looked for awhile and this is what I came up with. I apologize I left some stuff out. In your view if you are able to get 'country code' options and 'job' options you could look over them in them template.
I added value="{{ form.u_fullname }}", and value="{{ form.u_terms }}".
<form method="" action="">
{% csrf_token %}
{{ form.errors }}
<div class="row">
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type='text' name="u_fullname_C" id="u_fullname_c"
value="{{ form.u_fullname }}" placeholder="">
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_country_c" id="">
{% for option in options %}
<option value="{{ option.pk }}">{{ option.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_job_c" id="u_job_c" value="{{ form.u_job }}">
{% for job in jobs %}
<option value="{{ job.pk }}">{{ job.name }}</option>
{% endfor %}
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type='text' name='u_email_c' id='u_email_c' placeholder="" value="{{ form.u_email }}">
<i class="la la-envelope"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="u_password_c" id="u_password_c" placeholder="Password">
<i class=""></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="repeat-password_c" id="repeat-password_c" placeholder="" onfocusout="return checkPass('C')">
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="checky-sec st2">
<div class="fgt-sec">
<input type="checkbox" value="{{ form.u_terms }}" name="u_terms_c" id="u_terms_c">
<label for="u_terms_c"><span></span>
<span></span>
</label>
<small>Yes, I understand and agree to the workwise Terms &
Conditions.
</small>
</div>
</div>
</div>
<div class="col-lg-12 no-pdd">
<button type='submit' name='company' value='submit' onclick="return checkUserRegForm('C')">
Get Started
</button>
</div>
</div>
</form>
If you are using a class view
class ProfileView(CreateView):
form_class = UserProfileForm
success_url = '/'
def form_valid(self, form):
user_profile = form.save(commit=False)
user_profile.updated = datetime.datetime.now()
user_profile.save()
return super().form_valid(form)
Or a function view:
def user_profile_view(request):
if request.method == 'POST':
form = ProfileModelForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
fullname = cd['u_fullname']
UserProfile.objects.create(user=request.user, u_fullname=fullname)
return redirect('')
else:
form = ProfileModelForm()
Would you be able to provide your views.py file? I'm still semi new to Django so let me know if you are still having troubles.