Loop over tbody in Django views - django

I am trying to loop over a tbody in my django views to get the data from the form but when i print the items in the tbody it only shows the last one
Here's the part I am trying to loop on
<tbody class="player-instances">
<tr>
<td><input type="text" name="form-0-pname" id="id_form-0-pname"></td>
<td><input type="number" name="form-0-hscore" id="id_form-0-hscore"></td>
<td><input type="number" name="form-0-age" id="id_form-0-age"></td>
</tr>
<tr>
<td><input type="text" name="form-0-pname" id="id_form-1-pname"></td>
<td><input type="number" name="form-0-hscore" id="id_form-1-hscore"></td>
<td><input type="number" name="form-0-age" id="id_form-1-age"></td>
</tr>
</tbody>
Views.py
if form.player_instances.cleaned_data is not None:
for item in form.player_instances.cleaned_data:
print("item", item)
print("form.cleaned_data", form.cleaned_data)
player = Player()
player.pname= item['pname']
player.hscore= item['hscore']
player.age= item['age']
player.save()
team.player.add(player)
team.save()
The output in terminal is the following:
item {'pname': 'tt22', 'hscore': 8, 'age': 89}
form.cleaned_data {'tname': 'tt1'}
Why is it overriding the first input fields despite having different id?

Try different name in name field like : form-1-pname and so on.
Thanks.

Related

How do I use checkboxes to pass value to views django?

I am trying to use checkboxes to get the selected options from the user and pass it onto the views to create a new instance using the value, however, I am finding it difficult to get the input value as it keeps showing None the I try getting the value using the input name within the tag.
template
<form action='/print_from_button' method='GET'>
<table id="id_list_table" class="table table-condensed">
<thead>
<tr>
<th id="input">Input</th>
</tr>
</thead>
<tbody id="fbody">
{%for m in matches%}
<tr>
<td><br>{{ m.match }}</br> ({{m.datespent}})</td>
<td>
<input type="checkbox" name="inputs" class="checkvalue" value={{m.match}} />
</td>
</tr>
{%endfor%}
</tbody>
</table>
<input type="text" name="checkval" id="checkallvalues" size="50">
<button type='submit'> Confirm </button>
</form>
urls.py
from django.urls import path
from . import views
from .views import matchpaymentsoverview
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('matchpayment/overview/',views.matchpaymentsoverview, name="matchpaymentsoverview"),
path('print_from_button', views.print_from_button)
]
views.py
def print_from_button(request):
print("button clicked")
if request.POST.get('checkval'):
vi = request.POST.get('checkval')
print(vi)
vi1 = request.GET.get('checkval')
print(vi1)
list_of_input_ids=request.POST.getlist('inputs')
print(list_of_input_ids)
return HttpResponse("""<html><script>window.location.replace('/');</script></html>""")
I keep getting none when I print the above name tags, would I need the button to trigger the function, or I can just create a function and use the get to get the values. Hope it makes sense.
Thanks
You could you HTML Checkboxes like this:
<p>Choose your monster's features:</p>
<div>
<input type="checkbox" id="scales" name="scales"
checked>
<label for="scales">Scales</label>
</div>
<div>
<input type="checkbox" id="horns" name="horns">
<label for="horns">Horns</label>
</div>
Basically this is just a input field with the type checkbox. You also could use Django input fields:
https://docs.djangoproject.com/en/3.2/ref/forms/
This is the source of my code:
https://developer.mozilla.org/de/docs/Web/HTML/Element/input/checkbox
Mozialla is a good choice in general if you have any questions about html, javascript or css

Selenium Python I am trying to iterate rows in a html table I get error Index out of range

