Formset.is_valid() False, why? - python

I'm trying to validate a form set, it shows in the template perfectly but when I try to save it, its validation returns False.
I tried to put some errors callbacks and the error in print(formset.non_form_errors) say the following:
<bound method PhysicianSpecialtiesFormFormSet.non_form_errors of <django.forms.formsets.PhysicianSpecialtiesFormFormSet object at 0x7fd70af38a10>>
I don't know what to do to have a correct input in the form; the form is a dropdown list, and it's impossible to get wrong.
def UpdatePhysician(request,id):
physician = get_object_or_404(Physician, id=id)
employee = get_object_or_404(Employee, id=physician.employee.id)
person = get_object_or_404(Person, id=employee.person.id)
try:
address = get_object_or_404(Address, id=return_id(str(person.addresses.values('id'))))
except:
address = None
try:
email = get_object_or_404(Email, id=return_id(str(person.emails.values('id'))))
except:
email = None
try:
phone = get_object_or_404(PhoneNumber, id=return_id(str(person.phone_numbers.values('id'))))
except:
phone = None
try:
academic_degree = get_object_or_404(AcademicDegree, id=return_id(str(employee.academic_degrees.values('id'))))
university = get_object_or_404(University, id=return_id(str(employee.academic_degrees.values('university'))))
except:
academic_degree = None
university = None
physician_specialties = get_list_or_404(PhysicianSpecialties, employee_academic_degree__employee__pk=physician.employee.id)
for item in physician_specialties:
print(unicode(item.specialty))
specialties = Specialty.objects.all()
specialty = PhysicianSpecialties.objects.filter(employee_academic_degree__employee__physician__pk=id)
SpecialtyFormset = modelformset_factory(PhysicianSpecialties, fields=('specialty',),max_num=1, labels=None, )
formset = SpecialtyFormset(queryset=PhysicianSpecialties.objects.filter(employee_academic_degree__employee__pk=physician.employee.id))
person_form = PersonForm(request.POST or None, instance=person)
employee_form = EmployeeForm(request.POST or None, instance=employee)
physician_form = PhysicianForm(request.POST or None, instance=physician)
email_form = EmailForm(request.POST or None, instance=email)
address_form = AddressForm(request.POST or None, instance=address)
phone_form = PhoneForm(request.POST or None, instance=phone)
academic_degree_form = AcademicDegreeForm(request.POST or None, instance= academic_degree)
university_form = UniversityForm(request.POST or None, instance=university)
if request.method == "POST":
if (person_form.is_valid() and employee_form.is_valid() and physician_form.is_valid() and email_form.is_valid() and
address_form.is_valid() and phone_form.is_valid and physician_form.is_valid() and university_form.is_valid and
academic_degree_form.is_valid() and formset.is_valid()):
person_form.save()
physician_form.save()
new_address = address_form.save()
new_email = email_form.save()
new_phone = phone_form.save()
# academic_degree_form.save()
# university_form.save()
formset.save()
if address == None:
PersonAddress.objects.create(person=person, address=new_address)
if email == None:
PersonEmail.object.create(person=person, email=new_email)
if phone == None:
PersonPhoneNumber.objects.create(person=person, hone_number=new_phone)
return HttpResponse('yesh')
else:
print(formset.is_valid())
print(formset.non_form_errors)
print('nope')
return HttpResponse('nope')

You haven't passed data to your formset. Without post data, your formset is unbound and will always be invalid.
formset = SpecialtyFormset(request.POST or None, queryset=PhysicianSpecialties.objects.filter(employee_academic_degree__employee__pk=physician.employee.id))
Another problem is that you are trying to display the errors incorrectly. formset.non_form_errors is a method, you have to call it.
print(formset.non_form_errors())
There may also be errors attached to the forms in the formset, you can see these by printing formset.errors.
print(formset.errors)

Related

Django same function data not showing after page render

