How to get value in Dropdown list on edit in Django template - django-views

I have a form (edit_city.html) where I want to edit my record, there is also one dropdown
field in which data is retrieving from another model name Country. How can I get the exact
value in dropdown field, when I click on edit.
Here is my Code
class Country(models.Model):
CountryID = models.AutoField(primary_key=True)
CountryName = models.CharField(max_length=125, verbose_name="Country Name")
def __str__(self):
return self.CountryName
class City(models.Model):
CityID = models.AutoField(primary_key=True)
CityName = models.CharField(max_length=125, verbose_name='City Name')
Country = models.ForeignKey(Country, verbose_name='Country Name',
on_delete=models.CASCADE)
def __str__(self):
return self.CityName
views.py
def Edit_City(request, id):
city = City.objects.get(CityID=id)
country = Country.objects.all()
context = {
'city':city,
'country':country,
}
return render(request, 'City/edit_city.html', context)
edit_city.html
<form method="post" action="{% url 'update_city' %}">
{% csrf_token %}
<div class="row">
<div class="col-12">
<h5 class="form-title"><span>Edit City</span></h5>
</div>
{% include 'includes/messages.html' %}
<div class="col-12 col-sm-6">
<div class="form-group">
<label for="">Country</label>
<select class="form-control" name="country_id" required>
<option>Select Country</option>
{% for con in country %}
<option value="{{con.CountryID}}">{{con.CountryName}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-12 col-sm-6">
<div class="form-group">
<label>City Name</label>
<input type="text" class="form-control" name="city_name" value="{{city.CityName}}" required>
<input type="text" class="form-control" name="city_id" value="{{city.CityID}}" required hidden>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Update City</button>
</div>
</div>
</form>

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>

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 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.

how to save many to many field in django

I am trying to save students from addstudent form but it is not saving students and it is displaying error message 'error in form'.Is there any solutions for this code.I think the error is in html template.
Error is like this:
AttributeError at /students/add/student/
'ErrorDict' object has no attribute 'status_code'
Request Method: POST
Request URL: http://127.0.0.1:8000/students/add/student/
Django Version: 2.1.5
Exception Type: AttributeError
Exception Value:
'ErrorDict' object has no attribute 'status_code'
models.py
class Course(models.Model):
title = models.CharField(max_length=250)
basic_price = models.CharField(max_length=100)
advanced_price = models.CharField(max_length=100)
basic_duration = models.CharField(max_length=50)
advanced_duration = models.CharField(max_length=50)
class Student(models.Model):
name = models.CharField(max_length=100)
course = models.ManyToManyField(Course)
address = models.CharField(max_length=200)
email = models.EmailField()
phone = models.CharField(max_length=15)
image = models.ImageField(upload_to='Students',blank=True)
joined_date = models.DateField()
forms.py
class AddStudentForm(forms.ModelForm):
class Meta:
model = Student
fields = '__all__'
views.py
def addstudent(request):
courses = Course.objects.all()
if request.method == 'POST':
form = AddStudentForm(request.POST,request.FILES)
if form.is_valid():
student = form.save()
student.save()
messages.success(request,'student saved.')
return redirect('students:add_student')
# else:
# return HttpResponse(form.errors) --> it returns course
else:
form = AddStudentForm()
return render(request,'students/add_student.html',{'form':form,'courses':courses})
add_student.html
<form action="{% url 'students:add_student' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<h5>Full Name <span class="text-danger">*</span></h5>
<div class="controls">
<input type="text" name="name" class="form-control" required data-validation-required-message="This field is required"> </div>
</div>
<div class="form-group">
<h5>Course <span class="text-danger">*</span></h5>
<div class="controls">
<select name="course" id="select" required class="form-control">
<option value="">Select Your Course</option>
{% for course in courses %}
<option value="{{course.title}}">{{course.title}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<h5>Address<span class="text-danger">*</span></h5>
<div class="controls">
<input type="text" name="address" class="form-control" required data-validation-required-message="This field is required"> </div>
</div>
<div class="form-group">
<h5>Phone Number <span class="text-danger">*</span></h5>
<div class="controls">
<input type="text" name="phone" data-validation-match-match="password" class="form-control" required> </div>
</div>
<div class="form-group">
<h5>Email <span class="text-danger">*</span></h5>
<div class="controls">
<input type="email" name="email" data-validation-match-match="password" class="form-control" required> </div>
</div>
<div class="form-group">
<h5>Date <span class="text-danger">*</span></h5>
<div class="controls">
<input type="date" name="joined_date" data-validation-match-match="password" class="form-control" required> </div>
</div>
<div class="form-group">
<h5>Image <span class="text-danger">*</span></h5>
<div class="controls">
<input type="file" name="image" class="form-control" > </div>
</div>
<div class="text-xs-right">
<button type="submit" class="btn btn-info">Submit</button>
</div>
</form>
You should output the value of form.errors as suggested in the comments to discover the exact error. However, I can see two immediate issues that are likely causing form validation to fail.
Firstly, because your form contains an image upload you must set the enctype to multipart/form-data in the template:
<form action="{% url 'students:add_student' %}" method="post" enctype="multipart/form-data">
Second, the uploaded image exists in request.FILES so you need to pass that to the form:
form = AddStudentForm(request.POST, request.FILES)
You have to save many to many field after save method.
if form.is_valid():
student = form.save(commit=False)
student.save()
form.save_m2m()

How to store many to many fields with checkbox values in databse using django

With this code i want to store multiple courses to the student table.But this code is not working.Neither it throws any error neither saves any data.The main problem is while clicking submit button the submit button does not perform any action at all.It does not load the submit button.How can i solve this??
I think the problem is in add_student.html template.When i return form.error it throws course.Is there anything i have to change??but i want to keep my design like this
models.py
class Course(models.Model):
title = models.CharField(max_length=250)
basic_price = models.CharField(max_length=100)
advanced_price = models.CharField(max_length=100)
basic_duration = models.CharField(max_length=50)
advanced_duration = models.CharField(max_length=50)
def __str__(self):
return self.title
class Student(models.Model):
name = models.CharField(max_length=100)
course = models.ManyToManyField(Course)
address = models.CharField(max_length=200)
email = models.EmailField()
phone = models.CharField(max_length=15)
image = models.ImageField(upload_to='Students',blank=True)
joined_date = models.DateField()
def __str__(self):
return self.name
views.py
def addstudent(request):
courses = Course.objects.all()
if request.method == 'POST':
form = AddStudentForm(request.POST,request.FILES)
if form.is_valid():
student = form.save()
student.save()
# student.course.set(courses)
messages.success(request, 'student saved.')
return redirect('students:add_student')
else:
return HttpResponse(form.errors) # it returns course.i think the problem is while saving the course
else:
form = AddStudentForm()
return render(request,'students/add_student.html',{'form':form,'courses':courses})
forms.py
class AddStudentForm(forms.ModelForm):
course = forms.ModelMultipleChoiceField( queryset=Course.objects.all(), widget=forms.CheckboxSelectMultiple)
class Meta:
model = Student
fields = ['name','course','email','address','phone','image','joined_date']
add_student.html
<form action="{% url 'students:add_student' %}"
method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<h5>Full Name <span class="text-danger">*</span></h5>
<div class="controls">
<input type="text" name="name" class="form-control" required data-validation-required-message="This field is required"> </div>
</div>
<div class="form-group">
<h5>Courses <span class="text-danger">*</span></h5>
<div class="controls">
{% for course in courses %}
<input name ="course" type="checkbox" id="{{course.title}}" required value="{{course.id}}">
<label for="{{course.title}}">{{course.title}}</label>
{% endfor %}
</div>
</div>
<div class="form-group">
<h5>Address<span class="text-danger">*</span></h5>
<div class="controls">
<input type="text" name="address" class="form-control" required data-validation-required-message="This field is required"> </div>
</div>
<div class="form-group">
<h5>Phone Number <span class="text-danger">*</span></h5>
<div class="controls">
<input type="text" name="phone" data-validation-required-message="This field is required" class="form-control" required> </div>
</div>
<div class="form-group">
<h5>Email <span class="text-danger">*</span></h5>
<div class="controls">
<input type="email" name="email" data-validation-required-message="This field is required" class="form-control" required> </div>
</div>
<div class="form-group">
<h5>Joined Date <span class="text-danger">*</span></h5>
<div class="controls">
<input type="date" name="joined_date" data-validation-required-message="This field is required" class="form-control" required> </div>
</div>
<div class="form-group">
<h5>Image <span class="text-danger">*</span></h5>
<div class="controls">
<input type="file" name="image" class="form-control" > </div>
</div>
<div class="text-xs-right">
<button type="submit" class="btn btn-info">Submit</button>
</div>
</form>
I'd recommend this solution:
courses = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset= Course.objects.all())
in views.py
if form.is_valid():
student = form.save(commit=False)
courses = form.cleaned_data['courses']
student.course = courses
student.save()
ps. it's a good practice to name m2m fields in plural:
courses = models.ManyToManyField(Course)
here's what I meant with templates:
in add_student.html
Comment out whole <form> block and replace it with Django's {{ form }} and see how it'd render
You have a queryset of courses passed in context to template. Try to change it from:
{% for course in courses %}
<input name ="course" type="checkbox" id="{{course.title}}" required value="{{course.title}}">
<label for="{{course.title}}">{{course.title}}</label>
{% endfor %}
to just:
{{ form.cource }}
Try a Class Based View
class CreateStudent(CreateView):
model = Student
form_class = AddStudentForm
template_name = "add_student.html"