I have a webpage with a HTML table with some columns and rows. The user can select a row from the table and click the delete button. This will delete the row from the html table. E.g. In the Name column (index 1) there is a value "Testa"
The user can select the checkbox for the row where Name is "Testa" and delete it.
I would like to iterate over the rows and check "Testa" is not there. This way I can be sure the delete worked.
My code is not iterating over the table.
My code snippet is:
def is_value_deleted_from_user_defined_field(self, name): # return true if the user defined name is null. This method is to verify the user defined field has been deleted
# Params name : The name of the user defined field e.g. AREACODE, Testa
try:
WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.ID, 'data_configuration_edit_data_object_tab_details_tb_fields')))
table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((By.ID, 'data_configuration_edit_data_object_tab_details_tb_fields')))
rows = table_id.find_elements(By.TAG_NAME, "tr")
for row in rows:
# Get the columns
col_name = row.find_elements(By.TAG_NAME, "td")[1] # This is the Name column
print "col_name.text = "
if (col_name.text != name):
return True
return False
except NoSuchElementException, e:
print "Element not found "
print e
self.save_screenshot("is_value_deleted_from_user_defined_field")
return False
My code to call the method is:
self.assertTrue(data_objects_edit_page.is_value_deleted_from_user_defined_field("Testa"), "User Defiend field Testa has not been deleted")
The HTML snippet is:
<table id="data_configuration_edit_data_object_tab_details_tb_fields" class="GFNQNVHJE border" cellspacing="0" __gwtcellbasedwidgetimpldispatchingfocus="true" __gwtcellbasedwidgetimpldispatchingblur="true">
<thead aria-hidden="false">
<colgroup>
<tbody style="">
<tr class="GFNQNVHCD GFNQNVHMD" __gwt_subrow="0" __gwt_row="0">
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHED GFNQNVHLD GFNQNVHND">
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHND">
<div __gwt_cell="cell-gwt-uid-407" style="outline-style:none;">
<input id="" class="" type="text" style="color: black;" value="AREACODE"/>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHND">
<div __gwt_cell="cell-gwt-uid-408" style="outline-style:none;">
<select tabindex="-1">
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDD GFNQNVHOD GFNQNVHND">
<div __gwt_cell="cell-gwt-uid-409" style="outline-style:none;">
<input id="" class="" type="text" style="color: black;" value="50"/>
</div>
</td>
</tr>
<tr class="GFNQNVHCE GFNQNVHJD" __gwt_subrow="0" __gwt_row="1">
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHED GFNQNVHKD">
<div __gwt_cell="cell-gwt-uid-406" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHKD">
<div __gwt_cell="cell-gwt-uid-407" style="outline-style:none;">
<input id="" class="" type="text" style="color: black;" value="VSEQ"/>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHKD">
<div __gwt_cell="cell-gwt-uid-408" style="outline-style:none;">
<select tabindex="-1">
<option value="Integer">Integer</option>
<option selected="selected" value="Text string">Text string</option>
<option value="Date/time">Date/time</option>
<option value="Floating point">Floating point</option>
</select>
</div>
</td>
<td class="GFNQNVHBD GFNQNVHDE GFNQNVHOD GFNQNVHKD">
</tr>
</tbody>
<tbody style="display: none;">
<tfoot style="display: none;" aria-hidden="true"/>
</table>
The error I get is:
Traceback (most recent call last):
File "E:\test_runners 2 edit project - add more tests for Regression\selenium_regression_test_5_1_1\Regression_TestCase\RegressionProjectEdit_TestCase.py", line 951, in test_000033_Data_Objects_edit_ACVSEQ2_and_save_edited_changes
self.assertTrue(data_objects_edit_page.is_value_deleted_from_user_defined_field("Testa"), "User Defiend field Testa has not been deleted")
File "E:\test_runners 2 edit project - add more tests for Regression\selenium_regression_test_5_1_1\Pages\data_objects_edit.py", line 502, in is_value_deleted_from_user_defined_field
col_name = row.find_elements(By.TAG_NAME, "td")[1] # This is the Name column
IndexError: list index out of range
How do I iterate over the table and check "Testa" or for example "AREACODE" is not in the table?
"AREACODE" is in the HTML snippet above. I think it is at index column 1
Thanks, Riaz
IndexError: list index out of range
Actually you're passing hard coded index without checking it's length to determine whether column present or not after deleting the column, that's why it is throwing exception which is absolutely correct because after deleting column from desired row there is no more desire column element present at provided index.
You should try to check column elements length instead to determine whether deleted column element exists or not as below :-
rows = table_id.find_elements(By.TAG_NAME, "tr")
for row in rows:
cols = row.find_elements(By.TAG_NAME, "td")
if len(cols) > 1 and cols[1].text == name :
return False
return True
It seems to be just getting the header of the table and stopping there. It won't go to the next line which is cols = row.find_elements(By.TAG_NAME, "td")
Actually you need to return True after for loop as below :-
rows = table_id.find_elements(By.TAG_NAME, "tr")
for row in rows :
cols = row.find_elements(By.TAG_NAME, "td")
if len(cols) > 1 and cols[1].text == name :
return False
return True
I could use self.driver.page_source and check in the page source if the text is there or not
If you just want to determine desire text exists on the page or not after delete, you can try as below instead :-
if len(driver.find_elements_by_xpath(".//table[#id='data_configuration_edit_data_object_tab_details_tb_fields']//*[text()= '"+name+"']")) > 0 :
return False
return True