I am creating university management system using django. I have created faculty(teacher) registration form. For that, in my views.py
def faculty_registration(request):
data = {}
form = FacultyRegisterForm()
activetab = 'list'
if request.method == 'POST':
activetab = 'add'
form = FacultyRegisterForm(request.POST)
if form.is_valid():
userdata = User()
if User.objects.filter(username=request.POST.get('email')).exists():
messages.error(request, f"This email already exists.")
return redirect('/faculty/faculty_registration')
else:
userdatafirst_name = request.POST.get("first_name")
userdata.username = request.POST.get('email')
userdata.email = request.POST.get('email')
try:
fac_ID = Faculty.objects.last().id
except:
fac_ID = 0
LastInsertId = fac_ID+1
print('after_id',LastInsertId)
password = User.objects.make_random_password()
faculty_pw = password+str(LastInsertId)
print("pass",faculty_pw)
userdata.password = make_password(faculty_pw)
print( "teacher_pasword",userdata.password)
userdata.save()
fac = Faculty()
fac.faculty_college_id = request.POST.get("faculty_college")
fac.faculty_programme_id = request.POST.get('faculty_programme')
fac.salutation = request.POST.get("salutation")
fac.first_name = request.POST.get("first_name")
fac.middle_name = request.POST.get("middle_name")
fac.last_name = request.POST.get("last_name")
fac.phone = request.POST.get("phone")
fac.email = request.POST.get("email")
fac.address = request.POST.get('address')
fac.department = request.POST.get('department')
fac.highest_qualification = request.POST.get("highest_qualification")
fac.years_of_experience = request.POST.get('years_of_experience')
fac.previous_institute = request.POST.get('previous_institute')
# fac.documents = request.POST.get("documents")
if 'documents' in request.FILES:
filename = request.FILES['documents']
if str(filename).lower().split('.')[-1] == 'pdf':
if int(len(request.FILES['documents'].read())) < (3 * 1024 * 1024):
fac.documents = request.FILES['documents']
else:
messages.warning(request, "please upload a pdf within 3 mb")
navshow = 'add'
return redirect('faculty_registration')
else:
messages.warning(request, "please upload a pdf")
navshow = 'add'
return redirect('faculty_registration')
fac.photo = request.FILES.get('photo', 'faculty_picture/def.png')
fac.created_by_id = request.user.id
fac.user_id = userdata.id
fac.save()
assign_role(userdata, 'teacher')
html_content = render_to_string("email_template.html",{'title':'Kindly Note your Mailid and Password For Login.','to_mail':fac.email,'to_password':faculty_pw})
text_content = strip_tags(html_content)
msg = EmailMessage(
'Welcome to University', #subject
text_content, #content
settings.EMAIL_HOST_USER, #from email
[fac.email], #reclist
)
msg.content_subtype = "html" # Main content is now text/html
msg.send()
# print("send_email",send_email)
messages.success(request, f"Lecturer has been added successfully")
return redirect('/faculty/faculty_registration')
else:
print("\ninvalid form\n")
else:
form = FacultyRegisterForm()
# fac_data = Faculty.objects.order_by('-id')
fac_data = Faculty.objects.order_by(Lower('first_name'))
data['form'] = form
data['faculties'] = fac_data
data['activetab'] = activetab
return render(request, 'faculty_register.html', data)
Also I have added searchbar button to search faculty name.
So I created following function:
def searchbar (request):
data = {}
find = request.GET['find']
res = Faculty.objects.filter(Q(first_name__icontains=find) | Q(middle_name__icontains=find)| Q(last_name__icontains=find))
activetab = 'list'
form = FacultyRegisterForm()
data['form'] = form
data['activetab'] = activetab
data['faculties'] = res
return render(request,"faculty_register.html",data)
I have also added 'add' functionality to add faculty.
Now my problem is when I click search button, I am not able to add faculty because I think i am rendering the same page 'faculty_register.html' in both return function. So how can I get same page data even after clicking 'search button'.
URLs:
urlpatterns = [
path('faculty_registration', views.faculty_registration, name='faculty_registration'),
path('faculty/searchbar', views.searchbar, name= 'searchbarf')]
I've tried to add searchbar function in faculty_registration but not able to solve this.

i am making a django website with multiple forms also used foregin key ValueEror :The view Capp.views.InsertProduct didn't return anHttpResponseobject

