writing to model field in django / python - python

i'm trying to populate custom user profile fields with data from social networks. i created profile fields like:
currentjobtitle1
currentjobtitle2
currentjobtitle3
pastjobtitle1
pastjobtitle2
pastjobtitle3
I'm a newb in every way, so i tried to code this more efficiently than normal and have become very confused. I'm sure my code is wrong in more ways than one, but if i can just get it to work:
pnum=0
cnum=0
for x in clean_work_obj[:]:
if x['end_date']:
var='past'
count=pnum+1
else:
var='current'
count=cnum+1
if count>3:
break
else:
SarProfile.var+'jobtitle'+str(count)= x['position']['name']
clean_work_obj is the dict i received thru the social network api.
I had expected it to write out: SarProfile.pastjobtitle1 or SarProfile.currentjobtitle3, for example, and populate that field with the "position / name" data. it breaks because there is no field called "var" in SarProfile.

setattr(SarProfile, '%sjobtitle%d' % (var, count), x['position']['name'])
But you probably want to create an instance of SarProfile first, and use that instead.

Related

Django model request array

I am new to python and Django. I haven't found anything in documentations so I have to write here.
I have such problem.
I have cars table where you can find it's make, model. year and so on.
Usually i make request by just Cars.objects.filter(make=x, model=y, year=z)
I want to make search and all params are in array. There are many params and is it possible to make something like
Cars.objects.filter(array)
Ok. How i am getting my data. It is regular post form which I send by ajax to my view class. I have list of allowed params which can be found in users request. I have different names for tableview name and input name, but i have everything i need in prepared array. It can take user's sent car-name Acura and make something like {'make':123}. At the end i have an array which is fully compatible with my db {'make': 123, 'model':321}. Can i make a request using this array and not write by hands every param?
if arguments are stored in this format:
args = [('make', 'x'),('model', 'y'),('year', 'z')]
You can try:
arg_dict = dict(args)
Cars.objects.filter(**arg_dict)

Django csv download performance issue

