data did'nt validate error django - python

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'}),

Related

Please how can get the number of listings in a category, i have tried

I have a django app and I need to count the number of listings in a category (as defined by the models below):
here is my complete model
class Category(models.Model):
name = models.CharField(max_length=500)
icon = models.ImageField(upload_to='photos/icons/%Y/%m/%d/')
def __str__ (self):
return self.name
class Listing(models.Model):
name = models.CharField(max_length=300)
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=False, null=True)
email = models.EmailField(max_length=300)
description = RichTextField(blank=False, null=False)
photo_main = models.ImageField(upload_to = 'photos/%Y/%m/%d/')
photo_1 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
photo_2 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
photo_3 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
photo_4 = models.ImageField(upload_to = 'photos/%Y/%m/%d/', blank=True, default=True)
location = models.CharField(max_length=500, null=True)
phone_number = models.CharField(max_length=11, default = "#")
website = models.CharField(max_length=150, blank=True, default="#")
facebook = models.CharField(max_length=150, blank=True, default="#")
instagram = models.CharField(max_length=150, blank=True, default="#")
opening_time = models.CharField(max_length=7)
closing_time = models.CharField(max_length=7)
is_published = models.BooleanField(default=False)
posted_date = models.DateTimeField(auto_now_add=True)
user_id = models.IntegerField(blank=True)
def __str__ (self):
return self.name
here are my views
from django.shortcuts import render
from listings.models import Listing
from listings.models import Category
from testimonies.models import Testimony
from our_team.models import Team_Mate
from testimonies.models import Testimony
from django.db.models import Count
def index(request):
this part is working perfectly.
listings = Listing.objects.order_by('-posted_date').filter(is_published=True)[:6]
category = request.GET.get('category')
categories = Category.objects.all()[:7]
counting listings in a category
count_cate = Category.objects.all()
cate_count = count_cate.count()
if category == None:
listings = Listing.objects.order_by('-posted_date').filter(is_published=True)[:6]
else:
listings = Listing.objects.filter(Category__name=category)
here is my context
context ={
'listings': listings,
'categories': categories,
'cate_count': cate_count,
}
return render(request, 'pages/index.html', context)
Here is my html where I want the number of listings in category to show
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- ======= Intro Section ======= -->
<div class="header">
<div class="header-content display-table">
<div class="table-cell">
<div class="container">
<h1 class="header-title text-light text-uppercase pb-3">Explore Bonny Island</h1>
<h3 class="text-light">Find. Connect. Share</h3>
<div class="search mt-3 px-0 py-1 mx-0">
<form action="{% url 'search' %}" method="GET">
{% csrf_token %}
<div class="row d-flex justify-content-center container p-0 m-0 px-1">
<input type="text" name="keywords"
class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5"
placeholder=" Keyword">
<input type="text" name="location"
class="form-control col-lg-3 col-md-12 mx-2 py-4 col-sm-12 my-2 border border-5"
placeholder=" Location">
<input type="text" name="category" value="{{ query }}" list="category"
class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5"
placeholder=" Category (All)">
<datalist id="category">
{% for categories in categories %}
<option>{{ categories.name }}</option>
{% endfor %}
</datalist>
<button type="submit"
class="btn search-bt col-lg-2 col-md-12 mx-2 col-sm-12 py-2 px-2 font-weight-bold my-
2">Search</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div><!-- End Intro Section -->
<!-- ======== most popular categories ========= -->
<section class="main">
<div class="discover pb-1 m-0">
<h2>Explore Categories</h2>
<div class="container">
<div class="row justify-content-around m-0 p-0 pt-3">
{% for category in categories %}
{% if category %}
<div class="col-lg-3 col-md-6 py-2">
<a href="{% url 'listings' %}?category={{ category.name }}" class="card category">
<div class="d-flex justify-content-between align-items-start px-3 m-0 py-2">
<div class="category-name-icon p-0 m-0">
<span class="text-dark font-weight-bold"><img class="category-icon" src="{{
category.icon.url }}">
{{category.name}}</span>
</div>
<div class="category-list-number text-muted font-weight-bold">{{cate_count}}</div>
</div>
</a>
</div>
{% endif %}
{% endfor %}
<div class="col-lg-3 col-md-6 py-2">
<a href="{% url 'category' %}" class="card category" data-bs-toggle="collapse"
href="#collapseExample"
role="button" aria-expanded="false" aria-controls="collapseExample">
<div class="d-flex justify-content-between = px-3 m-0 py-2">
<i class="font-weight-bold py-1 text-secondary">More Categories...</i>
</div>
</a>
</div>
</div>
</div>
</section> <!-- ======== most popular categories end ======== -->
<!-- STRUCTURING THE POPULAR LISTINGS CONTENT-->
<section id="popularListings" class="container mb-5 py-5">
<!-- Popular listenings head title-->
<div class="sectionTitle d-flex justify-content-between align-items-baseline">
<div class="mainTitleContents">
<h2 class="titleText h2 text-blue">Popular Listings</h2>
<p class="subTitleText mb-2">Explore businesses on the island.</p>
</div>
<div class="filterOption">
All Listings
</div>
</div>
<!-- MAIN POPULAR LISTINGS ROW CONTENT-->
<div class="popularListingsRows row py-2">
{% if listings %}
{% for listing in listings %}
<div class="customCard p-1 m-0 col-lg-3 col-md-4 col-sm-6 mt-sm-3">
<div class="card">
<div class="card-header p-0">
<div class="blank rounded" style="background-image: url('{{
listing.photo_main.url }}'); background-repeat: no-repeat;
background-size:cover; width:100%; height: 15em; background-
position:center-top" ;></div>
</div>
<div class="card-body">
<div class="content-details">
<h3 class="m-0 mt-1 mb-2 cardTitle">{{ listing.name }}</h3>
<p class="cardSubTitle">
{%autoescape off%}
{{ listing.description|striptags|truncatechars:100 }}
{%endautoescape%}
</p>
<a href="{% url 'listing' listing.id %}" class="btn btn-sm bg-blue text-
light rounded-none">Read More</a>
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="col-md-12">
<p class="text-dark">No listings Available</p>
</div>
{% endif %}
</div>
</section>
{% endblock %}
How can I make this code work as intended?
You should call the count method on the list of objects like...
if category == None:
listings = Listing.objects.order_by('-posted_date').filter(is_published=True)[:6]
else:
listings = Listing.objects.filter(category__name=category).count()
Please ensure where you have Category__name=category you must allow this to match your model field category.
In your html:
<!-- ======= Intro Section ======= -->
<form action="{% url 'search' %}" method="GET">
{% csrf_token %}
<div class="row d-flex justify-content-center container p-0 m-0 px-1">
...
<!--<input type="text" name="category" value="{{ query }}" list="category" class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5" placeholder=" Category (All)">-->
<!-- Remove value="{{ query }}" -->
<input type="text" name="category" list="categories" class="form-control col-lg-3 col-md-12 col-sm-12 mx-2 py-4 my-2 border border-5" placeholder=" Category (All)">
<!-- Should be category in categories instead of categories in categories -->
<datalist id="categories">
{% for category in categories %}
<option value="{{ category.name }}"> <!-- Setting the value here... -->
{% endfor %}
</datalist>
...
</div>
</form>
I solved the it by calling the name of the category i want to count but am still to look for a way to count it without specifying the category name.
cate_count = Listing.objects.filter(category__name="Catering services").count()

