Accessing Python List - django

Hi I have this list which is working for what initially intended for
gp_list_t = [int(i) for i in gp_list]
gp_lits3 = gp_list_t[0]
agencys_sp = GPSpecial.objects.filter(agencys=user_agency,is_active=True,id =gp_lits3).values_list('agencys')
Now say they are more than 1 values on the list -gp_list_t. How do I access other values on the list that i want to use on my variable agencys_sp
Updated Code :
gp_list_t = [int(i) for i in gp_list]
agencys_sp=GPSpecial.objects.filter(agencys=user_agency,is_active=True,id=gp_list_t).values_list('agencys')
for value, in agencys_sp:
agency_tu = [i for i, in agencys_sp]
returns error int() argument must be a string, a bytes-like object or a number, not 'list'

You can use the in filter operator to query all rows matching the IDs in the gp_list_t. Then iterate over the queryset with a for loop:
gp_list_t = [int(i) for i in gp_list]
agencys_sp = GPSpecial.objects.filter(agencys=user_agency,is_active=True,id__in=gp_list_t).values_list('agencys')
for value, in agencys_sp:
print(value)

Related

Declaring an object within (vs. outside) a while loop

Given the python 2.7 code below:
# faultReportObj = {}
flatDataObj = []
while row:
faultReportObj = {}
faultReportObj['MessageTime'] = row['MessageTime']
faultReportObj['Event'] = row['Event']
faultReportObj['Subsystem'] = row['Subsystem']
faultReportObj['UnifiedFaultCode'] = row['UnifiedFaultCode']
faultReportObj['FaultDescription'] = row['FaultDescription']
faultReportObj['FaultDetails'] = row['FaultDetails']
faultReportObj['FirstOccurrenceDateTime'] = row['FirstOccurrenceDateTime']
faultReportObj['LastOccurrenceDateTime'] = row['LastOccurrenceDateTime']
faultReportObj['OccurrenceCount'] = row['OccurrenceCount']
print "current row:"
pp.pprint(faultReportObj)
flatDataObj.append(faultReportObj)
row = cursor.fetchone()
conn.close()
pp.pprint(flatDataObj)
If I declare faultReportObj outside the while loop, I get (say) 96 entries in flatDataObj that are all identical to the very last row returned by the query. Note that the pprint statement within the while loop prints the expected (varying) results.
If, as above, I declare faultReportObj inside the loop, flatDataObj is loaded correctly.
Why???? Why is the very last row returned being propagated throughout the entire list?
Thanks!
This is due to list.append inserting a reference to faultReportObj and not copying the value of the dict.
Another way of looking at it:
If you define faultReportObj before the loop, the following occurs:
Create a new dict.
Populate it.
Append a reference to the dict into the list.
Change the dict's content.
Append another reference to the same dict.
etc.
Here's a short piece of code that exemplifies this property:
>>> d = {}
>>> l = []
>>> l.append(d)
>>> d[1] = 2
>>> l
[{1: 2}]
What you want is for step one (Create a new dict) to happen in every iteration of the loop, so that you append a different dict every time.

Indexing a list of dictionaries for a relating value

I have a 4 dictionaries which have been defined into a list
dict1 = {'A':'B'}
dict2 = {'C':'D'}
dict3 = {'E':'F'}
dict4 = {'G':'H'}
list = [dict1, dict2, dict3, dict4]
value = 'D'
print (the relating value to D)
using the list of dictionaries I would like to index it for the relating value of D (which is 'C').
is this possible?
note: the list doesn't have to be used, the program just needs to find the relating value of C by going through the 4 dictionaries in one way or another.
Thanks!
You have a list of dictionaries. A straightforward way would be to loop over the list, and search for desired value using -
dict.iteritems()
which iterates over the dictionary and returns the 'key':'value' pair as a tuple (key,value). So all thats left to do is search for a desired value and return the associated key. Here is a quick code I tried. Also this should work for dictionaries with any number of key value pairs (I hope).
dict1 = {'A':'B'}
dict2 = {'C':'D'}
dict3 = {'E':'F'}
dict4 = {'G':'H'}
list = [dict1, dict2, dict3, dict4]
def find_in_dict(dictx,search_parameter):
for x,y in dictx.iteritems():
if y == search_parameter:
return x
for i in range(list.__len__()):
my_key = find_in_dict(list[i], "D")
print my_key or "No key found"
On a different note, such a usage of dictionaries is little awkward for me, as it defeats the purpose of having a KEY as an index for an associated VALUE. But anyway, its just my opinion and I am not aware of your use case. Hope it helps.

django - remove field name and brackets