I have a table of rows with checkboxes in columns. How do i select a particular checkbox

I have the following HTML structure. A table with rows, the 2nd column has the text displayed e.g. Title (in row 1), FName (in row 2), SNAME (in row3), GENDER etc.
The 3rd column has a checkbox for each row.
I am trying to select a particular checkbox. E.g. my method will accept a parameter (the name of the text value in the row e.g. TITLE).
The method will select the checkbox for TITLE.
When i call the method again with parameter FNAME, the checkbox for FNAME will be clicked.
I am using Selenium Webdriver with Python
I have tried the following XPATH to identify the checkbox:
//span[#title="TITLE" and contains(text(), "TITLE")]/following-sibling::*
//span [text()="TITLE"]/../../preceding-sibling::td/div/input[#type="checkbox"]
These do not find the checkbox for the row called TITLE
I can get to the TITLE with the following XPATH.
//span [text()="TITLE"]
My code snippet is:
def add_mapping2(self, name):
try:
checkbox = self.driver.find_element(By.XPATH, '//span [text()="+name+"]/../../preceding-sibling::td/div/input[#type="checkbox"]')
checkbox.click()
except NoSuchElementException, e:
return False
return True
From my unittest.Testcase class I call the method as follows:
class MappingsPage_TestCase(BaseTestCase):
def test_add_mappings(self):
mappingsPage = projectNavigator.select_projectNavigator_item("Mappings")
mappingsPage.add_mapping2("TITLE")
mappingsPage.add_mapping2("SNAME")
The HTML is:
<table id="data_configuration_edit_mapping_tab_mappings_ct_mapping_body" cellspacing="0" style="table-layout: fixed; width: 100%;">
<colgroup>
<tbody>
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="0">
<tr class="GOFU2OVEH GOFU2OVGH GOFU2OVPG GOFU2OVMG" __gwt_subrow="0" __gwt_row="1">
<td class="GOFU2OVEG GOFU2OVFH GOFU2OVHG GOFU2OVHH GOFU2OVAH GOFU2OVNG">
<td class="GOFU2OVEG GOFU2OVFH GOFU2OVHH GOFU2OVAH GOFU2OVNG">
<div __gwt_cell="cell-gwt-uid-792" style="outline-style:none;">
<span title="TITLE" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">TITLE</span>
</div>
</td>
<td class="GOFU2OVEG GOFU2OVFH GOFU2OVHH GOFU2OVBH GOFU2OVOG GOFU2OVAH GOFU2OVNG">
<div __gwt_cell="cell-gwt-uid-793" style="outline-style:none;" tabindex="0">
<input type="checkbox" checked="" tabindex="-1"/>
</div>
</td>
</tr>
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="2">
<td class="GOFU2OVEG GOFU2OVGG GOFU2OVHG">
<div __gwt_cell="cell-gwt-uid-791" style="outline-style:none;">
<input type="radio" name="rbCrossRow124"/>
</div>
</td>
<td class="GOFU2OVEG GOFU2OVGG">
<div __gwt_cell="cell-gwt-uid-792" style="outline-style:none;">
<span class="" title="FNAME" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;empty-cells:show;display:block;padding-right: 1px;">FNAME</span>
</div>
</td>
<td class="GOFU2OVEG GOFU2OVGG GOFU2OVBH">
<div __gwt_cell="cell-gwt-uid-793" style="outline-style:none;">
<input type="checkbox" tabindex="-1"/>
</div>
</td>
</tr>
<tr class="GOFU2OVEH" __gwt_subrow="0" __gwt_row="3">
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="4">
<tr class="GOFU2OVEH" __gwt_subrow="0" __gwt_row="5">
<tr class="GOFU2OVFG" __gwt_subrow="0" __gwt_row="6">
more rows with names with checkboxes etc......
</tbody>
</table>
What XPATH could I use to get the checkbox for TITLE, FNAME etc?
I have the table ID "data_configuration_edit_mapping_tab_mappings_ct_mapping_body"
Maybe there is a way to start from the table ID and use a for loop to iterate through the rows and find the particular checkbox?
Thanks.
Riaz
you would use the following xpath expression
String xpath = "//span[#title = 'TITLE']/ancestor::tr[1]//input[#type = 'checkbox']"
What it does:
first search for a span element with your parameter (pls change 'TITLE' to the variable you are using)
then find the first ancestor element that is a tr-element
from there find the input element that is your checkbox within this tr-element
You could then refine to sth like this:
WebElement table = driver.findElement(By.id("data_configuration_edit_mapping_tab_mappings_ct_mapping_body"));
WebElement checkbox = table.findElement(By.xpath(xpath));
For the interest of others whom come across a similar problem. My Python code which I have used for the above answer is:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
def add_mapping(self, name):
wait = WebDriverWait(self.driver, 10)
try:
checkbox = wait.until(EC.element_to_be_clickable((By.XPATH, '//span[#title = "%s"]/ancestor::tr[1]//input[#type = "checkbox"]' % name)))
#table_id = self.driver.find_element(wait.until(EC.element_to_be_clickable(By.ID, 'data_configuration_edit_mapping_tab_mappings_ct_mapping_body')))
#checkbox = table_id.find_element(By.XPATH, '//span[#title = "TITLE"]/ancestor::tr[1]//input[#type = "checkbox"]')
checkbox.click()
except NoSuchElementException, e:
return False
return True
The table id i commented out also works.