Django formtools with custom template

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

How can I filter foreignkeys in models?

I have created two models, Porumbei and Perechi. Porumbei means pigeon and it can be male or female, they live in pairs(Perechi). My models below(part of it)
class Gender(models.Model):
sexul = models.CharField(max_length=20, null=False, blank=False)
def __str__(self):
return self.sexul
class Porumbei(models.Model):
....
serie_inel = models.CharField(....)
sex = models.ForeignKey(Gender, on_delete=models.CASCADE)
....
class Perechi(models.Model):
....
mascul = models.ForeignKey(Porumbei, on_delete=models.CASCADE)
femela = models.ForeignKey(Porumbei, on_delete=models.CASCADE)
My form:
class AdaugaPereche(forms.Form):
boxa = forms.IntegerField(label="Boxa", min_value=1)
sezon = forms.CharField(label="Sezon reproducere", initial=datetime.now().year)
mascul = forms.ChoiceField(choices=Porumbei.objects.filter(sex__sexul="Mascul", perechi_masculi__isnull=True), label="Mascul")
femela = forms.ChoiceField(choices=Porumbei.objects.filter(sex__sexul="Femelă", perechi_femele__isnull=True), label="Femela")
serie_pui_1 = forms.CharField(label="Serie pui 1")
serie_pui_2 = forms.CharField(label="Serie pui 2")
culoare_pui_1 = forms.ChoiceField(choices=CuloriPorumbei.objects.all(), label="Culoare pui 1")
culoare_pui_2 = forms.ChoiceField(choices=CuloriPorumbei.objects.all(), label="Culoare pui 2")
data_imperechere = forms.DateField(label="Dată împerechere")
primul_ou = forms.DateField(label="Primul ou")
data_ecloziune = forms.DateField(label="Dată ecloziune")
data_inelare = forms.DateField(label="Dată inelare")
comentarii = forms.Textarea()
My view:
def perechenoua(request):
if request.method == "POST":
form = AdaugaPereche(request.POST)
if form.is_valid():
form.save()
return redirect("porumbei")
else:
form = AdaugaPereche()
context = {
'form': form
}
template = loader.get_template("adauga_pereche.html")
return HttpResponse(template.render(context, request))
The template:
<form method="post">{% csrf_token %}
<div class="form-group row">
<div class="col-sm-3">
{{ form.boxa|add_class:"form-control" }}
</div>
<div class="col-sm-3">
{{ form.sezon|add_class:"form-control" }}
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
{{ form.mascul|add_class:"form-control custom-select d-block w-100" }}
</div>
<div class="col-sm-3">
{{ form.femela|add_class:"form-control custom-select d-block w-100" }}
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
{{ form.serie_pui_1|add_class:"form-control" }}
</div>
<div class="col-sm-3">
{{ form.serie_pui_2|add_class:"form-control custom-select d-block w-100" }}
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
{{ form.culoare_pui_1|add_class:"form-control custom-select d-block w-100" }}
</div>
<div class="col-sm-3">
{{ form.culoare_pui_2|add_class:"form-control custom-select d-block w-100" }}
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
{{ form.data_imperechere }}
</div>
<div class="col-sm-3">
{{ form.primul_ou }}
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
{{ form.data_ecloziune }}
</div>
<div class="col-sm-3">
{{ form.data_inelare }}
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
{{ form.comentarii }}
</div>
</div>
</form>
When I create a new Perechi(pair), the field mascul I want to be sorted with all male in Porumbei(pigeons) and once it has been added to pairs, the next time when adding pairs that male to be excluded from list because it already have pair. The same with female. How can I implement this?
You can use the limit_choices_to argument of ForeignKey to directly limit the choices:
from django.db.models import Q
mascul = models.ForeignKey(Porumbei, on_delete=models.CASCADE,
limit_choices_to=Q(sex__sexul="male",
related_name="pairs_as_male"))
Here's the documentation.
With the related_name you can also query the reverse relationship:
Porumbei.objects.filter(sex__sexul="male", pairs_as_male__isnull=True)
will give you male pigeons that aren't paired yet.