i am making a django website with multiple forms also used foregin key(user_id) to link one form with other in the database but at the last i get value error the error is:Exception Type: ValueError
Exception Value:
The view Capp.views.InsertProduct didn't return an HttpResponse object. It returned None insteated ,
the following is view.py file code(not complete code but only where error can lie)models.py part
def InsertProduct(request):
if request.method == 'POST':
if request.POST.get('user_id') and request.POST.get('pname') and request.POST.get('pcategory') and request.POST.get('pdetails') and request.POST.get('foundedin') and request.POST.get('orderoftest') and request.POST.get('t1') and request.POST.get('t2') and request.POST.get('t3') and request.POST.get('f1') and request.POST.get('f2') and request.POST.get('f3') and request.POST.get('f4') and request.POST.get('f5'):
saveproduct = ProInsert()
saveproduct.user_id = request.POST.get('user_id')
saveproduct.pname = request.POST.get('pname')
saveproduct.pcategory = request.POST.get('pcategory')
saveproduct.pdetails = request.POST.get('pdetails')
saveproduct.foundedin = request.POST.get('foundedin')
saveproduct.orderoftest = request.POST.get('orderoftest')
saveproduct.t1 = request.POST.get('t1')
saveproduct.t2 = request.POST.get('t2')
saveproduct.t3 = request.POST.get('t3')
saveproduct.f1 = request.POST.get('f1')
saveproduct.f2 = request.POST.get('f2')
saveproduct.f3 = request.POST.get('f3')
saveproduct.f4 = request.POST.get('f4')
saveproduct.f5 = request.POST.get('f5')
checkpname = ProInsert.objects.filter(
pname=saveproduct.pname).first()
return render(request, 'product_details.html')#here I had add what u said sir
if checkpname:
msgpname = messages.success(request, 'The user with Product Name ' +
request.POST['pname']+' already exist...!')
return render(request, 'product_details.html', {'msgpname': msgpname})
saveproduct.save()
messages.success(request, 'Product Added..!')
return render(request, 'product_details.html')
else:
return render(request, 'product_details.html')
I think you got it wrong I have update your code and commented the part i was telling you.
def InsertProduct(request):
if request.method == 'POST':
if request.POST.get('user_id') and request.POST.get('pname') and request.POST.get('pcategory') and request.POST.get('pdetails') and request.POST.get('foundedin') and request.POST.get('orderoftest') and request.POST.get('t1') and request.POST.get('t2') and request.POST.get('t3') and request.POST.get('f1') and request.POST.get('f2') and request.POST.get('f3') and request.POST.get('f4') and request.POST.get('f5'):
saveproduct = ProInsert()
saveproduct.user_id = request.POST.get('user_id')
saveproduct.pname = request.POST.get('pname')
saveproduct.pcategory = request.POST.get('pcategory')
saveproduct.pdetails = request.POST.get('pdetails')
saveproduct.foundedin = request.POST.get('foundedin')
saveproduct.orderoftest = request.POST.get('orderoftest')
saveproduct.t1 = request.POST.get('t1')
saveproduct.t2 = request.POST.get('t2')
saveproduct.t3 = request.POST.get('t3')
saveproduct.f1 = request.POST.get('f1')
saveproduct.f2 = request.POST.get('f2')
saveproduct.f3 = request.POST.get('f3')
saveproduct.f4 = request.POST.get('f4')
saveproduct.f5 = request.POST.get('f5')
checkpname = ProInsert.objects.filter(
pname=saveproduct.pname).first()
# return render(request, 'product_details.html')# NO need to add here as code below will be dead in this case.
if checkpname:
msgpname = messages.success(request, 'The user with Product Name ' +
request.POST['pname']+' already exist...!')
return render(request, 'product_details.html', {'msgpname': msgpname})
saveproduct.save()
messages.success(request, 'Product Added..!')
return render(request, 'product_details.html')
else:
return render(request, 'product_details.html')# What i meant was to add it here
else:
return render(request, 'product_details.html')

Unable to get logged in username in django

