Django Formset Iteration go wrong - django

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

Related

how to find if string is in a result of a query set in Django

I have the following object result from query set on a model as follow:
ddd = Post_Sub_Category.objects.filter(
category_name__category_name__iexact=dd
).values_list('sub_category_name', flat=True)
the query set I obtained:
<QuerySet ['car', 'spare parts', 'truck', 'motor cycle']>
then tried:
print(ddd.values('sub_category_name'))
I obtained the following result:
<QuerySet [
<Post_Sub_Category: car>,
<Post_Sub_Category: spare parts>,
<Post_Sub_Category: truck>,
<Post_Sub_Category: motor cycle>
]
How to access the values only and make list of them as string:
['car','spare parts','truck','motor cycle'].
the first query set seems that it gave me what I want. However, When I use following if statement. it does not executed:
if 'car' in ddd:
# do some thing
as you can see car should be in the list. so, I could not understand why the if statement has not been executed.
any help or suggestion?
I think you might need to index that. The values list actually looks like it returns a list. Can you try:
try:
ddd = ddd[0]
except IndexError:
# Catch index error
pass
if 'car' in ddd:
# do some thing
If that doesn't work, try explicitly converting your QuerySetList to a regular ole list, as in this question, like this:
ddd = list(ddd)
Also, this looks a little strange to me: category_name__category_name__iexact=dd. Posting your corresponding models would be helpful.

Fetch value of selection field instead of key

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]

When appending dictionaries to a list through for loop, I get only the last dictionary

I'm trying to scrape a career search website by going through all the different pages and I keep running into a problem when I try to append the dictionaries into a list using a for loop. When I execute the code below in Python 3.4, the code will pull all the relevant data from each page into a dictionary (I've checked with print()) and append into "FullJobDetails", but at the end of the for loop I get a list that is full of dictionaries from the last page only. The number of dictionaries is exactly the same as the number of pages in the list "ListofJobs". "ListofJobs" is a list of html links to each page that I am scrapping.
I just started learning code, so I know that the code below is not in any shape, way, or form the most efficient or best way of doing it. Any suggestions would be appreciated. Thanks in advance!
FullJobDetails = []
browser = webdriver.Chrome()
dictionary = {}
for jobs in ListofJobs:
browser.get(jobs)
dictionary["Web Page"] = jobs
try:
dictionary["Views"] = browser.find_element_by_class_name('job-viewed-item-count').text
except NoSuchElementException:
dictionary["Views"] = 0
try:
dictionary['Applicants'] = browser.find_element_by_class_name('job-applied-item-count').text
except NoSuchElementException:
dictionary["Applicants"] = 0
try:
dictionary["Last Application"] = browser.find_element_by_class_name('last-application-time-digit').text
except NoSuchElementException:
dictionary["Last Application"] = "N/A"
try:
dictionary["Job Title"] = browser.find_element_by_class_name('title').text
except NoSuchElementException:
dictionary["Job Title"] = "N/A"
try:
dictionary['Company'] = browser.find_element_by_xpath('/html/body/div[3]/article/section[2]/div/ul/li[4]/span/span').text
except NoSuchElementException:
dictionary['Company'] = "Not found"
try:
dictionary['Summary'] = browser.find_element_by_class_name('summary').text
except NoSuchElementException:
dictionary['Summary'] = "Not found"
FullJobDetails.append(dictionary)
The problem is that you create only a single dictionary - dicitonaries are mutable objects - the same ditionary is appended over and over to your list, and on each pass of the for loop you update its contents. Therefore, atthe end, you will have multple copies of the same dicitonry, all showing the information on the last page fectched.
Just create a new dictionary object for each run of the for loop. That new dictionary will be saved on the list, and the variable name dictionary can hold your new object with no conflicts.
for jobs in ListofJobs:
dictionary = {}
browser.get(jobs)
...

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).

How to remember objects to be treated after QuerySet.update()

I want to update the bar attribute of a bunch of Foo objects using the QuerySet's update() method. Then I want to do something with the modified objects, but I can no more identify them using the bar attribute.
Somehow it doesn't work by remembering the ids.
old_bar = Bar.objects.get(id=1)
new_bar = Bar.objects.get(id=2)
foo_query = Foo.objects.filter(bar=old_bar)
foo_ids = foo_query.values_list('id', flat=True)
print len(foo_ids), foo_query.count(), Foo.objects.filter(id__in=foo_ids).count()
# outputs "42 42 42"
print foo_query.update(bar=new_bar)
# outputs "42"
print len(foo_ids), foo_query.count(), Foo.objects.filter(id__in=foo_ids).count()
# outputs "42 0 0"
Does the update() method modify the ids or what am I doing wrong?
Querysets are lazy, so they are evaluated everytime you use them! Therefore in your example foo_query will be evaluated more than once and return something different depending on the actual objects in your database. foo_ids is therefore not a list of ids, but a ValuesQueryset that evaluates to a list.
Forcing it evaluate to a list should make your example work, as the ids do not change to reflect the actual state of the database: foo_ids = list(foo_query.values_list('id', flat=True)).