I am trying to edit multiple rows of data in a model via formsets. In my rendered form, I use javascript to delete (hide and assign DELETE) rows, and then save changes with post.
My view:
def procedure_template_modification_alt(request, cliniclabel, template_id):
msg = ''
clinicobj = Clinic.objects.get(label=cliniclabel)
template_id = int(template_id)
template= ProcedureTemplate.objects.get(templid = template_id)
formset = ProcedureModificationFormset(queryset=SectionHeading.objects.filter(template = template))
if request.method == 'POST':
print(request.POST.get)
# Create a formset instance with POST data.
formset = ProcedureModificationFormset(request.POST)
if formset.is_valid():
print("Form is valid")
instances = formset.save(commit=False)
print(f'instances:{instances}')
for instance in instances:
print(f'Instance: {instance}')
instance.template = template
instance.save()
msg = "Changes saved successfully."
print("Deleted forms:")
for form in formset.deleted_forms:
print(form.cleaned_data)
else:
print("Form is invalid")
print(formset.errors)
msg = "Your changes could not be saved as the data you entered is invalid!"
template= ProcedureTemplate.objects.get(templid = template_id)
headings = SectionHeading.objects.filter(template = template)
return render(request, 'procedures/create_procedure_formset_alt.html',
{
'template': template,
'formset': formset,
'headings': headings,
'msg': msg,
'rnd_num': randomnumber(),
})
My models:
class ProcedureTemplate(models.Model):
templid = models.AutoField(primary_key=True, unique=True)
title = models.CharField(max_length=200)
description = models.CharField(max_length=5000, default='', blank=True)
clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
def __str__(self):
return f'{self.description}'
class SectionHeading(models.Model):
procid = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=200)
default = models.CharField(max_length=1000)
sortorder = models.IntegerField(default=1000)
fieldtype_choice = (
('heading1', 'Heading1'),
('heading2', 'Heading2'),
)
fieldtype = models.CharField(
choices=fieldtype_choice, max_length=100, default='heading1')
template = models.ForeignKey(ProcedureTemplate, on_delete=models.CASCADE, null=False)
def __str__(self):
return f'{self.name} [{self.procid}]'
My forms:
class ProcedureCrMetaForm(ModelForm):
class Meta:
model = SectionHeading
fields = [
'name',
'default',
'sortorder',
'fieldtype',
'procid'
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['name'].widget.attrs.update({'class': 'form-control'})
self.fields['default'].widget.attrs.update({'class': 'form-control'})
self.fields['sortorder'].widget.attrs.update({'class': 'form-control'})
self.fields['fieldtype'].widget.attrs.update({'class': 'form-control'})
ProcedureCreationFormset = formset_factory(ProcedureCrMetaForm, extra=3)
ProcedureModificationFormset = modelformset_factory(SectionHeading, ProcedureCrMetaForm,
fields=('name', 'default', 'sortorder','fieldtype', 'procid'),
can_delete=True,
extra=0
# widgets={"name": Textarea()}
)
The template:
{% block content %} {% load widget_tweaks %}
<div class="container">
{% if user.is_authenticated %}
<div class="row my-1">
<div class="col-sm-2">Name</div>
<div class="col-sm-22">
<input type="text" name="procedurename" class="form-control" placeholder="Enter name of procedure (E.g. DNE)"
value="{{ template.title }}" />
</div>
</div>
<div class="row my-1">
<div class="col-sm-2">Description</div>
<div class="col-sm-22">
<input type="text" name="proceduredesc" class="form-control" placeholder="Enter description of procedure (E.g. Diagnostic Nasal Endoscopy)"
value="{{ template.description }}" />
</div>
</div>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %} {{ formset.management_form }}
<div class="row mt-3">
<div class="col-sm-1">Select</div>
<div class="col-sm-6">Heading</div>
<div class="col-sm-8">Default (Normal description)</div>
<div class="col-sm-2">Sort Order</div>
<div class="col-sm-4">Type</div>
<div class="col-sm-2">Action</div>
</div>
{% for form in formset %}
<div class="row procrow" id="row{{ forloop.counter0 }}">
<div class="" style="display: none;">{{ form.procid }}</div>
<div class="col-sm-6">
{{ form.name }}
</div>
<div class="col-sm-8">
<div class="input-group">
{{ form.default }}
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
{{ form.sortorder }}
</div>
</div>
<div class="col-sm-4">
<div class="input-group">
{{ form.fieldtype }}
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
<div class="input-group-append">
<button id="add{{ forloop.counter0 }}" class="btn btn-success add-row">+</button>
</div>
<div class="input-group-append">
<button id="del{{ forloop.counter0 }}" class="btn btn-danger del-row">-</button>
</div>
</div>
</div>
</div>
{% endfor %} {% endif %}
<div class="row my-3">
<div class="col-sm-8"></div>
<div class="col-sm-8">
<div class="input-group">
<div class="input-group-append mx-1">
<button id="save_report" type="submit" class="btn btn-success"><i class="fal fa-shield-check"></i>
Save Report Format</button>
</div>
<div class="input-group-append mx-1">
<button id="save_report" type="button" class="btn btn-danger"><i class="fal fa-times-hexagon"></i>
Cancel</button>
</div>
</div>
</div>
<div class="col-sm-8"></div>
</div>
<div>
{% for dict in formset.errors %} {% for error in dict.values %} {{ error }} {% endfor %} {% endfor %}
</div>
</form>
</div>
{% endblock %}
My data is displayed as below (Screenshot). I make changes with javascript when the delete button is pressed, so that the html becomes like this:
<div class="row procrow" id="row2" style="display: none;">
<div class="" style="display: none;"><input type="hidden" name="form-2-procid" value="25" id="id_form-2-procid"></div>
<div class="col-sm-6">
<input type="text" name="form-2-name" value="a" maxlength="200" class="form-control" id="id_form-2-name">
</div>
<div class="col-sm-8">
<div class="input-group">
<input type="text" name="form-2-default" value="v" maxlength="1000" class="form-control" id="id_form-2-default">
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
<input type="number" name="form-2-sortorder" value="1000" class="form-control" id="id_form-2-sortorder">
</div>
</div>
<div class="col-sm-4">
<div class="input-group">
<select name="form-2-fieldtype" class="form-control" id="id_form-2-fieldtype">
<option value="heading1" selected="">Heading1</option>
<option value="heading2">Heading2</option>
</select>
</div>
</div>
<div class="col-sm-2">
<div class="input-group">
<div class="input-group-append">
<button id="add2" class="btn btn-success add-row">+</button>
</div>
<div class="input-group-append">
<button id="del2" class="btn btn-danger del-row">-</button>
</div>
</div>
</div>
<input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" checked=""></div>
On submitting the data, I get the following output, and data does not reflect the deletion I did. It displays the same thing again. There are no errors. But my edited data is not being saved.
Output:
<bound method MultiValueDict.get of <QueryDict: {'csrfmiddlewaretoken': ['ka3avICLigV6TaMBK5a8zeVJlizhtsKW5OTDBLlYorKd7Iji9zRxCX2vvjBv6xKu'], 'form-TOTAL_FORMS': ['3'], 'form-INITIAL_FORMS': ['3'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['1000'], 'form-0-procid': ['23'], 'form-0-name': ['External ear canal'], 'form-0-default': ['Bilateral external ear canals appear normal. No discharge.'], 'form-0-sortorder': ['100'], 'form-0-fieldtype': ['heading1'], 'form-1-procid': ['24'], 'form-1-name': ['Tympanic membrane'], 'form-1-default': ['Tympanic membrane appears normal. Mobility not assessed.'], 'form-1-sortorder': ['500'], 'form-1-fieldtype': ['heading1'], 'form-2-procid': ['25'], 'form-2-name': ['a'], 'form-2-default': ['v'], 'form-2-sortorder': ['1000'], 'form-2-fieldtype': ['heading1'], 'form-2-DELETE': ['on']}>>
Form is valid
instances:[]
Deleted forms:
{'name': 'a', 'default': 'v', 'sortorder': 1000, 'fieldtype': 'heading1', 'procid': <SectionHeading: a [25]>, 'DELETE': True}
You actually need to delete the instances: Loop through the formsets' deleted_objects property after you called saved(commit=False) and delete them.
Related
I have this view with two forms.
def anunciocreateview(request):
anuncio_form = AnuncioForm(request.POST or None)
producto_form = ProductoForm(request.POST or None)
if request.method == "POST":
if all([anuncio_form.is_valid(), producto_form.is_valid(), imagen_form.is_valid()]):
anuncio = anuncio_form.save(commit=False)
anuncio.anunciante = request.user
anuncio.save()
producto = producto_form.save(commit=False)
producto.anuncio = anuncio
producto.save()
return HttpResponse(status=204, headers={'HX-Trigger' : 'eventsListChanged'})
else:
anuncio_form = AnuncioForm()
producto_form = ProductoForm()
context = {
'anuncio_form' : anuncio_form,
'producto_form' : producto_form,
}
return render(request, 'buyandsell/formulario.html', context)
This view works OKAY; it allows the user to create instances of both models with the correct relation. I'm trying to add another form for the image of the product. I tried adding this:
def anunciocreateview(request):
anuncio_form = AnuncioForm(request.POST or None)
producto_form = ProductoForm(request.POST or None)
imagen_form = ImagenForm(request.POST, request.FILES)
if request.method == "POST":
if all([anuncio_form.is_valid(), producto_form.is_valid(), imagen_form.is_valid()]):
anuncio = anuncio_form.save(commit=False)
anuncio.anunciante = request.user
anuncio.save()
producto = producto_form.save(commit=False)
producto.anuncio = anuncio
producto.save()
imagen = imagen_form.request.FILES.get('imagen')
if imagen:
Imagen.objects.create(producto=producto, imagen=imagen)
return HttpResponse(status=204, headers={'HX-Trigger' : 'eventsListChanged'})
else:
print(request.FILES)
else:
anuncio_form = AnuncioForm()
producto_form = ProductoForm()
imagen_form = ImagenForm()
context = {
'anuncio_form' : anuncio_form,
'producto_form' : producto_form,
'imagen_form' : imagen_form
}
return render(request, 'buyandsell/formulario.html', context)
But this happens:
1- The 'Image upload' form field shows error 'This field is required' at the moment of rendering the form.
2- If uploading an image and clicking submit, the redirect doesn't happen as the imagen_form is not marked as valid. No error pops in the console whatsoever (I'm handling requests with HTMX).
If I omit the 'request.FILES' when instantiating the form, the error when the form renders disappear, but it anyway doesn't upload the image nor the form.
What am I missing?
For reference, here is the HTML file:
<form class="row g-3" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create new listing</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="{{ anuncio_form.titulo.auto_id }}">{{ anuncio_form.titulo.label }}</label>
{% render_field anuncio_form.titulo|add_error_class:"is-invalid" class="form-control" %}
</div>
<div class="mb-3">
<label for="{{ anuncio_form.envio.auto_id }}">{{ anuncio_form.envio.label }}</label>
{% translate "Select available delivery options" as input_place_holder %}
{% render_field anuncio_form.envio|add_error_class:"is-invalid" class="form-control" placeholder=input_place_holder %}
</div>
<h5>Product:</h5>
<div class="mb-3">
<label for="{{ producto_form.nombre.auto_id }}">{{ producto_form.nombre.label }}</label>
{% translate "Name of your product" as input_place_holder %}
{% render_field producto_form.nombre|add_error_class:"is-invalid" class=" form-control" placeholder=input_place_holder %}
</div>
<div class="mb-3">
<label for="{{ producto_form.descripcion.auto_id }}">{{ producto_form.descripcion.label }}</label>
{% translate "Give a detailed description of your product" as input_place_holder %}
{% render_field producto_form.descripcion|add_error_class:"is-invalid" class=" form-control" placeholder=input_place_holder %}
</div>
<div class="row g-3">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.estado.auto_id }}">{{ producto_form.estado.label }}</label>
{% render_field producto_form.estado|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.cantidad.auto_id }}">{{ producto_form.cantidad.label }}</label>
{% render_field producto_form.cantidad|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
</div>
<div class="row g-3">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.precio_unitario.auto_id }}">{{ producto_form.precio_unitario.label }}</label>
{% render_field producto_form.precio_unitario|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ producto_form.disponibilidad.auto_id }}">{{ producto_form.disponibilidad.label }}</label>
{% render_field producto_form.disponibilidad|add_error_class:"is-invalid" class=" form-control" %}
</div>
</div>
</div>
<h5>Images:</h5>
<div class="mb-3">
<label for="{{ imagen_form.imagen.auto_id }}">{{ imagen_form.imagen.label }}</label>
{% render_field imagen_form.imagen|add_error_class:"is-invalid" class=" form-control" %}
</div>
<div id="productforms"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-tertiary" hx-get="{% url 'buyandsell:create-product' %}" hx-target="#productforms" hx-swap="beforeend">Add new product</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary" hx-post="{% url 'buyandsell:createview' %}">Submit</button>
</div>
</div>
</form>
Edit:
forms.py for ImagenForm:
class ImagenForm(ModelForm):
class Meta:
model = Imagen
fields = ['imagen']
models.py for the Imagen model:
class Imagen(models.Model):
producto = models.ForeignKey(Producto, on_delete=models.CASCADE, related_name='imagen', blank=True, null=True)
imagen = models.ImageField(upload_to='marketplace/')
def __str__(self):
return f"Imagen de {self.producto}"
def save(self, *args, **kwargs):
self.image = resize_image(self.image, size=(350, 350))
super().save(*args, **kwargs)
Don't initialize forms with request.POST if it is not a POST request.
Two changes to fix your issue:
move first form init block under if request.method == "POST"
move else block one tab to the left so it becomes else to if request.method == "POST" instead of current version where it is else to if .is_valid()
if request.method == "POST":
anuncio_form = AnuncioForm(request.POST or None)
producto_form = ProductoForm(request.POST or None)
imagen_form = ImagenForm(request.POST, request.FILES)
if all([anuncio_form.is_valid(), producto_form.is_valid(), imagen_form.is_valid()]):
...
else:
anuncio_form = AnuncioForm()
producto_form = ProductoForm()
imagen_form = ImagenForm()
Now you use request.POST only on POST requests, instead you show empty forms. If a form is invalid on POST then it will be rendered with errors (if template is done cottectly) instead of showing empty forms back again.
For handling multiple forms with one view/template take a look at these answers: one two three
upd
For HTMX-requests it is also required to set hx-encoding="multipart/form-data" in form element attributes. Similar question HTMX docs
I am using Form Wizard in Django. My form is okay the problem is adding multiple person details in the form. There is a button on the HTML to add person. If it is click there is a drop down. For now the code works for adding one person only. Is there a way that you can repeat the step in FormWizard if the user wants to add many people? Do I need to save it in session? Thank you
HTML
{% extends "incident_report_home.html" %}
{% block form_if %}{% block form_else %}
{% csrf_token %}
<fieldset>
{% comment %} <legend>Title</legend> {% endcomment %}
<div>
{% comment %} <label>{{ form.field.label }}:<p class="note">{{ form.field.help_text }}</p></label>
<hr> {% endcomment %}
<button class="btn btn-primary" type="button" data-toggle="collapse"
data-target="#collapsePeople" aria-expanded="false"
aria-controls="collapsePeople">
<i class='bx bx-plus'></i> Add Person
</button>
<div class="collapse pt-4" id="collapsePeople">
<form>
<div class="form-row">
<div class="form-group col-md-4">
<label for="inputFirstName">First Name</label>
{{form.incident_first_name}}
</div>
<div class="form-group col-md-4">
<label for="inputMiddleName">Middle Name</label>
{{form.incident_middle_name}}
</div>
<div class="form-group col-md-4">
<label for="inputLastName">Last Name</label>
{{form.incident_last_name}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label for="inputAge">Age</label>
{{form.incident_age}}
</div>
<div class="form-group col-md-4">
<label for="inputGender">Gender</label>
{{form.incident_gender}}
</div>
</div>
<div class="form-group">
<label for="inputAddress">Address</label>
{{form.incident_address}}
</div>
<!-- ================================= -->
<hr>
<div class="form-row">
<div class="form-group col-md-4">
<label for="inputInvolvement">Involvement</label>
{{form.incident_involvement}}
</div>
<div class="form-group col-md-4">
<label for="inputID">ID Presented</label>
{{form.incident_id_presented}}
</div>
<div class="form-group col-md-4">
<label for="inputIDNumber">ID Number</label>
{{form.incident_id_number}}
</div>
</div>
<div class="form-group">
<label for="inputInjury">Injury</label>
{{form.incident_injury}}
</div>
<div class="form-group">
<label for="inputInjury">Driver Error</label>
{{form.incident_driver_error}}
</div>
<div class="form-group">
<label for="inputInjury">Alcohol / Drugs</label>
{{form.incident_alcohol_drugs}}
</div>
<div class="form-group">
<label for="inputInjury">Seat belt / Helmet </label>
{{form.incident_seatbelt_helmet}}
</div>
<br>
<div class="modal-footer mb-3">
<input type="button" class="btn btn-secondary" data-dismiss="modal"
value="Clear">
<input type="submit" class="btn btn-primary" value="Save">
</div>
</div>
<p class="error">
{% if form.field.errors %}
{% for error in form.field.errors %}
{{ error }}
{% endfor %}
{% endif %}
</p>
</div>
</fieldset>
{% endblock %}{% endblock %}
Views
FORMS = [("information", UserReportForm),
("general", IncidentGeneralForm),
("people", IncidentPersonForm),
("vehicle",IncidentVehicleForm),
("media", IncidentMediaForm),
("remarks", IncidentRemarksForm)]
TEMPLATES = {"information": "pages/super/incident_report_user.html",
"general": "pages/super/incident_report_general.html",
"people": "pages/super/incident_report_people.html",
"vehicle": "pages/super/incident_report_vehicle.html",
"media": "pages/super/incident_report_media.html",
"remarks": "pages/super/incident_report_remarks.html"}
TEMPLATES1 = {"information": "pages/admin/incident_report_user.html",
"general": "pages/admin/incident_report_general.html",
"people": "pages/admin/incident_report_people.html",
"vehicle": "pages/admin/incident_report_vehicle.html",
"media": "pages/admin/incident_report_media.html",
"remarks": "pages/admin/incident_report_remarks.html"}
class multistepformsubmission(SessionWizardView):
# template_name = 'pages/incident_report.html'
# form_list = [UserReportForm, IncidentGeneralForm, IncidentPersonForm, IncidentVehicleForm, IncidentMediaForm, IncidentRemarksForm]
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'media'))
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
def done(self, form_list, **kwargs):
# UserReport, IncidentGeneral, IncidentRemark, AccidentCausationSub, CollisionTypeSub, IncidentMedia, IncidentPerson, IncidentVehicle
profile = get_object_or_404(UserProfile, user=self.request.user)
user_instance = UserReport()
general_instance = IncidentGeneral()
person_instance = IncidentPerson()
vehicle_instance = IncidentVehicle()
media_instance = IncidentMedia()
remarks_instance = IncidentRemark()
#listing_instance.created_by = self.request.user
#listing_instance.listing_owner = self.request.user
#listing_instance.listing_type = 'P'
for form in form_list:
user_instance = construct_instance(form, user_instance, form._meta.fields, form._meta.exclude)
general_instance = construct_instance(form, general_instance, form._meta.fields, form._meta.exclude)
person_instance = construct_instance(form, person_instance, form._meta.fields, form._meta.exclude)
vehicle_instance = construct_instance(form, vehicle_instance, form._meta.fields, form._meta.exclude)
media_instance = construct_instance(form, media_instance, form._meta.fields, form._meta.exclude)
remarks_instance = construct_instance(form, remarks_instance, form._meta.fields, form._meta.exclude)
user_instance.user = self.request.user
user_instance.status = 2
user_instance.save()
general_instance.user_report = user_instance
general_instance.save()
person_instance.incident_general = general_instance
person_instance.save()
vehicle_instance.incident_general = general_instance
vehicle_instance.save()
media_instance.incident_general = general_instance
media_instance.save()
remarks_instance.incident_general = general_instance
remarks_instance.save()
context = {
'profile': profile
}
return redirect('/userReports', context)
def incident_form_super(request):
attWizardView = multistepformsubmission.as_view(FORMS)
return attWizardView(request)
URL
path('incidentReport/formsubmissions', views.incident_form_super, name='incident_form_super'),
Trying to edit a profile using a form I have that should allow a user to edit her first name, last name and email. Problem is when I try editing the form nothing happens. Still trying to learn Django so could be something I am missing/not getting right.
Here is my form;
<form id="edit-mentor-profile" class="form-horizontal" method="post" >
{% csrf_token %}
<div class="form-group">
<label for="photo" class="col-sm-2 control-label">Avatar</label>
<div class="col-md-6">
<div class="media v-middle">
<div class="media-left">
<div class="icon-block width-100 bg-grey-100">
<i class="fa fa-photo text-light"></i>
</div>
</div>
<div class="media-body">
</i>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-md-2 control-label">Full Name</label>
<div class="col-md-8">
<div class="row">
<div class="col-md-6">
<div class="form-control-material">
<input type="text" class="form-control" id="edit-mentor-profile-first_name" placeholder= {{ user.first_name }}>
<label for="edit-mentor-profile-first_name"></label>
</div>
</div>
<div class="col-md-6">
<div class="form-control-material">
<input type="text" class="form-control" id="edit-mentor-profile-last_name" placeholder={{ user.last_name }}>
<label for="edit-mentor-profile-last_name"></label>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="email" class="col-md-2 control-label">Email</label>
<div class="col-md-6">
<div class="form-control-material">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
<input type="email" class="form-control" id="edit-mentor-profile-email" placeholder={{ user.email }}>
<label for="edit-mentor-profile-email"></label>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-6">
<div class="checkbox checkbox-success">
<input id="checkbox3" type="checkbox" checked="">
<label for="checkbox3">Subscribe to our Newsletter</label>
</div>
</div>
</div>
<div class="form-group margin-none">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary paper-shadow relative" data-z="0.5" data-hover-z="1" data-animated>Save Changes</button>
</div>
</div>
</form>
this is what I have on forms.py
class TeacherSignUpForm(UserCreationForm):
email = forms.EmailField(max_length=100)
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
linkedin = forms.URLField(max_length=200)
class Meta(UserCreationForm.Meta):
model = User
fields = ('email', 'username', 'first_name', 'last_name')
def save(self, commit=True):
self.instance.is_teacher = True
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
mentor = Mentor.objects.create(
user=user,
linkedin=self.cleaned_data['linkedin']
)
return user
forms.py
# edit mentor profile
class MentorProfileForm(forms.Form):
first_name = forms.CharField(widget=forms.TextInput(attrs={'type': 'text', 'id': 'edit-mentor-profile-first_name',
'class': 'form-control'}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'type': 'text', 'id': 'edit-mentor-profile-last_name',
'class': 'form-control'}))
email = forms.EmailField(widget=forms.EmailInput(attrs={'type': 'email', 'id': 'edit-mentor-profile-email',
'class': 'form-control'}))
and teachers.py(views.py)
class TeacherSignUpView(CreateView):
model = User
form_class = TeacherSignUpForm
template_name = 'registration/signup_form.html'
def get_context_data(self, **kwargs):
kwargs['user_type'] = 'teacher'
return super().get_context_data(**kwargs)
def form_valid(self, form):
user = form.save()
# user.set_password(form.cl)
login(self.request, user)
return redirect('teachers:app-instructor-dashboard')
#edit mentor profile
def edit_user(request):
user = request.user
form = MentorProfileForm(initial={'first_name':user.first_name,'last_name':user.last_name,'email':user.email})
if request.method == 'POST':
if form.is_valid():
user.first_name = request.POST['first_name']
user.last_name = request.POST['last_name']
user.email = request.POST['email']
# user.password = request.POST['password']
user.save()
return HttpResponseRedirect('%s'%(reverse('profile')))
context = {
"form":form
}
return render(request, 'classroom/teachers/app-instructor-profile.html', context)
UPDATE
Based on the answer provided I made the following changes
html form:
<form id="edit-mentor-profile" class="form-horizontal" method="post" >
{% csrf_token %}
<div class="form-group">
<label for="photo" class="col-sm-2 control-label">Avatar</label>
<div class="col-md-6">
<div class="media v-middle">
<div class="media-left">
<div class="icon-block width-100 bg-grey-100">
<i class="fa fa-photo text-light"></i>
</div>
</div>
<div class="media-body">
</i>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-md-2 control-label">Full Name</label>
<div class="col-md-8">
<div class="row">
<div class="col-md-6">
<div class="form-control-material">
{{ form.first_name }}
<label for="edit-mentor-profile-first_name"></label>
</div>
</div>
<div class="col-md-6">
<div class="form-control-material">
{{ form.last_name }}
<label for="edit-mentor-profile-last_name"></label>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="email" class="col-md-2 control-label">Email</label>
<div class="col-md-6">
<div class="form-control-material">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
{{ form.email }}
<label for="edit-mentor-profile-email"></label>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-6">
<div class="checkbox checkbox-success">
<input id="checkbox3" type="checkbox" checked="">
<label for="checkbox3">Subscribe to our Newsletter</label>
</div>
</div>
</div>
<div class="form-group margin-none">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary paper-shadow relative" data-z="0.5" data-hover-z="1" data-animated>Save Changes</button>
</div>
</div>
</form>
and forms.py
class MentorProfileForm(forms.Form):
class Meta:
widgets = {
'first_name': forms.TextInput(attrs={'class':'form-control'}),
'last_name': forms.TextInput(attrs={'class':'form-control'}),
'email': forms.EmailInput(attrs={'class':'form-control'})
}
With these changes I cannot interact with the form. I cannot click the textboxes available.
Here is a sample of what i am seeing
You should render the inputs using the form field elements themselves
Instead of this
<input type="text" class="form-control" id="edit-mentor-profile-first_name" placeholder= {{ user.first_name }}>
Use this
{{ form.first_name }}
If you need to add the class to the input then in your model form add the class attribute to the field's widget
class Meta:
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control'})
}
I have the following custom wizard
<div class="container">
<div id="smartwizard">
<ul>
<li>Engagement Setup<br /><small>Basic info</small></li>
<li>File Upload<br /><small>Upload files</small></li>
<li>Business Rules<br /><small>rules</small></li>
<li>Documentation<br /><small>documentation</small></li>
</ul>
<div>
<div id="step-1" class="">
<div id="form-step-0" role="form" data-toggle="validator">
<div class="form-group">
<label for="text">Code <span class="tx-danger">*</span></label>
<input type="text" class="form-control" name="code" id="code" placeholder="Write your code" required>
<div class="help-block with-errors"></div>
</div>
</div>
<hr />
</div>
....
</div>
</div>
<br />
</div>
I have setup the django form as such
class PageOne(forms.Form):
ibs_code = forms.CharField(max_length=100)
engagement_name = forms.CharField(max_length=100)
engagement_manager = forms.CharField(max_length=100)
engagement_partner = forms.CharField(max_length=100)
solution = forms.CharField(label='What solution would you like to use?', widget=forms.Select(choices=FRUIT_CHOICES))
And of course the views..
class TestWizard(SessionWizardView):
file_storage = FileSystemStorage(
location=os.path.join(settings.MEDIA_ROOT, 'temp_uploads'))
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.is_done = False
def get_template_names(self):
if self.is_done:
# return [self.templates['done']]
return [TEMPLATES['done']]
else:
return [TEMPLATES[self.steps.current]]
.....
......
Now I want to use the custom template with the form. Meaning, I want to generate the form fields the way the html/style looks with form-group and such. How can I achieve this?
I tried the documentation but they weren't any sources for custom templating
Update #1: Doing something like this is not sufficient
<div id="form-step-0" role="form">
<div class="form-group">
{% if wizard.form.forms %}
{{wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{form}}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
</div>
</div>
I need it to look just like the html I put together
First, you can specify the class to be used for your form fields, for example:
class PageOne(forms.Form):
ibs_code = forms.CharField(
max_length=100,
widget=forms.TextInput(
attrs={'class' : 'YourClassName'}
)
)
Second, you can put the individual fields within the template as you want
<div class="container">
<div id="smartwizard">
<ul>
<li>Engagement Setup<br /><small>Basic info</small></li>
<li>File Upload<br /><small>Upload files</small></li>
<li>Business Rules<br /><small>rules</small></li>
<li>Documentation<br /><small>documentation</small></li>
</ul>
<form>
{{ wizard.form.management_form }}
{% csrf_token %}
<div>
<div id="step-1" class="">
<div id="form-step-0" role="form" data-toggle="validator">
<div class="form-group">
<label for="text">Code <span class="tx-danger">*</span></label>
{{ form.ibs_code }}
{{ form.ibs_code.errors }}
</div>
</div>
<hr />
</div>
....
</div>
</form>
</div>
<br />
</div>
EDIT - ACTUAL LIVE EXMAPLE
<form id="" class="max-width-800px margin-center" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ wizard.management_form }}
{{ wizard.form.media }}
<input name="job-is_user" type="checkbox" hidden {% if request.user.is_authenticated %}checked{% endif %}>
<input name="job-is_company" type="checkbox" hidden {% if request.user.company_user %}checked{% endif %}>
<div class="form-group">
<label for="id_job-plan_"PLANS[0].id >Job Listing Type</label>
{{ wizard.form.plan }}
<div class="alert alert-primary top-3">Jobs are subscription-based and are active until you've filled the position. At the end of your recurring billing cycle you will be charged and your listing will be moved back to the top of its category.</div>
</div>
<div class="form-group row">
<div class="col-6">
<label for="id_job-title">Job Title</label>
{{ wizard.form.title }}
</div>
<div class="col-6">
<label for="id_job-category">Job Category</label>
<span class="form-select">
{{ wizard.form.category }}
</span>
</div>
</div>
<div class="form-group">
<label for="">Job Type</label>
<div class="row">
{% for employment in EMPLOYMENTS %}
<div class="col-4">
<span class="form-radio form-radio-lg">
<input type="radio" id="id_job-employment_{{employment.id}}" name="job-employment" value="{{ employment.id }}" required {% if job.employment.id == employment.id or wizard.form.employment.value|add:"0" == employment.pk %}checked{% endif %}>
<label for="id_job-employment_{{employment.id}}">{{ employment }}</label>
</span>
</div>
{% endfor %}
</div>
</div>
<div class="form-group row">
<div class="col-6">
<label for="id_job-job_level">Job Level</label>
<span class="form-select">
{{ wizard.form.job_level }}
</span>
</div>
<div class="col-6">
<label for="id_job-salary_range">Job Compensation</label>
<span class="form-select">
{{ wizard.form.salary_range }}
</span>
</div>
</div>
<div id="job-location-groupX" class="form-group">
<label for="id_job-office_base">Job Location</label>
<div class="row">
{% for office in OFFICE_BASE %}
<div class="col-6">
<span class="form-radio form-radio-lg">
<input type="radio" id="id_job-office_base_{{office.id}}" name="job-office_base" value="{{ office.id }}" {% if job.office_base.id == office.id or wizard.form.office_base.value|add:"0" == office.pk %}checked{% endif %}>
<label for="id_job-office_base_{{office.id}}">{{ office.name }}</label>
</span>
</div>
{% endfor %}
</div>
<div id="new-job-location-details" class="hidden top-1">
{{ wizard.form.outside_location }}
{{ wizard.form.outside_location.errors }}
<ul class="list-unstyled list-increase-spacing">
<li>
<span class="form-checkbox">
{{ wizard.form.relocation_assistance }}
<label id="label-id_job-relocation_assistance" for="id_job-relocation_assistance">Relocation assistance provided</label>
{{ wizard.form.relocation_assistance.errors }}
</span>
</li>
<li>
<span class="form-checkbox">
{{ wizard.form.visa_sponsorship }}
<label for="id_job-visa_sponsorship">Visa sponsorship provided</label>
{{ wizard.form.visa_sponsorship.errors }}
</span>
</li>
</ul>
</div>
</div>
<div class="form-group">
<label for="id_job-description">Job Description</label>
<div class="col-12">
{{ wizard.form.description }}
{{ wizard.form.description.errors }}
</div>
</div>
<div id="job-how-to-apply-groupX" class="form-group">
<label>How to Apply to This Job</label>
<div class="row">
<div class="col-6">
<span class="form-radio form-radio-lg">
<input type="radio" required id="new-job-apply-us" value="4" name="job-apply_online" {% if job.apply_online == 4 or wizard.form.apply_online.value|add:"0" == 4 %}checked {% endif %}>
<label for="new-job-apply-us">Through us <em class="float-right tablet-hide">(recommended)</em></label>
</span>
</div>
<div class="col-6">
<span class="form-radio form-radio-lg">
<input type="radio" id="new-job-apply-you" name="job-apply_online" value="3" {% if job.apply_online == 3 or wizard.form.apply_online.value|add:"0" == 3 %}checked {% endif %}>
<label for="new-job-apply-you">Through you <em class="float-right tablet-hide">(external URL)</em></label>
</span>
</div>
</div>
<div id="new-job-apply-details" class="hidden top-1">
{{ wizard.form.apply_url }}
{{ wizard.form.howto_apply }}
</div>
</div>
<div id="job-extras" class="form-group">
<h6>Additional Extras <span class="optional-field">(optional)</span></h6>
{{ wizard.form.addons }}
</div>
<button type="submit" class="btn btn-lg btn-solid-teal">{% if request.user.company_user %}Preview Your Listing{% elif request.user.is_authenticated %}Enter Company Details{% else %}User Details{% endif %} →</button>
</form>
forms.py
class JobPostWizardForm1(forms.ModelForm):
error_css_class = "alert alert-error"
category = forms.ModelChoiceField(Category.objects.all(), empty_label='Choose one...', required=False)
job_level = forms.ModelChoiceField(JobLevel.objects.all(), empty_label='Choose one...', required=False)
salary_range = forms.ModelChoiceField(Salary.objects.active(), empty_label='Choose one...', required=False)
plan = forms.ModelChoiceField(Plan.objects.all(), empty_label=None, required=True, widget=PlanSelect)
is_user = forms.BooleanField(required=False)
is_company = forms.BooleanField(required=False)
class Meta:
model = Job
fields = [
'plan','title','category','employment','job_level','salary_range','office_base', 'outside_location',
'relocation_assistance','visa_sponsorship','description','apply_online','howto_apply','addons', 'is_user',
'is_company', 'apply_url'
]
def __init__(self, is_active= False, edit_mode=False, plan=0, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['plan'].initial = Plan.objects.all()[plan]
if is_active : self.fields['plan'].widget.attrs['disabled'] = True
self.fields['description'].required = True
self.fields['apply_url'].widget.attrs['placeholder'] = 'External URL'
self.fields['howto_apply'].widget = forms.Textarea()
self.fields['howto_apply'].widget.attrs['rows']=10
self.fields['howto_apply'].widget.attrs['placeholder']="Additional instructions..."
self.fields['relocation_assistance'].widget = AuthenticJobsCheckbox()
self.fields['visa_sponsorship'].widget = AuthenticJobsCheckbox()
self.fields['addons'].widget = AddOnCheckboxSelectMultiple()
self.fields['addons'].queryset = AddOnItem.objects.filter(active=True)
#if edit_mode : self.fields['addons'].widget.attrs['disabled'] = True
if is_active : self.fields['addons'].widget.attrs['onclick'] = "return false;"
self.error_class = DivErrorList
Can anyone please help me..... I keep on getting "data didn't validate" error when saving data from a ModelForm. Everything worked fine for me until I added some CSS and JS for the frontend, used form widgets and manually displayed the form field on the template.
Here are the codes:
forms.py
from django import forms
from .models import List_of_Res
class fordtp(forms.Form):
month_choices=(
('JAN','January'),
('FEB','February'),
('MAR','March'),
('APR','April'),
('MAY','May'),
('JUN','June'),
('JUL','July'),
('AUG','August'),
('SEP','September'),
('NOV','November'),
('DEC','December'),
)
day_choices=[]
for ddd in range(1,32):
day_toS=(str(ddd),str(ddd))
day_choices.append(day_toS)
year_choices=[]
for yyy in range(1990,2100):
year_toS=(str(yyy),str(yyy))
year_choices.append(year_toS)
month = forms.ChoiceField(choices = month_choices,widget=forms.Select(attrs={'class':'form-control form-control-sm'}))
year = forms.ChoiceField(choices = year_choices,widget=forms.Select(attrs={'class':'form-control form-control-sm'}))
day = forms.ChoiceField(choices = day_choices,widget=forms.Select(attrs={'class':'form-control form-control-sm'}))
class ResearchForm(forms.ModelForm):
class Meta:
model = List_of_Res
fields={
'prog_title',
'proj_title',
'stud_title',
'prog_lead',
'stud_lead',
'co_res',
'res_site',
'campus',
'category_res',
'classif_res',
'amt_granted',
'date_started',
'res_status',
'date_completed',
'res_SF',
'res_pubstat',
'res_JN',
'res_JV',
'date_pub',
'res_iprstat',
'apptype',
'date_appl',
'date_pprv',
'app_pending',
'res_abs'
}
widgets = {
'prog_title': forms.TextInput(attrs={'class':'form-control'}),
'proj_title': forms.TextInput(attrs={'class':'form-control'}),
'stud_title': forms.TextInput(attrs={'class':'form-control'}),
'prog_lead': forms.TextInput(attrs={'class':'form-control'}),
'stud_lead': forms.TextInput(attrs={'class':'form-control'}),
'co_res': forms.Textarea(attrs={'class':'form-control','placeholder':'Enter 1 name per line'}),
'res_site': forms.Textarea(attrs={'class':'form-control','placeholder':'Enter 1 site per line'}),
'campus': forms.Select(attrs={'class':'form-control'}),
'category_res': forms.RadioSelect(attrs={'class':'form-check-input'}),
'classif_res': forms.Select(attrs={'class':'form-control'}),
'amt_granted': forms.TextInput(attrs={'class':'form-control'}),
'date_started': forms.DateInput(attrs={'placeholder':'YYYY-MM-DD','class':'form-control'}),
'res_status': forms.RadioSelect(attrs={'class':'form-check-input'}),
'date_completed': forms.DateInput(attrs={'placeholder':'YYYY-MM-DD','class':'form-control'}),
'res_SF': forms.CheckboxSelectMultiple(attrs={'class':'form-check-input'}),
'res_pubstat': forms.RadioSelect(attrs={'class':'form-check-input'}),
'res_JN': forms.TextInput(attrs={'class':'form-control'}),
'res_JV': forms.TextInput(attrs={'class':'form-control'}),
'date_pub': forms.DateInput(attrs={'placeholder':'YYYY-MM-DD','class':'form-control'}),
'res_iprstat':forms.RadioSelect(attrs={'class':'form-check-input'}),
'apptype':forms.RadioSelect(attrs={'class':'form-check-input'}),
'date_appl':forms.DateInput(attrs={'placeholder':'YYYY-MM-DD','class':'form-control'}),
'date_pprv':forms.DateInput(attrs={'placeholder':'YYYY-MM-DD','class':'form-control'}),
'app_pending': forms.RadioSelect(attrs={'class':'form-check-input'}),
'res_abs': forms.Textarea(attrs={'class':'form-control'})
}
(views.py):
from django.shortcuts import render
from django.http import HttpResponse
from .forms import ResearchForm
from .models import List_of_Res
def RIS_Home(request):
return render(request,'RIS/RIS_Home.html')
def Add_Res(request):
if request.method=='POST':
form = ResearchForm(request.POST)
if form.is_valid():
resAdd=form.save(commit=False)
resAdd.save()
else:
form = ResearchForm()
args = {'form':form}
return render(request,'RIS/RIS_Add-Edit.html',args)
(models.py)
from django.db import models
class List_of_Res(models.Model):
Yes_no_Choices = (('YES','YES'),('NO','NO'))
Stat_choices = (("COMPLETED","Completed"),("ON_GOING","On-Going"))
Campus_choices = (
("APARRI","Aparri"),
("LASAM","Lasam"),
("LALLO","Lal-lo"),
("SANCHEZ_MIRA","Sanchez Mira"),
("CARIG","Carig"),
("ANDREWS","Andrews"),
("PIAT","Piat")
)
Category_choices = (
("BASIC","Basic"),
("APPLIED","Applied"),
("PILOT_TESTING","Pilot Testing"),
("TECHNOLOGY_PROMOTION_COMMERCIALIZATION","Technology Promotion / Commercialization")
)
Classification_choices = (
("AGRICULTURE","Agriculture"),
("BIOTECHNOLOGY","Biotechnology"),
("ICT","ICT"),
("HEALTH_PRODUCTS","Health Products"),
("ALTERNATIVE_ENERGY","Alternative Energy"),
("CLIMATE_CHANGE","Climate Change"),
("ENVIRONMENT","Environment"),
("SOCIO_ECONOMIC","Socio-economic"),
("NATURAL_PRODUCTS","Natural Products"),
("OTHER","Other")
)
Source_fund_choices = (
("CSU","CSU"),
("CHED","CHED"),
("DA_BAR","DA-BAR"),
("DOST","DOST"),
("PCCARRD","PCCARRD"),
("PCIERD","PCIERD"),
("PCHRD","PCHRD"),
("DA","DA"),
("OTHER","Other")
)
IPR_Type_choices = (
("PATENT","Patent"),
("UTILITY_MODEL","Utility Model"),
("TRADEMARK_TRADENAME","Trademark/Tradename"),
("COPYRIGHT","Copyright"),
("OTHER","Other")
)
prog_title = models.CharField(max_length=1000)
proj_title = models.CharField(max_length=1000)
stud_title = models.CharField(max_length=1000)
prog_lead = models.CharField(max_length=300)
stud_lead = models.CharField(max_length=300)
co_res = models.TextField()
res_site = models.TextField()
campus = models.CharField(max_length=50,choices=Campus_choices,default='ANDREWS')
category_res = models.CharField(max_length=50,choices=Category_choices,default='BASIC')
classif_res = models.CharField(max_length=50,choices=Classification_choices,default='ICT')
amt_granted = models.TextField()
date_started = models.TextField()
res_status = models.CharField(max_length=10, choices=Stat_choices, default='COMPLETED')
date_completed = models.TextField()
res_SF = models.TextField(choices=Source_fund_choices,default='CSU')
res_pubstat = models.CharField(max_length=5,choices=Yes_no_Choices, default='YES')
res_JN = models.TextField()
res_JV = models.CharField(max_length=100)
date_pub = models.TextField()
res_iprstat = models.CharField(max_length=10, choices=Yes_no_Choices, default='YES')
apptype = models.CharField(max_length=100,choices=IPR_Type_choices,default='PATENT')
date_appl = models.TextField()
date_pprv = models.TextField()
app_pending = models.CharField(max_length=10, choices=Yes_no_Choices, default='YES')
res_abs = models.CharField(max_length=1000)
end this is the html template
{% extends 'RIS/RIS_Home.html' %}
{% block body %}
<div class="container">
<form method="post">
<div>
{% csrf_token %}
<div>
<div class="row"><div class="boxed_content">Title of Research</div></div>
<br>
<div class="row">
<label class="label_style_AEform">Program Title</label>
<br>
{{ form.prog_title }}
</div>
<div class="row">
<label class="label_style_AEform">Project Title</label>
<br>
{{ form.proj_title }}
</div>
<div class="row">
<label class="label_style_AEform">Study Title</label>
<br>
{{ form.stud_title }}
</div>
</div>
<br>
<div>
<br>
<div class="row"><div class="boxed_content">Researcher/s</div></div>
<br>
<div class="row">
<div class="col">
<div class="row">
<label class="label_style_AEform">Program Leader</label>
<br>
{{ form.prog_lead }}
</div>
<br><br><br>
<div class="row">
<label class="label_style_AEform">Study Leader</label>
<br>
{{ form.stud_lead }}
</div>
</div>
<div class="col">
<label class="label_style_AEform">Co-Researcher/s</label>
<br>
{{ form.co_res }}
</div>
</div>
</div>
<div>
<br>
<div class="row"><div class="boxed_content">Site / Location of study</div></div>
<br>
<div class="row">
{{ form.res_site }}
</div>
</div>
<div>
<br>
<div class="row"><div class="boxed_content">Category of Research</div></div>
{% for rdo in form.category_res %}
<div class="form-check form-check-inline">
{{ rdo }}
</div>
{% endfor %}
</div>
<br>
<div>
<div class="row">
<div class="col">
<div class="row"><div class="boxed_content">Classification of Research<br>
{{ form.classif_res }}
</div></div>
</div>
<div class="col">
<div class="row"><div class="boxed_content">Campus<br>
{{ form.campus }}
</div></div>
</div>
</div>
</div>
<br>
<div>
<div class="row">
<div class="col">
<div class="row"><div class="boxed_content">Source of Fund</div></div>
{% for chk in form.res_SF %}
<div class="form-check form-check-inline">
{{ chk }}
</div>
{% endfor %}
</div>
<div>
<div class="col">
<div class="row"><div class="boxed_content">Amount Granted<br>{{ form.amt_granted }}</div></div>
</div>
</div>
</div>
</div>
<br>
<div>
<div class="row">
<div class="col">
<div class="row"><div class="boxed_content">Status of Research</div></div>
{% for rdo in form.res_status %}
<div class="form-check form-check-inline">
{{ rdo }}
</div>
{% endfor %}
</div>
<div class="col">
<div class="row"><div class="boxed_content">Date Started<br>
<div class="form-check form-check-inline">
{{ form.date_started }}
</div>
</div></div>
</div>
<div class="col">
<div class="row"><div class="boxed_content">Date Completed<br>
<div class="form-check form-check-inline">
{{ form.date_completed }}
</div>
</div></div>
</div>
</div>
</div>
<br>
<div class="row">
<div class="boxed_content">Is the research published?
{% for rdo in form.res_pubstat %}
<div class="form-check form-check-inline">
{{ rdo }}
</div>
{% endfor %}
</div>
<br>
<div class="row">
<div class="col">
<label class="label_style_AEform">If Yes,</label>
</div>
<div class="col">
<label class="label_style_AEform">Name of Journal</label>
{{ form.res_JN }}
</div>
<div class="col">
<label class="label_style_AEform">Volume</label>
{{ form.res_JV }}
</div>
<div class="col">
<label class="label_style_AEform">Date Published</label>
<div class="form-check form-check-inline">
{{ form.date_pub }}
</div>
</div>
</div>
</div>
<br>
<div class="row">
<div class="boxed_content">Does the research have IPR application?
{% for rdo in form.res_iprstat %}
<div class="form-check form-check-inline">
{{ rdo }}
</div>
{% endfor %}
</div>
<br>
<div class="row">
<div class="col">
<label class="label_style_AEform">If Yes, Application Type: </label>
{% for rdo in form.apptype %}
<div class="form-check form-check-inline">
{{ rdo }}
</div>
{% endfor %}
</div>
</div>
<div class="row">
<div class="col">
<label class="label_style_AEform">Date of Application</label>
<div class="form-check form-check-inline">
{{ form.date_appl }}
</div>
</div>
<div class="col">
<label class="label_style_AEform">Date of Approval of application</label>
<div class="form-check form-check-inline">
{{ form.date_pprv }}
</div>
</div>
<br>
<div class="col">
<label class="label_style_AEform">Is the application Pending? </label>
{% for rdo in form.app_pending %}
<div class="form-check">
{{ rdo }}
</div>
{% endfor %}
</div>
</div>
</div>
<div class="row">
<div class="boxed_content">Abstract of the study</div>
<br>
{{ form.res_abs }}
</div>
</div>
<div class="row"><button type="submit" class="btn btn-primary mb-2">SAVE</button></div>
</form>
</div>
{% endblock %}
You should use MultipleChoiceField in your forms as a widget.
'res_SF': forms.MultipleChoiceField(attrs={'class':'form-check-input'}),