I have the following queryset -
pk = Jobmst.objects.db_manager('database1').extra(where=['jobmst_alias=%s'], params=[alias]).values('jobmst_id')
Which returns the following -
[{'jobmst_id': 21195}]
edit -
pk = Jobmst.objects.db_manager('database1').extra(where=['jobmst_alias=%s'], params=[alias]).values_list('jobmst_id', flat=True)
Returns the following -
[21195]
Close but I don't want the brackets I want only the integer.
I want it to simply give me the integer value so I can call it in another query -
mst = Jobmst.objects.db_manager('database1').raw("""
SELECT jobmst_id, jobmst_type, jobmst_prntname AS jobmst_prntid, jobmst_active,
evntmst_id, jobmst_evntoffset, jobmst_name, jobmst_mode, jobmst_owner, jobmst_desc,
jobmst_crttm, jobdtl_id, jobmst_lstchgtm, jobmst_runbook, jobcls_id, jobmst_prntname,
jobmst_alias, jobmst_dirty FROM Jobmst WHERE jobmst_id = %s""", [pk])
Which would ideally parse as this -
mst = Jobmst.objects.db_manager('database1').raw("""
SELECT jobmst_id, jobmst_type, jobmst_prntname AS jobmst_prntid, jobmst_active,
evntmst_id, jobmst_evntoffset, jobmst_name, jobmst_mode, jobmst_owner, jobmst_desc,
jobmst_crttm, jobdtl_id, jobmst_lstchgtm, jobmst_runbook, jobcls_id, jobmst_prntname,
jobmst_alias, jobmst_dirty FROM Jobmst WHERE jobmst_id = 21195""")
values returns list of dicts, so you can access value by list index and key name:
try:
pk = Jobmst.objects.db_manager('database1').extra(where=['jobmst_alias=%s'],
params=[alias]).values('jobmst_id')[0]['jobmst_id']
except IndexError:
pk = None
You can use values_list that returns only list of specified fields values and to access the value you need only index:
try:
pk = Jobmst.objects.db_manager('database1').extra(where=['jobmst_alias=%s'],
params=[alias]).values_list('jobmst_id', flat=True)[0]
except IndexError:
pk = None

django, trying to manipulate queryset and return to template

I'm trying to perform an operation on all the elements from a single field of a model, but I'm getting an error:
list indices must be integers, not tuple
Here's my index function in views.py:
design_list = Design.objects.values_list().order_by('-date_submitted')[:10]
x=list(design_list)
for i in x:
b = list(x[i]) # ERROR RELATES TO THIS LINE
c = b[2]
b[2] = datetimeConvertToHumanReadable(c)
new_list[i] = b
return render_to_response('index.html', {
'design_list': new_list,
})
I'm sure this is a common problem, does anyone know what I'm doing wrong?
Python is not C - the for x in y loop does not loop over indices, but over the items themselves.
design_list is a list of tuples, so you can treat it as such. Tuples are immutable, therefore you'll need to create a new list. A list comprehension would probably be best.
# Create a new list of tuples
new_list = [row[:2] + (datetimeConvertToHumanReadable(row[2]),) + row[3:]
for row in x]
However, it doesn't seem like you really need to use tuples, since you were confused by the error. If this is the case, then don't use values_list (which returns tuples), but just use order_by, and reference the field directly (I'll assume it's called date_submitted).
design_list = Design.objects.order_by('-date_submitted')[:10]
x=list(design_list)
for row in x:
row.date_submitted = datetimeConvertToHumanReadable(row.date_submitted)
return render_to_response('index.html', {
'design_list': x,
})
for i in x: iterates over the values of x, not the indices. Without analyzing the intent behind the code (and the proper use of QuerySets), the line could be changed to:
b = list(i)
to avoid this particular error.

In django forms custom widget return list as value instead of string

I am writting a custom widget which I want to return a list as the value. From what I can find to set the value that is returned you create a custom value_from_datadict function. I have done this
def value_from_datadict(self, data, files, name):
value = data.get(name, None)
if value:
# split the sting up so that we have a list of nodes
tag_list = value.strip(',').split(',')
retVal = []
# loop through nodes
for node in tag_list:
# node string should be in the form: node_id-uuid
strVal = str(node).split("-")
uuid = strVal[-1]
node_id = strVal[0]
# create a tuple of node_id and uuid for node
retVal.append({'id': node_id, 'uuid': uuid})
if retVal:
# if retVal is not empty. i.e. we have a list of nodes
# return this. if it is empty then just return whatever is in data
return retVal
return value
I expect this to return a list but when I print out the value it is returned as a string rather than a list. The string itself contains the right text but as i said it is a string and not a list. An example of what is returned could be
[{'id': '1625', 'uuid': None}]
but if I did str[0] it would print out [ instead of {'id': '1625', 'uuid': None}
How can I stop it from converting my list into a string?
Thanks
Well, it's simple: if you have a CharField, then you will get a string as a result, because CharField uses method to_python, that coerces the result to string. You need to create your own Field for this one and return a list.
OLD
Could you post the result of:
x = value_from_datadict(..)
print type(x)
so we can see, what exactly is returned?
And could you post the whole test case you are using to deliver the example?