Django form validation is failing - django

form.is_valid is always set to false in the below code. How do I implement the code to check why its false.
I have given the code to forms.py, model.py and views.py below.
forms defines the form
views processes the form
model defined the model
forms.py
class VolunteerForm(forms.ModelForm):
volposition = forms.CharField(label="VolunteerPosition",widget=forms.Textarea(attrs={'cols':30,'rows':1}))
roledesc = forms.CharField(label="Role Description",widget=forms.Textarea(attrs={'cols':30,'rows':5}))
noofhours = forms.CharField(widget=forms.Select(choices=NO_OF_HRS_MONTH),max_length=2)
Qualreqt = forms.CharField(label="Qualifications and Requirements",widget=forms.Textarea(attrs={'cols':30,'rows':5}))
Duration = forms.CharField(widget=forms.Select(choices=NO_OF_HRS),max_length=2)
Durationyrmon = forms.CharField(widget=forms.Select(choices=YR_MONTH),max_length=10)
posstatus = forms.CharField(widget=forms.Select(choices=POS_STATUS),max_length=1)
teamrelation = forms.CharField(max_length=50)
class Meta:
model = Volunteer
views.py
def volunteersignupform_2_model(form):
if not form.is_valid():
return None
data = form.cleaned_data
signup = Contact(email=data['email'],
phone=data['phone'],
first_name=data['first_name'],
last_name=data['last_name'],
location=data['location'],
other_location=data['other_location'],
new_ac=data['new_ac'],
int_volunteer=data['int_volunteer'],
int_projects=data['int_projects'],
int_fundraise=data['int_fundraise'],
int_it=data['int_it'],
int_programs=data['int_programs'],
int_marketing=data['int_marketing'],
age=data['age'],
occupation=data['occupation'],
intro_source=data['intro_source'],
comments=data['comments'])
signup.save()
# The next line is needed for signup.get_location_display() function to
# work
signup = Contact.objects.get(id=signup.id)
return signup
models.py
NO_OF_HRS = (
('1','1'),
('2','2'),
('3','3'),
('4','4'),
('5','5'),
('6','6'),
('7','7'),
('8','8'),
('9','9'),
('10','10'),
('11','11'),
('12','12'),
)
YR_MONTH = (
("Y", "Year"),
("M", "Month"),
)
POS_STATUS = (
("A", "Active"),
("C", "Closed"),
)
NO_OF_HRS_MONTH = (
("10","10"),
("20","20"),
("30","30"),
("40","40"),
("50","50"),
("60","60"),
("70","70"),
("80","80"),
("90","90"),
)
class Volunteer(models.Model):
datecreated = models.DateTimeField()
volposition = models.CharField(max_length=100)
roledesc = models.CharField(max_length=400)
noofhours = models.CharField(choices=NO_OF_HRS_MONTH,max_length=2)
Qualreqt = models.CharField(max_length=500)
Duration = models.CharField(choices=NO_OF_HRS,max_length=2)
Durationyrmon = models.CharField(choices=YR_MONTH,max_length=10)
posstatus = models.CharField(choices=POS_STATUS,max_length=1)
teamrelation = models.CharField(max_length=50)

Related

select filtering and removal if they are already present in the db

