Remove specific sign when filtering in Django - django

I have this query in my views.py
cardId = request.POST.get('id')
with connection.cursor() as cursor:
cursor.execute("SELECT category1_id FROM app_card_tbl WHERE id =%s", [cardId])
row = cursor.fetchone()
cursor.execute("SELECT name FROM app_category1_tbl WHERE id =%s",[row])
tab1 = cursor.fetchone()
print(tab1)
And the output of this when print is
('thisisname',)
All i want is the output should looks like below must remove the `(',) sign it is possible?
thisisname

The reason this happens is because each record is put in a tuple, even if it contains a single column. You can print the first item with:
print(tab1[0])
or you can unwrap it when fetching the object:
tab1, = cursor.fetchone()
print(tab1)

Related

Django Table forward fill missing values

I have a table like this:
A
B
a
row
row
row
row
b
row
row
row
c
row
...
....
How can I fill in missing values like forward fill in Pandas data frame using Django ORM query?
PS: I have an ID column which is unique
Assuming, that the table is sorted by primary key.
If this is just a one-off you could do something like this. It will probably take a very long time if you have a very large table.
To actually run in you can use the django shell or django management command.
latest_a = None
max_id = MyModel.objects.last().id
for i in range(1, max_id + 1):
try:
instance = MyModel.objects.get(pk=i)
except MyModel.DoesNotExist:
continue
if instance.a == None and latest_a:
instance.a = latest_a
instance.save()
else:
latest_a = instance.a

Use response of a method to define a model field in Django

I need some dynamic choices fields in a django model and I want to validate if a table exists before get them.
I already know how to check if the table exists with raw sql and also I know how to generate my dynamic tuple for choices, but I don't know how to use the response of my validation method.
Any ideas?
This is a snippet of my code:
class SomeModel(models.Model):
...
row = False
def check_table(self):
with connection.cursor() as cursor:
cursor.execute(
"SELECT EXISTS("
"SELECT *"
" FROM pg_tables WHERE schemaname = \'schema_name\' AND "
"tablename = \'table_name\')")
row = cursor.fetchall()
return row
# Then, I need to put that reponse in a variable to do something like this.
if table_exists:
# do something
...
Thanks

Webdriver Wait showing StaleElementReferenceException Message Element is no longer valid when i loop through table rows

I am using Selenium Webdriver with Python. I have some code which loops through rows in a HTML table. It finds the values in the columns.
I am getting Element is no longer valid.
It is a race condition because sometimes it works if all the rows load in time on the webpage.
StaleElementReferenceException: Message: Element is no longer valid
I am using Webdriver Wait. Maybe my syntax is incorrect. Here is my code snippet.
It would be helpful if someone could give help here on how to solve this element no longer valid issue.
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
from Locators.locators import MainPageLocators
def is_mappings_details_saved(self, name, dataset, feed, variable):
try:
WebDriverWait(self.driver, 20).until(EC.presence_of_all_elements_located((By.TAG_NAME, 'td')))
table_id = self.get_element(*MainPageLocators.mappings_details_savedpage_table)
#rows = table_id.find_elements(By.TAG_NAME, "tr")
rows = WebDriverWait(self.driver, 20).until(EC.presence_of_all_elements_located(table_id.find_elements(By.TAG_NAME, "tr")))
for row in rows:
time.sleep(1)
# Get the columns
col_name = row.find_elements(By.TAG_NAME, "td")[1] # This is the Name column
col_variable = row.find_elements(By.TAG_NAME, "td")[2] # This is the Variable column
col_feed = row.find_elements(By.TAG_NAME, "td")[3] # This is the Feed column
col_data_category = row.find_elements(By.TAG_NAME, "td")[4] # This is the Data Category column
col_dataset = row.find_elements(By.TAG_NAME, "td")[6] # This is the Dataset column
col_datamap = row.find_elements(By.TAG_NAME, "td")[7] # This is the Datamap column
if (col_name.text == name) and (col_variable.text == variable) and (col_feed.text == feed) and (col_data_category.text == "Main") and (col_dataset.text == dataset) and (col_datamap.text == self.datamap_name):
return True
return False
except NoSuchElementException, e:
return False
The following line is where the problem is
rows = WebDriverWait(self.driver, 20).until(EC.presence_of_all_elements_located(table_id.find_elements(By.TAG_NAME, "tr")))
The webpage displays a table of columns (Name, Variable, Feed etc).
Each row has data for each column. E.g. Lucy, Name, datafeed.
I am checking if the data is correct in each row in the if statement.
I need to wait for all off the rows in the table to be loaded to avoid the stale element exception.
What is the best way to wait for the whole table to be loaded?
Here is the working solution:
JeffC suggested to wait for just the table container to load. No need to wait for cols and rows as well. I have got it to work now. I also put self.driver.implicitly_wait(20)in the base class.
Here is the working solution:
class BasePage(object):
def __init__(self, driver):
self.driver = driver
self.driver.implicitly_wait(20)
class MappingsPage(BasePage):
def is_mappings_details_saved(self, name, dataset, feed, variable):
table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((*MainPageLocators.mappings_details_savedpage_table)))
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]
col_variable = row.find_elements(By.TAG_NAME, "td")[2]
etc...
Thanks,
Riaz
I'm confused about what you are trying to do. You waited for all TDs on the page in the first line (which seems odd)... why are you then waiting for all the TRs under some TABLE 3 lines down? My guess is that table_id is stale because you are using bad references in *MainPageLocators. Unless the table is getting loaded dynamically, you should be able to just wait for a single element on the page to load. Once it does, the entire DOM should be loaded. You could wait for the container TABLE if it has an ID, etc. Without more code or the relevant HTML, I'm not sure I can help you further.
JeffC suggested to wait for just the table container to load. No need to wait for cols and rows as well. I have got it to work now. I also put self.driver.implicitly_wait(20)in the base class - Here is the solution:
class BasePage(object):
def __init__(self, driver):
self.driver = driver
self.driver.implicitly_wait(20)
class MappingsPage(BasePage):
table_id = WebDriverWait(self.driver, 20).until(EC.presence_of_element_located((*MainPageLocators.mappings_details_savedpage_table)))
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]
col_variable = row.find_elements(By.TAG_NAME, "td")[2]
etc...
I had a similar issue with the WebdriverWait on a long loop and chocking on it. The way I resolved was to create a utility function outside the loop.
In the loop call the function and pass parameters to it.
def try_path(driver,foo):
# this is an utility to circumvent the stale error
try:
foo = WebDriverWait(driver).until(EC.presence_of_element_located((By.TAG_NAME, "#yourtablehere")))
return foo
except WebDriverException as e:
return try_path(foo)
You may want to implement a counter just in case

How can i do such query in multiple tables at the same time in django

I happen on some query like this below:
bphoto = B_Photo.objects.filter(q_user).order_by('-pub_date')
bactivity = B_Activity.objects.filter(q_user).order_by('-pub_date')
bpart = B_Part.objects.filter(q_user).order_by('-pub_date')
q_user is a Q object,and what i want is to sort all results in the three tables,use the 'pub_date' field.
how can i simplify this kind of query?
B_Photo, B_Activity and B_Part don't have the same table structure, right? I think you cannot make a query with three different table. UNION can do this but it requires all the sub-queries return data with the same structure.
It seems that you want to display a timeline mixed with photos, activities and parts. The most reasonable way is to sort the results in python.
bphoto = B_Photo.objects.filter(q_user).order_by('-pub_date')
bactivity = B_Activity.objects.filter(q_user).order_by('-pub_date')
bpart = B_Part.objects.filter(q_user).order_by('-pub_date')
timeline = sorted(bphoto + bactivity + bpart, key=lambda x:x.pub_date)
UPDATE:
I see what you mean. If you have too much data in these 3 tables and you only want to show the most recent, say, 20 records, you can run a raw UNION sql on the 3 tables like this:
cursor = connection.cursor()
cursor.execute("SELECT id, type FROM (
SELECT id, 'photo' AS type, pub_date FROM b_photo UNION
SELECT id, 'activity' AS type, pub_date FROM b_activity UNION
SELECT id, 'part' AS type, pub_date FROM b_part) AS my_query
ORDER BY pub_date DESC LIMIT 20")
results = cursor.fetchall()
# results will be something like ((id, type), (id, type), ...)
# where type indicates what the id is (photo, activity or part)
Then use individual B_XXX.objects.get(id=id) to get each object in ids.
for result in results:
if result[1] == 'photo':
obj = B_Photo.objects.get(id=result[0])
elif result[1] == 'activity':
obj = B_Activity.objects.get(id=result[0])
elif result[1] == 'part':
obj = B_Part.objects.get(id=result[0])
# do sth with obj...

Transpose Django Table in django_tables2

I'm trying to make a view that essentially shows information about a record like this
|Description| blahblahblah
|Name | blah blah blahs
|Last Edited| someDate
|Owned by | Blah blah blah info
which is transposed from the way that django_tables2 renders tables by default. Is there an easy way to do this or will I have to code my own template? I'm find doing that (in theory) as there's a good example of a custom template which says I have to "pass an instance of your Table subclass into your own template, and render it yourself". I don't actually know what's meant by that though :(
You will need to write your own template that produces the HTML you desire, by iterating over attributes of the table and writing the correct tags. A good example of how you might do this is the template used for the as_html() function: https://github.com/bradleyayers/django-tables2/blob/master/django_tables2/templates/django_tables2/table.html
I solved this for a project today, it was actually fairly simple.
Define a new table
Within tables.py, define a two-column table. Let's call the first column name and second column value:
class RowTable(tables.Table):
name = tables.Column()
value = tables.Column()
class Meta:
template = 'django_tables2/bootstrap.html'
attrs = {'class': 'table table-striped table-responsive'}
In your view, bind data to table
Then, in your view, you need to pull the instance (row) from your database, and populate the table using a dictionary:
row_instance = Model.objects.get(foo=foo.id)
#Extract column data from instance be sure it is string!
height = str(row_instance.height)
weight = str(row_instance.weight)
nationality = row_instance.nationality
#Create dictionary of data in form table will recognize
row_data =[ {'name': 'height', 'value': height},
{'name': 'weight', 'value': weight},
{'name': 'nationality', 'value': nationality} ]
#Bind to table and configure
table = RowTable(row_data)
Then configure the table, put in context and send to template as usual. You will have a table with two columns showing all the data from a row of your database.
Change the result_list(cl) function in /lib/python2.7/site-packages/django/contrib/admin/templatetags/admin_list.py to this:
def result_list(cl):
"""
Displays the headers and data list together
"""
headers = list(result_headers(cl))
num_sorted_fields = 0
for h in headers:
if h['sortable'] and h['sorted']:
num_sorted_fields += 1
result1 = list(results(cl))
result2 = map(list, zip(*result1))
return {'cl': cl,
'result_hidden_fields': list(result_hidden_fields(cl)),
'result_headers': headers,
'num_sorted_fields': num_sorted_fields,
'results': result2}