Ok so i am having problems generating a CSV file from data.
I have a list of about 6,000 objects. These objects are like custom forms,
so each object has many fields associated with it. for example a request could consist of name, age, phone number, etc. In this case every request has the same fields. So each form has a one to many relationship with these fields.
So I am grabbing this custom form and a few standard things from it as a ValuesQuerySet, then grabbing all of the fields associated with this form. and adding them to each row. Finally I use dictionary writer to write the data to a csv. This all works great however the performance is awful. to do my 6,000 records each with about 15 custom fields takes about 90 seconds.(This triggers a timeout error). I am in need of some way to make this faster.
My Code Looks Something like this....
forms = SomeForm.objects.filter(created_by=user).values('value1', 'value2', 'etc...')
for form in forms:
id = form['id']
fields = Fields.objects.filter(Form_id=id).values('value', 'field__label')
for field in fields:
label = field['form_field__label']
value = field['value']
form[label] = value
writer = csv.DictWriter(response, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(forms)
Some of the code is removed, but this is the gist of it.
if you can think of anyway to speed this up or maybe an alternative way to handle it i would be very grateful.
Ya I ended up taking taking cdvv7788's advice and making this a celery task. Thanks guys

Add a field to existing document in CouchDB

I have a database with a bunch of regular documents that look something like this (example from wiki):
{
"_id":"some_doc_id",
"_rev":"D1C946B7",
"Subject":"I like Plankton",
"Author":"Rusty",
"PostedDate":"2006-08-15T17:30:12-04:00",
"Tags":["plankton", "baseball", "decisions"],
"Body":"I decided today that I don't like baseball. I like plankton."
}
I'm working in Python with couchdb-python and I want to know if it's possible to add a field to each document. For example, if I wanted to have a "Location" field or something like that.
Thanks!
Regarding IDs
Every document in couchdb has an id, whether you set it or not. Once the document is stored you can access it through the doc._id field.
If you want to set your own ids you'll have to assign the id value to doc._id. If you don't set it, then couchdb will assign a uuid.
If you want to update a document, then you need to make sure you have the same id and a valid revision. If say you are working from a blog post and the user adds the Location, then the url of the post may be a good id to use. You'd be able to instantly access the document in this case.
So what's a revision
In your code snippet above you have the doc._rev element. This is the identifier of the revision. If you save a document with an id that already exists, couchdb requires you to prove that the document is still the valid doc and that you are not trying to overwrite someone else's document.
So how do I update a document
If you have the id of your document, you can just access each document by using the db.get(id) function. You can then update the document like this:
doc = db.get(id)
doc['Location'] = "On a couch"
db.save(doc)
I have an example where I store weather forecast data. I update the forecasts approximately every 2 hours. A separate process is looking for data that I get from a different provider looking at characteristics of tweets on the day.
This looks something like this.
doc = db.get(id)
doc_with_loc = GetLocationInformationFromOtherProvider(doc) # takes about 40 seconds.
doc_with_loc["_rev"] = doc["_rev"]
db.save(doc_with_loc) # This will fail if weather update has also updated the file.
If you have concurring processes, then the _rev will become invalid, so you have to have a failsave, eg. this could do:
doc = db.get(id)
doc_with_loc = GetLocationInformationFromAltProvider(doc)
update_outstanding = true
while update_outstanding:
doc = db.get(id) //reretrieve this to get
doc_with_loc["_rev"] = doc["_rev"]
update_outstanding = !db.save(doc_with_loc)
So how do I get the Ids?
One option suggested above is that you actively set the id, so you can retrieve it. Ie. if a user sets a given location that is attached to a URL, use the URL. But you may not know which document you want to update - or even have a process that finds all the document that don't have a location and assign one.
You'll most likely be using a view for this. Views have a mapper and a reducer. You'll use the first one, forget about the last one. A view with a mapper does the following:
It returns a simplyfied/transformed way of looking at your data. You can return multiple values per data or skip some. It gives the data you emit a key, and if you use the _include_docs function it will give you the document (with _id and rev alongside).
The simplest view is the default view db.view('_all_docs') this will return all documents and you may not want to update all of them. Views for example will be stored as a document as well when you define these.
The next simple way is to have view that only returns items that are of the type of the document. I tend to have a _type="article in my database. Think of this as marking that a document belongs to a certain table if you had stored them in a relational database.
Finally you can filter elements that have a location so you'd have a view where you can iterate over all those docs that still need a location and identify this in a separate process. The best documentation on writing view can be found here.

Item won't update in database

I'm writing a method to update several fields in multiple instances in my database. For now, I'm trying to get it to work just for one.
My user uploads a CSV file with all the information to change (including the pk). I've written the function that parses all the information, and this all works fine. I can even assign the data to an item, and if I print it from that function, it comes out correctly. However, when I save the updates (using item.save()) nothing seems to change in the database.
Here's a very stripped down version of the method. I really don't know why it isn't working. I've done something very similar in other spots (getting data through a form, setting the field, calling save, and then displaying the changed information), and I've used a very similar CSV uploading technique to create new entries.
Small piece of relevant code:
reader = csv.reader(f)
for row in reader:
pk = row[0]
print(pk)
item = POObject.objects.get(pk=pk)
p2 = item.purchase2
print item.purchase.requested_start_date
print p2.requested_start_date
requested_start_date=row[6]
requested_start_date = datetime.datetime.strptime(requested_start_date, "%d %b %y")
print requested_start_date
p2.requested_start_date = requested_start_date
p2.save()
print p2.requested_start_date
item.purchase2 = p2
item.save()
print item.purchase.requested_start_date
return pk
Obviously I have lots of prints in there to find where stuff went wrong. Basically what I find is that if I look at item, it looks fine, but if I query the server again (after saving) i.e. dong item2=POObject.objects.get(pk=pk) it won't have had any updates. Does anyone have any idea why save() isn't doing anything?
UPDATE:
The mystery continues.
If I update a field that isn't contained within an FK relation (say, a text field or something), everything seems to work fine. However, what I really need to do is update an item, and then set that item as the fk relation to the main item in question. I'm not sure why this isn't working in the normal way (updating the internal item, saving it, and then setting the fk to that new, updated item).
Whoa. Feel a little ashamed that I didn't figure this out. I had forgotten exactly how I had designed one of my models, and there was another object within it that needed to be updated, but I wasn't saving it.

processing form with multiple selection options

I have a cgi script that contains a select box where the end user can submit multiple options or only one option. This selection tag is named "parameters". See here for an example....
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select_multiple
When this form is submitted with multiple options selected the URL looks something like this...
http........mycgiscript.py?parameters=option1value&parameters=option2values
or if the user only selected one option it looks like this...
http........mycgiscript.py?parameters=option3value
My form is declared as...
import cgi
form = cgi.FieldStorage()
So when the user selects multiple options and submits the form, the data type of form['parameters'] is a list, however, when the user only selects one option and submits, the data type of form['parameters'] is an instance...
Multiple Options (returned as list):
[MiniFieldStorage('parameters', 'option1value'), MiniFieldStorage('parameters', 'option2value')]
Single Option (returned as instance):
MiniFieldStorage('parameters', 'option3value')
My question is....
Since the form['parameters'] can be a list or instance depending on what the user submits; what is the best way to process these two data types ? The output I want is a list variable containing the optionsXvalues selected on the form. So far the best I can do is this...
if type(form['parameters']) == type([]):
l = [ x.value for x in form['parameters'] ]
else:
l = [form['parameters'].value]
I've done it this way because simply using form['parameters'].value produces the following exception when the user selects multiple options.
AttributeError: 'list' object has no attribute 'value'
So is there a better way than my if/else statement based suggestion above? I was hoping some of you python guru's would be able to suggest a better way to do this.
What you could do is use:
form.getlist('parameters')
This provides the value of all the different input types with the same name, namely parameters.
This is what i gathered from http://docs.python.org/2/library/cgi.html in 20.2.2 where they suggest this is the case when you expect there could be multiple items with the same name field.
Hope this helps though i reckon you already found this yourself.

Categories