look at the picture before answering me.
that group2 is inside saved in the db with the button I open a modal that allows me to save other groups in the db and I would like that the same groups no longer appear in that select if I have already added them
form.py
class EserciziForm(forms.ModelForm):
class Meta:
model = models.DatiEsercizi
exclude = ['gruppo_single']
#fields = '__all__'
class GruppiForm(forms.ModelForm):
class Meta:
model = models.DatiGruppi
exclude = ['gruppi_scheda']
views.py
def creazione(request, nome):
scheda = get_object_or_404(Schede, nome_scheda = nome)
eserciziFormSet = formset_factory(EserciziForm, extra = 0)
if request.method == "POST":
gruppo_form = GruppiForm(request.POST, prefix = 'gruppo')
if gruppo_form.is_valid():
gruppo = gruppo_form.save(commit = False)
gruppo.gruppi_scheda = scheda
gruppoName = gruppo_form.cleaned_data['dati_gruppo']
gruppo.save()
esercizi_formset = eserciziFormSet(request.POST, prefix='esercizi')
for esercizi in esercizi_formset:
esercizi_instance = esercizi.save(commit = False)
esercizi_instance.gruppo_single = get_object_or_404(DatiGruppi, gruppi_scheda = scheda.id, dati_gruppo = gruppoName)
esercizi_instance.save()
return HttpResponseRedirect(request.path_info)
else:
gruppo_form = GruppiForm(prefix = 'gruppo')
esercizi_formset = eserciziFormSet(prefix='esercizi')
context = {'scheda' : scheda, 'gruppo_form' : gruppo_form, 'esercizi_formset': esercizi_formset}
return render(request, 'crea/passo2.html', context
models.py
class DatiGruppi(models.Model):
giorni_settimana_scelta = [
("LUNEDI","Lunedì"),
("MARTEDI","Martedì"),
("MERCOLEDI","Mercoledì"),
("GIOVEDI","Giovedì"),
("VENERDI","Venerdì"),
("SABATO","Sabato"),
("DOMENICA","Domenica")
]
giorni_settimana = MultiSelectField(choices = giorni_settimana_scelta,default = '-')
dati_gruppo = models.ForeignKey(
Gruppi,on_delete = models.CASCADE, related_name = 'dati_gruppo')
gruppi_scheda = models.ForeignKey(Schede,on_delete = models.CASCADE, related_name = 'gruppi_scheda')
class Schede(models.Model):
nome_scheda = models.CharField(max_length=100)
data_inizio = models.DateField()
data_fine = models.DateField()
utente = models.ForeignKey(User, on_delete = models.CASCADE,related_name = 'utente')
You can override a form field before instantiate it like this :
views.py
from django import forms
if request.method == "POST":
# Post logic here
else:
# We try to retrieve group that the current user is not yet in.
# Not your logic, but to sum up, you have to retrieve the groups
# which had not yet been added.
# Use a filter that permit you to retrieve only groups which had not yet been added.
group_to_add = Group.objects.filter(...)
GruppiForm.base_fields['group_field'] = forms.ModelChoiceField(
queryset=group_to_add)
# Instantiate the form now
# In this form, the choices are only those contained in the group_to_add queryset
form = GruppiForm(prefix = 'gruppo')

Django multiplechoicefield always renders None

I made a multiplechoicefield form (to ask what category user wants to select), but i can't get the answer back...it always renders "None".
I added some 'print' in the code to be sure that it was the problem and it is.
I don't understand why.
forms.py:
class Category(forms.ModelForm):
class Meta:
model = Auctions
fields = ("category",)
#fields = ('category',)
#widgets = {'category' : forms.RadioSelect()}
catform = forms.MultipleChoiceField(choices=fields, widget=forms.CheckboxSelectMultiple())
models.py
'''
class Auctions(models.Model):
Category = [('FASHION', 'Fashion'),('TOYS','Toys'),('ELECTRONICS','Electronics'),('HOME','Home')]
ID_auction = models.AutoField(primary_key = True)
title = models.CharField(max_length = 80)
description = models.TextField()
startingbid = models.IntegerField()
image = models.URLField(blank = True)
category = models.CharField(max_length = 80, choices = Category)
author_id = models.ForeignKey(User,on_delete = models.CASCADE, related_name = "auteur")
highest_bid = models.IntegerField("Bid", blank = True, null = True)
buyer = models.ForeignKey(User, on_delete = models.CASCADE, related_name = "acheteur")
active = models.BooleanField(default=True)
'''
views.py
'''
def filter_cat(request):
if request.method == "POST":
form = Category(request.POST)
print(form)
if form.is_valid():
cat = form.cleaned_data.get("catform")
print(cat)
auctions = Auctions.objects.filter(category = cat)
return render(request, "auctions/index.html",{
'active_listing' : auctions, 'cat' : cat
})
else :
form = Category()
return render(request, "auctions/filter_cat.html",{'form' : form})
'''
when I select FASHION for example i get this on the terminal :
for print(form):
Category:
---------
Fashion
Toys
Electronics
Home
for print(cat):
None

Django UpdateView and ChoiceField issue. Django 1.11 python 3.6

I am facing a strange problem while implementing ChoiceField and UpdateView in django. I have made a small clip showing the problem that I am facing. Please watch it with subtitles/cc enabled. It will give an idea about the problem I am facing. https://youtu.be/M36TnlJvrZs. The problem goes like this.....
During CreateView, I set the 'gender' ChoiceField as 'Female'. But in UpdateView it pre-populates the 'gender' ChoiceField as Male.
However, The ListView renders the 'gender' field properly as 'Female'.
And strangely, the django admin panel, displays no value at all for the 'gender' field.
Here are all the codes:
models.py:
from django.db import models
from django.core.urlresolvers import reverse
gender_choices = (('Male', 'Male'), ('Female', 'Female'))
class Birth(models.Model):
full_name = models.CharField(max_length = 100)
gender = models.CharField(max_length=6, choices=gender_choices)
date_of_birth = models.DateField()
place_of_birth = models.CharField(max_length = 50)
mother_name = models.CharField(max_length = 50)
father_name = models.CharField(max_length = 50)
address_at_time_of_birth = models.TextField(max_length = 500)
permanent_address = models.TextField(max_length = 500)
registration_no = models.CharField(max_length = 50)
remarks = models.CharField(max_length = 200)
registration_date = models.DateField()
issue_date = models.DateField()
def get_absolute_url(self):
return reverse('birth:birth_update', kwargs={'pk':self.pk})
#return reverse('birth:birth_home')
def __str__(self):
return self.full_name
forms.py:
from django import forms
from .models import *
class BirthForm(forms.ModelForm):
full_name = forms.CharField()
gender = forms.ChoiceField(choices = gender_choices, widget=forms.Select())
date_of_birth = forms.DateField(widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
place_of_birth = forms.CharField()
mother_name = forms.CharField()
father_name = forms.CharField()
address_at_time_of_birth = forms.CharField(widget = forms.Textarea())
permanent_address = forms.CharField(widget = forms.Textarea())
registration_no = forms.CharField(required = False)
registration_date = forms.DateField(required = False, widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
remarks = forms.CharField(required = False)
issue_date = forms.DateField(required = False, widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
class Meta:
model = Birth
fields = '__all__'
views.py:
from django.views.generic import ListView, CreateView, UpdateView
from .models import *
from .forms import *
from datetime import date
class BirthHome(ListView):
template_name = 'birth/birth_home.html'
model = Birth
context_object_name = 'birth_objects'
paginate_by = 20
def get_queryset(self):
return Birth.objects.all().order_by('-id')
class NewBirth(CreateView):
model = Birth
form_class = BirthForm
#fields = '__all__'
template_name = 'birth/birth_add.html'
def form_valid(self, form):
obj = form.save(commit = False)
if not obj.registration_date:
obj.registration_date = date.today()
if not obj.issue_date:
obj.issue_date = date.today()
if not (date(1900, 1, 1) <= obj.date_of_birth <= date.today()):
form.add_error('date_of_birth', 'Please enter a valid date')
return super(NewBirth, self).form_invalid(form)
obj.full_name = obj.full_name.upper()
obj.gender = obj.gender.upper()
obj.place_of_birth = obj.place_of_birth.upper()
obj.mother_name = obj.mother_name.upper()
obj.father_name = obj.father_name.upper()
obj.address_at_time_of_birth = obj.address_at_time_of_birth.upper()
obj.permanent_address = obj.permanent_address.upper()
if obj.remarks:
obj.remarks = obj.remarks.upper()
self.object = form.save()
return super(NewBirth, self).form_valid(form)
class BirthUpdate(UpdateView):
model = Birth
form_class = BirthForm
template_name = 'birth/birth_update.html'
def form_valid(self, form):
obj = form.save(commit = False)
if not obj.registration_date:
obj.registration_date = date.today()
if not obj.issue_date:
obj.issue_date = date.today()
if not (date(1900, 1, 1) <= obj.date_of_birth <= date.today()):
form.add_error('date_of_birth', 'Please enter a valid date')
return super(BirthUpdate, self).form_invalid(form)
obj.full_name = obj.full_name.upper()
obj.gender = obj.gender.upper()
obj.place_of_birth = obj.place_of_birth.upper()
obj.mother_name = obj.mother_name.upper()
obj.father_name = obj.father_name.upper()
obj.address_at_time_of_birth = obj.address_at_time_of_birth.upper()
obj.permanent_address = obj.permanent_address.upper()
if obj.remarks:
obj.remarks = obj.remarks.upper()
self.object = form.save()
return super(BirthUpdate, self).form_valid(form)
I searched a lot and experimented a lot as well, but to no avail. Seriously need help. Also if this approach is not correct, what should be the correct working approach??
Solved!
So after lots of experimenting, I realized what the problem was!! It was in models.py file:
Since, I was converting all my inputs to uppercase, the 'choices' tuple also needed to have the values in uppercase. Initially the gender_choices tuple read like this:
gender_choices = (('Male', 'Male'), ('Female', 'Female'))
And in my views, I was making the gender as uppercase, thus causing mis-match in the declared tuple data and form data.
So, I changed the tuple to this:
gender_choices = (('MALE', 'MALE'), ('FEMALE', 'FEMALE'))
Works like a Charm!! Cheers.... And thanx for all the help and suggestions. Any feedback is always welcome :)

Save another model's object in CreateView

I have 3 model:
class City(models.Model):
name = models.CharField()
class State(models.Model):
name = models.CharField()
class Role(models.Model):
CITY = 1
State = 2
NOACCESS = 0
VIEW = 1
UPDATE = 2
DELETE = 3
TYPE_CHOICES = (
(CITY, 'City'),
(STATE, 'State'),
)
ROLE_CHOICES = (
(NOACCESS, 'No access'),
(VIEW, 'View'),
(UPDATE, 'Update'),
(DELETE, 'Delete'),
)
obj_type = models.IntegerField(choices=TYPE_CHOICES)
obj_id = models.IntegerField(verbose_name="Object ID")
obj_role = models.IntegerField(choices=ROLE_CHOICES, default=NOACCESS)
obj_user = models.IntegerField()
I would like to save a role for each user in views.py:
class FormCreateView(CreateView):
form_class = City
def form_valid(self, form):
users = self.request.POST.getlist('access-users')
f.save()
for i in users:
role = RoleCreateView() # save a role for each user
role.type = 'city'
role.user = i
role.city = f.id
role.save()
return super(FormCreateView, self).form_valid(form)
How I can do this?

django-select2 not working with inlines in django-admin

Here are my models and admin classes:
---------------------Models-----------------------
from django.contrib.auth.models import User
class PurchaseOrder(models.Model):
buyer = models.ForeignKey(User)
is_debit = models.BooleanField(default = False)
delivery_address = models.ForeignKey('useraccounts.Address')
organisation = models.ForeignKey('useraccounts.AdminOrganisations')
date_time = models.DateTimeField(auto_now_add=True)
total_discount = models.IntegerField()
tds = models.IntegerField()
mode_of_payment = models.ForeignKey(ModeOfPayment)
is_active = models.BooleanField(default = True)
class Meta:
verbose_name_plural = "Purchase Orders"
def __unicode__(self):
return '%s' % (self.id)
----------------------------------Admin----------------------------------------
"""
This class is used to add, edit or delete the details of item purchased
"""
class PurchasedItemInline(admin.StackedInline):
form = ItemSelectForm
model = PurchasedItem
fields = ['parent_category', 'sub_category', 'item', 'qty', ]
extra = 10
class BuyerChoices(AutoModelSelect2Field):
queryset = User.objects.all()
search_fields = ['username__icontains', ]
class BuyerForm(ModelForm):
user_verbose_name = 'Buyer'
buyer = BuyerChoices(
label='Buyer',
widget=AutoHeavySelect2Widget(
select2_options={
'width': '220px',
'placeholder': 'Lookup %s ...' % user_verbose_name
}
)
)
class Meta:
model = PurchaseOrder
fields = '__all__'
"""
This class is used to add, edit or delete the details of items
purchased but buyer has not confirmed the items purchased, this class
inherits the fields of PurchaseOrder derscribing the delivery address of
buyer , is_debit , total discount , tds and mode of payment
"""
class PurchaseOrderAdmin(admin.ModelAdmin):
form = BuyerForm
#list_display = ['id','buyer','delivery_address','date_time','is_active']
inlines = [PurchasedItemInline]
# model = PurchaseOrder
#actions = [mark_active, mark_inactive]
#list_filter = ['date_time']
#search_fields = ['id']
list_per_page = 20
def response_add(self, request, obj, post_url_continue=None):
request.session['old_post'] = request.POST
request.session['purchase_order_id'] = obj.id
return HttpResponseRedirect('/suspense/add_distance/')
I am trying to implement django-select2, but when I use inlines in
PurchaseOrderAdmin it doesn't show the field where I have implemented
django-select2:
But when I remove inlines, it works fine:
Edit
Here is the ItemSelectForm
class ItemSelectForm(forms.ModelForm):
class Media:
js = (
'http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
'js/ajax.js',
)
try:
parent_category = forms.ModelChoiceField(queryset=Category.objects.\
filter(parent__parent__isnull=True).filter(parent__isnull=False))
sub_category_id = Category.objects.values_list('id',flat=True)
sub_category_name = Category.objects.values_list('name',flat=True)
sub_category_choices = [('', '--------')] + [(id, name) for id, name in
itertools.izip(sub_category_id, sub_category_name)]
sub_category = forms.ChoiceField(sub_category_choices)
except:
pass
item = forms.ModelChoiceField(queryset = Product.objects.all())
def __init__(self, *args, **kwargs):
super(ItemSelectForm, self).__init__(*args, **kwargs)
self.fields['parent_category'].widget.attrs={'class': 'parent_category'}
self.fields['sub_category'].widget.attrs={'class': 'sub_category'}
self.fields['item'].widget.attrs={'class': 'item'}
It worked for me by adding the following line in the static/suit/js/suit.js
Add:
(function ($) {
Suit.after_inline.register('init_select2', function(inline_prefix, row){
$(row).find('select').select2();
});