Error executing query, using ajax?

I'm updating a query using a form and ajax.
I added a new column (select option) to the form, it work before adding the select option.
I'm trying to get the value of the #dept_id# but i keep getting error
'NetworkError: 500 Error Executing Database Query'.
This has to do with the update query I have in delete_record.cfc.
when adding dept=#selectDept# to the query is when i get the error.
Taking this part off the query works and it updates.
Below its the form and after that its the delete_record.cfc file.
I also made a http://jsfiddle.net/6focvy54/4/
where I poster the ajax call and have the delete_record.cfc file code.
<form method="post" action="" id="confrm_key">
<table >
<tr>
<th >Add?</th>
<th >Delete?</th>
</tr>
<cfoutput query="total">
<tr id="hd#emp_id#">
<td>
<select name="selectDept" >
<option selected="selected" >Select Department</option>
<cfloop query="department">
<option value="#dept_id#">#dept_name#</option>
</cfloop>
</select>
</td>
<td> <input type="checkbox" name="check_delete" value="#emp_id#" >Yes</td>
</tr>
</cfoutput>
</table>
<p><input type="button" name="Submit" value="Remove" onclick="sub_keys();"></p>
</form>

How to generate dynamic name for a <td> and pass the name of it to server

I have the following code :
{% for assessments in list_assessments%}
<form action="/test/" method="post">{%csrf_token%}
<tr>
<td>{{assessments.assessment_id}}</td>
<td>{{assessments.name}}</td>
<td>{{assessments.assessment_begin_date}}</td>
<td>{{assessments.assessment_end_date}}</td>
<td>{{assessments.is_active}}</td>
<td>{{assessments.is_complete}}</td>
<td>{{assessments.created_at}}</td>
<td>{{assessments.updated_at}}<br></td>
<td><input type="submit" value="Edit Assessment" /></td>
</tr>
{%endfor%}
</form>
All the data here are dynamically coming.
In this following code, i need to assign an name to assessments.name dynamically, something like
<td name="dynamic_name">{{assessment.name}}</td>.
And on clicking the button "Edit Assessment", i want the dynamic_name to be passed and received my the view.
The idea is each assessment has its own set of parameters. I want to display only the parameters related to the name. So if i could pass the value i would be able to do it.
Any help appreciated.
Your ending **</form>** tag should be before for loop.
{% for assessments in list_assessments%}
<form action="/test/" method="post" name="form-{{ assessments.counter }}">{%csrf_token%}
<tr>
<td>{{assessments.assessment_id}}</td>
<td>{{assessments.name}}</td>
<td>{{assessments.assessment_begin_date}}</td>
<td>{{assessments.assessment_end_date}}</td>
<td>{{assessments.is_active}}</td>
<td>{{assessments.is_complete}}</td>
<td>{{assessments.created_at}}</td>
<td>{{assessments.updated_at}}<br></td>
<td><input type="submit" value="Edit Assessment" /></td>
</tr>
</form>
{%endfor%}
Now, You can get specific block values by form name ( see above code ) in javascript as well as in python.
In Javascript,
form = document.getElementByTagName("form")
elems = form.children("td")
elems will give you all td elements.