Fetch value of selection field instead of key - python-2.7

I defined a selection field in one model.
type = fields.Selection([('a','A'),('b','B'),('c','C')])
In one of function i tried to get string value instead of key.
#api.multi
def testFunc(self):
for res in self:
print'Value',res.type //It prints 'a'.
I need to print 'A'.
How can i do this?

Choose One of the solutions :
The most importing thing that you can get the selection list like this:
self._fields['type'].selection
So try this:
# convert the list to dictionary
dict(self._fields['type'].selection).get(self.type)
IF you want the label to be translated in user language:
# here the label return is translated.
value = dict(self.fields['state']._description_selection(self.evn)).get(self.type)

You can use this method, it returns the string value, translated if it's the case:
#api.multi
def testFunc(self):
for res in self:
print'Value', dict(res.fields_get(["type"],['selection'])['type']["selection"]).get(res.type)

A possible and simple solution would be:
VALUES_TYPE = [('a','A'),('b','B'),('c','C')]
type = fields.Selection(VALUES_TYPE )
dict(VALUES_TYPE )[self.type]

Related

how to extract value in queryset and convert to string

the output of my code is currently
book_name = book.objects.values('book_name').filter(book_id=book_id)
book_name =str(book_name[0])
this code should give me 'Chronicles of Narnia '.
but it instead returns {'book_name': 'Chronicles of Narnia '}. how do i extract the value i need.
*note there will only be 1 value in this query every time
You could use values_list, option flat will mean the returned results are single values:
book.objects.values('book_name')
.filter(book_id=book_id).values_list('book_name', flat=True)
# <QuerySet [book_name1, book_name2, book_name3, ...]>

How to add an unlimited number of class instances with user input in python

I am trying to use
class reader
def __init__(self, name, booksread)
self.name = name
self.booksread = booksread
while True
option = input("Choose an option: ")
if option = 1:
#What to put here?
I want to create an unlimited number of instances of the reader class, But I could only figure out how to do it a limited number of times by using variables for the class. I also need to call the info later (without losing it). Is it possible to do this with a class? Or would I be better off with a list, or dictionary?
First: if option == 1: is always false in python 3, input only reads strings there.
Second: python lists can be expanded until you run out of RAM.
So the solution would be to create a list in the surrounding code and call append on that every time you have a new item:
mylist = []
while True:
mylist.append(1)
It's perfectly possibly to populate a data structure (such as a list or dict) with instances of a class, given your code example you could put the instances into a list:
class reader
def __init__(self, name, booksread)
self.name = name
self.booksread = booksread
list = []
while True:
option = input("Choose an option: ")
if option == 1:
list.append(reader(name,booksread))
Note: I don't know how you are obtaining the values for 'name' or 'booksread', so their values in the list.append() line are just placeholders
To access the instances in that list, you can then iterate over it, or access elements by their indexes, e.g.
# access each element of the list and print the name
for reader in list:
print(reader.name)
#print the name of the first element of the list
print(list[0].name)

Dictionary error in Python 2.7

I have a file in the format:
0000 | a1_1,a3_2 | b2_1, b3_2
0001 | a1_3 | b4_1
and I'm trying to create a dictionary which has
{ 'a1' : set(['b2', 'b3', 'b4']), 'a3': set(['b2', 'b3']) }
and this is how my code looks like:
def get_ids(row, col):
ids = set()
x = row.strip().split('|')
for a in x[col].split(','):
ids.add(a.split('_')[0])
return ids
def add_to_dictionary(funky_dictionary,key, values):
if key in funky_dictionary:
funky_dictionary[key].update(values)
else:
funky_dictionary[key] = values
def get_dict(input_file):
funky_dictionary = {}
with open(input_file,'r') as ip:
for row in ip:
a_ids = get_ids(row,1)
b_ids = get_ids(row,2)
for key in a_ids:
add_to_dictionary(funky_dictionary,key,b_ids)
return funky_dictionary
So my problem is this when I lookup values for certain key in the dictionary, it returns me with way more values than expected. E.g.
For the above example the expected value of a3 would be set(['b2', ' b3'])
However with the code, I'm getting set(['b2', ' b3', 'b4'])
I cant figure out whats wrong with the code. Any help?
The issue you have is that many of your dictionary's values are in fact references to the same set instances. In your example data, when the first line is processed, 'a1' and 'a3' both get mapped to the same set object (containing 'b2' and 'b3'). When you process the second line and call update on that set via the key 'a1', you'll see the added value through 'a3' too, since both values are references to the same set.
You need to change the code so that each value is a separate set object. I'd suggest getting rid of add_to_dictionary and just using the dictionary's own setdefault method, like this:
for key in a_ids:
funky_dictionary.setdefault(key, set()).update(b_ids)
This code always starts with a new empty set for a new key, and always updates it with new values (rather than adding a reference to the b_ids set to the dictionary directly).