I am trying to get User as foreignkey in a model but getting error.
When I try:
qr.claimed = True
user = get_object_or_404(User,id=request.user.id)
qr.branch = user
qr.save();
OUTPUT:
AttributeError: 'str' object has no attribute 'user'
When I try to POST:
qr.claimed = True
get_user = request.POST.get('branch')
user = User.objects.get(id=get_user)
qr.branch = user
qr.save();
OUTPUT:
AttributeError: 'str' object has no attribute 'POST'
When I define user in another python file and try to fetch from there:
qr.claimed = True
get_user = pythonfile.user
user = User.objects.get(id=get_user)
qr.branch = user
qr.save();
OUTPUT:
TypeError: Field 'id' expected a number but got <function user at 0x0E777E38>.
request.user -> AttributeError: 'str' object has no attribute 'user'
request.POST -> AttributeError: 'str' object has no attribute 'POST'
Any error with request or missing any package to install/import?
UPDATE:
#csrf_exempt
def decodeAjax(request):
if request.POST:
decodedData = barCode.decode(request.POST['imgBase64'])
if decodedData:
json_data = json.dumps(decodedData)
print(json_data)
return JsonResponse(json_data,safe=False)
return JsonResponse({"code" : 'NO BarCode Found'})
def decode(request):
# Find barcodes and QR codes
imgstr = re.search(r'base64,(.*)', request).group(1) #url
image_bytes = io.BytesIO(base64.b64decode(imgstr))
im = Image.open(image_bytes)
arr = np.array(im)[:, :, 0]
decodedObjects = pyzbar.decode(arr)
#print(decodedObjects)
# return decodedObjects.Decoded
# Print results
data = []
for obj in decodedObjects:
qrs = Scanner.objects.all()
for qr in qrs:
if obj.data.decode('utf-8') in qr.ID:
dt = 'Successfully Claimed!'
btn = 'Claim Another'
img = 'tick.gif'
if qr.claimed == True:
dt = 'Already Claimed at %s'%(localtime(qr.scanned_at))
img = 'cross.png'
else:
qr.claimed = True
qr.save();
break
else:
dt = 'Invalid QR Code'
btn = 'Try Another'
img = 'cross.png'
data.append({
"code":obj.data.decode('utf-8') ,
#"type": obj.type,
"dt": dt,
"btn":btn,
"img":img
})
return data
You check the method with:
#csrf_exempt
def decodeAjax(request):
if request.method == 'POST':
decodedData = barCode.decode(request.POST['imgBase64'])
# …
The item you pass to decode is not a HttpRequest object, but the image in base64 encoding. You thus might want to rename this to:
def decode(base64img):
imgstr = re.search(r'base64,(.*)', base64img).group(1)
# …
If you need the request somewhere, you will need to pass request, not request.POST['imgBase64'].
furthermore I would really advise not to make methods with a CSRF exeption. You can send the CSRF token as specified in the AJAX section of the documentation.

Flask WTForms dynamic select field validation value is empty on POST

I am having trouble validating a dynamically generated WTForms SelectField. Somehow my self.choices is empty during POST while they are populated on the first GET request. Am I missing something?
app.py:
#app.route('/users/edit/<email>/', methods=['GET', 'POST'])
def users_edit(email):
match = False
for user in session['users']['message']:
if user['email']['S'] == email:
match = True
if match:
form = EditUserForm()
if request.method == 'GET':
form_data = session.get('edit_user_form_data', None)
if form_data:
form = EditUserForm(MultiDict(form_data))
form.shops_allowed.choices = [(str(shop['shop_id']['S']), str(shop['general']['M']['shop_name']['S'])) for i, shop in enumerate(session['shops']['message'])]
print(f"SHOPS_ALLOWED CHOICES WITH FORM DATA: {form.shops_allowed.choices}")
form.validate()
session.pop('edit_user_form_data', None)
else:
form.email.data = email
form.shops_allowed.choices = [(str(shop['shop_id']['S']), str(shop['general']['M']['shop_name']['S'])) for i, shop in enumerate(session['shops']['message'])]
print(f"SHOPS_ALLOWED CHOICES WITHOUT FORM DATA: {form.shops_allowed.choices}")
matched_shop = []
for user in session['users']['message']:
if user['email']['S'] == email and 'shops_allowed' in user.keys():
matched_shop = [allow['S'] for allow, shop in zip(user['shops_allowed']['L'], session['shops']['message'])]
form.shops_allowed.data = matched_shop
form.validate()
if request.method == 'POST' and form.validate_on_submit():
app.logger.info(f"PRE POST EDIT USER FORM DATA: {form.data}")
url = ...
<REDACTED POST REQUESTS ENDPOINT>
app.logger.info(f"POST EDIT USER RESPONSE: ({post_response.status_code}) {response_data}")
if post_response.status_code == 200:
session.pop('edit_user_form_data', None)
return redirect(url_for('users'))
else:
app.logger.info(f"EDIT USER FORM DATA: {form.data}")
session['edit_user_form_data'] = form.data
return redirect(url_for('users_edit', email=email))
elif request.method == 'POST' and form.validate_on_submit() == False:
app.logger.info(f"EDIT USER FORM DATA VALIDATION FAILED: {form.data}")
session['edit_user_form_data'] = form.data
return redirect(url_for('users_edit', email=email))
forms.py
class NonValidatingSelectMultipleField(SelectMultipleField):
def __len__(self):
return 1
def pre_validate(self, form):
pass
# HACK TO VALID A CHOICE FOR SELECT MULTIPLE
if self.data:
print(f"SELF DATA: {self.data}")
print(f"VALUES: {self.choices}")
values = list(self.coerce(c[0]) for c in self.choices)
print(f"PROCESSED VALUES: {values}")
for d in self.data:
if d not in values:
raise ValueError(self.gettext("'%(value)s' is not a valid choice for this multiple select field") % dict(value=d))
class EditUserForm(FlaskForm):
email = StringField('Email', [
validators.DataRequired(),
validators.Length(min=6),
validators.Email(message='Not a valid email address.')]
)
shops_allowed = NonValidatingSelectMultipleField(
'Shops',
widget = widgets.ListWidget(prefix_label=False),
option_widget = widgets.CheckboxInput(),
coerce=str
)
This renders the following logging:
SHOPS_ALLOWED CHOICES WITHOUT FORM DATA: [('decb5a00-fe45-484f-b887-b9bd41c4f0f2', 'My shop'), ('2cea2efa-7ccf-4bca-896d-16119d5fb7a8', 'My other shop')]
SELF DATA: ['decb5a00-fe45-484f-b887-b9bd41c4f0f2', '2cea2efa-7ccf-4bca-896d-16119d5fb7a8']
VALUES: [('decb5a00-fe45-484f-b887-b9bd41c4f0f2', 'My shop'), ('2cea2efa-7ccf-4bca-896d-16119d5fb7a8', 'My other shop')]
PROCESSED VALUES: ['decb5a00-fe45-484f-b887-b9bd41c4f0f2', '2cea2efa-7ccf-4bca-896d-16119d5fb7a8']
127.0.0.1 - - [03/Apr/2020 14:30:11] "GET /users/edit/my#email.com/ HTTP/1.1" 200 -
After POST:
SELF DATA: ['decb5a00-fe45-484f-b887-b9bd41c4f0f2', '2cea2efa-7ccf-4bca-896d-16119d5fb7a8']
VALUES: None
And on screen:
forms.py", line 35, in pre_validate values = list(self.coerce(c[0]) for c in self.choices) TypeError: 'NoneType' object is not iterable
Meh, after going over my code once more I finally found the issue. I am calling form.validate_on_submit() at the same time I am verifying if request.method == 'POST' which never gives me the possibility to populated the choices during POST.
Changed my code to be:
if request.method == 'POST':
form.shops_allowed.choices = [(str(shop['shop_id']['S']), str(shop['general']['M']['shop_name']['S'])) for i, shop in enumerate(session['shops']['message'])]
form.validate_on_submit()
And it started to work. Sometimes you just need to write things down to see the answer :-)