Saving edited data via formsets

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.

Django: Checkboxes are not saved while FormValidationError

I am working with a CreateView. When sending my form with all fields properly filled out, the field tickets (ManyToMany field) is also saved. However if I POST my form with some validation error (e.g. required field empty), then all the pre-filled fields are still field through request.POST. However, my pre-checked fields are not selected anymore. Do you know why?
Demonstration
view.py
class DiscountCreate(AdminPermissionRequiredMixin, SuccessMessageMixin,
FormValidationMixin, BaseDiscountView, CreateView):
form_class = DiscountForm
template_name = 'discounts/admin/create.html'
success_message = _("Discount Code has been successfully created.")
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['event'] = self.request.event
return kwargs
def get_success_url(self):
return reverse('discounts:admin:detail', kwargs={
'organizer': self.request.organizer.slug,
'event': self.request.event.slug,
'discount': self.instance.pk
})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['type_fixed'] = Discount.TYPE_FIXED
context['type_percentage'] = Discount.TYPE_PERCENTAGE
return context
def form_valid(self, form):
self.instance = form.save(commit=False)
self.instance.event = self.request.event
self.instance.status = Discount.STATUS_ACTIVE
return super().form_valid(form)
Template
<div class="card">
<div class="card-header">
<h4 class="card-header-title">
{% trans "Creating Discount Code" %}
</h4>
</div>
<div class="card-body">
<form method="post" autocomplete="off" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="{{ form.code.id_for_label }}">
{{ form.code.label }}
</label>
{{ form.code }}
{% if form.code.errors %}
<div class="invalid-feedback d-block">
{{ form.code.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.type.id_for_label }}">
{{ form.type.label }}
</label>
{{ form.type }}
{% if form.type.errors %}
<div class="invalid-feedback d-block">
{{ form.type.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group fixed{% if form.type.value != type_fixed %} d-none {% endif %}">
{{ form.value.label_tag }}
<div class="input-group">
{{ form.value }}
<div class="input-group-append">
<span class="input-group-text text-dark">{{ request.event.currency }}</span>
</div>
</div>
{% if form.value.errors %}
<div class="invalid-feedback d-block">
{{ form.value.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group percentage{% if form.type.value != type_percentage %} d-none {% endif %}">
{{ form.percentage.label_tag }}
<div class="input-group">
{{ form.percentage }}
<div class="input-group-append">
<span class="input-group-text text-dark">%</span>
</div>
</div>
{% if form.percentage.errors %}
<div class="invalid-feedback d-block">
{{ form.percentage.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
{{ form.available_amount.label_tag }}
{{ form.available_amount }}
{% if form.available_amount.errors %}
<div class="invalid-feedback d-block">
{{ form.available_amount.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.tickets.id_for_label }}">
{{ form.tickets.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.tickets.help_text }}</small>
{% for ticket_id, ticket_label in form.tickets.field.choices %}
<div class="custom-control custom-checkbox">
<input
type="checkbox"
name="{{ form.tickets.html_name }}"
value="{{ ticket_id }}"
class="custom-control-input"
id="id_{{ form.tickets.html_name }}_{{ forloop.counter }}"
{% if ticket_id in form.tickets.value %}checked{% endif %}>
<label class="custom-control-label" for="id_{{ form.tickets.html_name }}_{{ forloop.counter }}">{{ ticket_label }}</label>
</div>
{% endfor %}
{% if form.tickets.errors %}
<div class="invalid-feedback d-block">
{{ form.tickets.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.valid_from.id_for_label }}">
{{ form.valid_from.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.valid_from.help_text }}</small>
{{ form.valid_from }}
{% if form.valid_from.errors %}
<div class="invalid-feedback d-block">
{{ form.valid_from.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.valid_until.id_for_label }}">
{{ form.valid_until.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.valid_until.help_text }}</small>
{{ form.valid_until }}
{% if form.valid_until.errors %}
<div class="invalid-feedback d-block">
{{ form.valid_until.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.comment.id_for_label }}">
{{ form.comment.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.comment.help_text }}</small>
{{ form.comment }}
{% if form.comment.errors %}
<div class="invalid-feedback d-block">
{{ form.comment.errors|first }}
</div>
{% endif %}
</div>
<button type="submit" class="btn btn-primary btn-block">{% trans "Create Discount Code" %}</button>
</form>
</div>
</div> {# / .card #}
<a class="btn btn-block btn-link text-muted mb-4" href="{% url 'discounts:admin:index' request.organizer.slug request.event.slug %}">
{% trans "Cancel discount code creation" %}
</a>
forms.py
class DiscountForm(forms.ModelForm):
# Remove required attribute from HTML elements
use_required_attribute = False
value = forms.DecimalField(decimal_places=2, required=False)
percentage = forms.DecimalField(max_digits=4, decimal_places=2, required=False)
class Meta:
model = Discount
fields = (
'code',
'type',
'value',
'percentage',
'available_amount',
'tickets',
'valid_from',
'valid_until',
'comment',
)
def __init__(self, *args, **kwargs):
self.event = kwargs.pop('event')
super().__init__(*args, **kwargs)
for visible_field in self.visible_fields():
visible_field.field.widget.attrs['class'] = 'form-control'
self.fields['tickets'].queryset = self.event.tickets.all()
self.fields['code'].widget.attrs['autofocus'] = True
self.fields['valid_from'].widget.attrs['class'] = 'form-control start-date picker'
self.fields['valid_until'].widget.attrs['class'] = 'form-control end-date picker'
self.fields['valid_from'].widget.format = settings.DATETIME_INPUT_FORMATS[0]
self.fields['valid_until'].widget.format = settings.DATETIME_INPUT_FORMATS[0]
self.fields['valid_from'].widget.attrs['data-lang'] = get_lang_code()
self.fields['valid_until'].widget.attrs['data-lang'] = get_lang_code()
def clean(self):
cleaned_data = super().clean()
discount_type = cleaned_data.get('type')
if discount_type:
if discount_type == Discount.TYPE_FIXED:
value = cleaned_data.get('value')
cleaned_data['percentage'] = None
if not value:
message = _("Please enter how much discount you want to give.")
self.add_error('value', forms.ValidationError(message))
if discount_type == Discount.TYPE_PERCENTAGE:
percentage = cleaned_data.get('percentage')
cleaned_data['value'] = None
if not percentage:
message = _("Please enter how much discount you want to give.")
self.add_error('percentage', forms.ValidationError(message))
def clean_value(self):
value = self.cleaned_data['value']
if value:
value = smallest_currency_unit_converter(
value,
self.event.currency,
)
return value
def clean_percentage(self):
percentage = self.cleaned_data['percentage']
if percentage:
percentage /= 100 # convert 19 to 0.19
return percentage
def clean_valid_until(self):
valid_until = self.cleaned_data['valid_until']
if valid_until and valid_until > self.event.end_date:
valid_until = self.event.end_date
return valid_until
def clean_valid_from(self):
valid_from = self.cleaned_data['valid_from']
if valid_from and valid_from > self.event.end_date:
raise forms.ValidationError(_("Discount code should become valid \
before the event starts."), code='valid_from')
return valid_from
def clean_code(self):
code = self.cleaned_data['code']
code_check = self.event.discounts.filter(
code=code
).exclude(pk=self.instance.pk).exists()
if code_check:
raise forms.ValidationError(_("The code you chose as your discount code \
already exists for this event. Please change it."), code='code_exists')
return code
After I broke the problem down, the final solution that helped me can be found here: Django template: {% if 5 in ['4', '3', '5'] %} doesn't work

Categories