Python - Changing Class Variable Value in Function

I'm building a python class to encapsulate a drop-down list and its buttons in one convenient widget and I ran across a problem.
class DropDownMenu(DropDown):
def __init__(self, **kwargs):
super(DropDownMenu, self).__init__(**kwargs)
self.The_Menu = DropDown()
self.The_Btns = []
self.Num_Btns = 0
def Set_Num_Btns(self):
self.Num_Btns = len(self.The_Btns)
def Create_Menu(self, Btn_Names):
# Populate List Size Property
if (self.Num_Btns == 0):
self.Set_Num_Btns()
# Add Buttons to the Drop-Down
for i in range(0, self.Num_Btns):
self.The_Btns.append(Button(text = Btn_Names[i], size_hint_y = None, height = 20))
self.The_Menu.add_widget(self.The_Btns[i])
It compiles fine and when I try to create a drop-down menu, I get what I want:
self.File_Menu = DropDownMenu()
self.File_Menu.Create_Menu(self.File_Menu_Names)
self.add_widget(self.File_Menu)
But, if I try to bind any of the buttons to anything, like so:
self.File_Menu.The_Btns[0].bind(on_release = self.Insert_File_Menu.open)
The compiler throws an exception saying the list was out-of-bounds. On further inspection, I realized that even though I'm calling the Create_Menu function, the value of The_Btns is not being changed from an empty list. So, my question is: how do I fix this problem?
Any help would be appreciated. Thanks!
First of all, python doesn't "compile" in the sense that you refer to, and doesn't have a compiler. Also, have a look at PEP8.
To answer your question, You are iterating over a range, 0 to Num_Btns. However, in Set_Num_Btns, you set the variable to len(self.The_Btns), which is an empty list, i.e. you are iterating over range(0, 0). I suspect you mean to do soemthing like this:
for name in Btn_Names:
self.The_Btns.append(Button(text=name, ...))
....

Django Formset Iteration go wrong

I am trying to get the cleaned_data for each form in a formset, using a normal iteration (just like what shown in Django documentation):
MyFormSet = formset_factory(form=MyForm, formset=MyBaseFormSet)
my_form_set = MyFormSet(request.POST or None, initial = my_data, prefix = 'myform')
After that I'm validating and trying to iterate through each form and print it values like this:
for f in my_form_set.forms:
print(f.cleaned_data)
But the result that I get is somekind like this:
<QueryDict: {"myform-0-field_a" : "this is a", "myform-1-field_a" : "this is second a"}>
<QueryDict: {"myform-0-field_a" : "this is a", "myform-1-field_a" : "this is second a"}>
I was expecting to get individual pair of key and values, but instead, for each iteration, I get the whole thing of POST data.
I was expecting something like this:
Iteration 0:
"field_a" : "this is a"
Iteration 1:
"field_a" : "this is second a"
Where do I miss?
Thanks
The labels each form field have needs to be unique, otherwise there is no way telling
from which form what data came. "myform-0-field_a" , "myform-1-field_a" are the keys/labels
The browser send you all fields in one post.
since f.cleaned data seams to be a subclassed dict this will probably work
for k, v in f.cleaned_data.items():
print k.split('-')[-1], v
https://docs.djangoproject.com/en/dev/ref/request-response/#querydict-objects