The view Expéditions.views.changelisteexpédition didn't return an HttpResponse object. It returned None instead

I'm new in django developpemnt , in my view i have some elif conditions that mastring some functions, in execution on the last condition i have this issue :
The view Expéditions.views.changelisteexpédition didn't return an HttpResponse object. It returned None instead.
def changelisteexpédition(request,id=id):
if "Editer" in request.POST:
.......
elif "Bloquer" in request.POST :
.......
elif "Supprimer" in request.POST:
.......
elif "Annuler" in request.POST:
.......
elif "Débloquer" in request.POST :
.......
elif "Top Départ" in request.POST :
trsp = transporteur.objects.all().order_by('id')
obj = get_object_or_404(Expédition,id=request.POST.get("choix"))
form = TopdépartForm(request.POST)
if form.is_valid():
Topdépart.objects.create(
Expédition = obj,
transporteur = request.POST.get("transporteur"),
chauffeur = request.POST.get("chauffeur"),
bl = request.POST.get("bl"),
plomb = request.POST.get("plomb"),
commentaire = request.POST.get("commentaire"),
date = request.POST.get("date"),
immatriculation = request.POST.get("immatriculation")
)
obj.statut = "Expédié"
obj.transporteur = request.POST.get("transporteur")
obj.chauffeur = request.POST.get("chauffeur")
obj.immatriculation = request.POST.get("immatriculation")
obj.save()
a = Commande.objects.get(numcommande=obj.numcommande)
a.quantitélivrée = obj.quantitélivrée
a.statut = "Expédié"
a.save()
j = Ligneexpédition.objects.filter(numcommande=obj.numcommande)
for i in j :
c = Articles.objects.get(sku=i.sku)
c.stockexpedié = c.stockexpedié + i.quantitélivrée
c.save()
return HttpResponseRedirect("asnintransit")
else :
form = TopdépartForm()
context = {
'form':form,`enter code here`
'obj':obj,
'trsp':trsp
}
return render(request,'topdépart.html',context)
I need some help.
Thanks.
In this part:
else:
form = TopdépartForm()
You are not returning a render() method, so basically I'm telling you to indent the last portion of your code like this:
else :
form = TopdépartForm()
context = {
'form':form,`enter code here`
'obj':obj,
'trsp':trsp
}
return render(request,'topdépart.html',context)
I'm 90% confident it will make your code work, if not, reach again I'll try to replicate

Categories