Django: how to assign a RawQuerySet to a Selectfield in forms - sql

In a lot of situations I add a custom queryset to a selectfield in django form.
form.fields[fieldname] = model.objects.all()
Now I have a selectfield where I need to assign as choices the result of a RawQueryset.
I tried this (queryset is simplified):
sql = "SELECT * FROM table WHERE value = %s"
param.append (1234)
qs = model.objects.raw (sql, param)
form.fields[fieldname] = qs
The page is correctly displayed and the select field contains the data from the queryset.
When I try to save the form, form validation (form.is_valid()) throws the error:
*** Attribut error: 'RawQuerySet' object has no attribut 'get'
How can I fix this?
Thanks

You cannot assign a queryset to a form field, like this:
# this is wrong
form.fields[fieldname] = qs
you need to define the field using one of the fields django has, like:
form.fields[fieldname] = forms.ModelChoiceField(queryset=qs)
django doc.

Related

How to update/ delete a key from a context in Odoo 10?

Hi i am trying to delete a key value from the context for res.partner form view.
I opening the partner form view using controller function and trying to set phone number as default and its working fine. But when i try to create a new customer by clicking on the create button the phone number again auto-filled. In order to avoid this behaviour, in default_get function, i copied the context into another variable, removed the key value from the context using del context['cc_mobile']. And reassigned to self.env.context. But when i try to create a new customer, the deleted key value comes in the context again.
Controller.py
#http.route('/open_customer/<string:val>', type="http",method=['POST','GET'],website=False, auth="public")
def open_case_window(self,**kw):
mobile_no = kw.get('val')
action = request.env.ref('base.action_partner_form').sudo()
mobile_flag = 0
partner = 'res.partner'
partner_model = request.env[partner]
regex = re.match( '^(?:\01|02|03|04|06|07|09)\d*$', mobile_no)
if regex:
mobile_flag = 0
partner_id = partner_model.search([('phone', '=', mobile_no)]).id
else:
mobile_flag = 1
partner_id = partner_model.search([('mobile','=',mobile_no)]).id
if partner_id:
return werkzeug.utils.redirect('/web#id='+str(partner_id)+'&view_type=form&model='+partner)
else:
context = dict(action._context)
if mobile_flag == 0:
context.update({'cc_phone': mobile_no})
else:
context.update({'cc_mobile': mobile_no})
context.pop('lang')
url = werkzeug.utils.redirect('/web?debug=#view_type=form&model='+str(partner)+'&action=%s'%(action.id))
return url
ResPartner.py
#api.model
def default_get(self, fields):
context = self.env.context.copy()
print'default_get context',context
res = super(Partner, self).default_get(fields)
if 'cc_mobile' in context:
res.update({'mobile':context.get('cc_mobile')})
if 'cc_phone' in context:
res.update({'phone':context.get('cc_phone')})
if context.get('cc_mobile'):
del context['cc_mobile']
if context.get('cc_phone'):
del context['cc_phone']
self.env.context = context
print'self.env.context after',self.env.context
action = self.env.ref('base.action_partner_form').sudo()
action.env.context = self.env.context
return res
You cannot remove a key of action context from python side, because it's in the client side. when ever you call the server like search in many2one field, create a record in fly you will see this context comeback again every time (The way Odoo work).
What you need is something that will be used for one time, I think you need some kind of persistence for example:
dummy model that contains user_id, model_name, value, active fields so in the controller you create a record for default value for that specific user.
get that value by overriding default_get by searching with user_id and model_name field and hide that value or delete it.
this way when yo hit create button or create contact in fly when you search for the value it will be gone so it will not be used a second time.
This a simple Idea and easy to implement, you need to handle some cases to prevent user from saving two default value if some interruption happens should not be hard.
Edit
After second thought to prevent any error when you create a record just pass it's ID in the context with a special key, then use That Id to retrieve it, use it then delete it. easier, safer and no need for search.

How to update a Podio category using PHP API

I'm using a webhook to kick off a series of PHP scripts that take advantage of the Podio PHP API. I've tried using several different API calls but haven't been able to sort this out. This is a test file I'm using so the actual logic of what its doing doesn't make much sense. When I run the code below I get the error.
PHP Fatal error: Uncaught PodioBadRequestError: "Invalid value "status" (string): Not a valid option"
Request URL: http://api.podio.com/item/<removed>/value/<removed>
Stack Trace:
/data/www/default/contracts/lib/podio-php-master/lib/Podio.php(357):
Podio::request('PUT', '/item/<removed>...', Array)
/data/www/default/contracts/lib/podio-php-master/models/PodioItemField.php(55): Podio::put('/item/<removed>...', Array)
/data/www/default/contracts/test-category.php(25):
PodioItemField::update(<removed>, <removed>, Array, Array)
{main}
thrown in /data/www/default/contracts/lib/podio-php-master/lib/Podio.php on line 291`
Here is my code:
//dummy item_id
$item_id = 123456789;
//dummy field_id
$field_id = 987654321;
//Get the category field value
$item = PodioItem::get_field_value($item_id, $field_id);
//Create a variable with the text of the selected category option for validation
$button_value = $item[0]['value']['text'];
//Print the text of the selected option
print $button_value;
//Now that I have validated the current selection I want to change it
//These are the names of the attributes for my category
$my_attributes = array("status", "text", "id", "color");
//These are the values I want to update them to
$my_options = array("active","Generated",21,"DCEBD8");
//This should update the record in podio with the new values
PodioItemField::update($item_id, $field_id, $my_attributes, $my_options);
I reviewed all of the examples in the documentation but I feel like I'm missing something simple. Is anyone familiar with this that can tell me what I'm doing wrong? I've tried to comment the code to make it clear what I expect to be happing on each line but I can definitely clarify more if needed.
You are passing the attributes in the wrong method. To update the Category field you just pass the id of the option that you want to change in an array. So the $my_attributes array must be like,
$my_attributes = array(21);//id of the category option
And the $my_options array should like this,
$my_options = array('silent' => true, 'hook' => false);
This should update the item in Podio with the new values,
PodioItemField::update($item_id, $field_id, $my_attributes, $my_options);

Default values for query parameters

Please forgive me if my question does not make sense.
What im trying to do is to inject in values for query parameters
GET1 File
Scenario:
Given path 'search'
And param filter[id] = id (default value or variable from another feature file)
POST1 File
Scenario:
def newid = new id made by a post call
def checkid = read call(GET1) {id : newid}
like if one of my feature files creates a new id then i want to do a get call with the above scenario. therefore i need a parameter there which takes in the new id.
On the other hand if i do not have an id newly created or the test creating it is not part of the suite. i want to still be able to run the above mentioned scenario but this time it has a default value to it.
Instead of param use params. It is designed so that any keys with null values are ignored.
After the null is set on the first line below, you can make a call to another feature, and overwrite the value of criteria. If it still is null, no params will be set.
* def criteria = null
Given path 'search'
And params { filter: '#(criteria)' }
There are multiple other ways to do this, also refer to this set of examples for data-driven search params: dynamic-params.feature
The doc on conditional logic may also give you some ideas.

Attribute Error when getting unique column values

I am new to Python and Pandas. I am trying to write a function to get a unique list of my column values. My function looks like below, where "placename" is the attribute that I want to get unique values. 'placename' should be passed as a string argument,corresponding to the header of the csv file.
def get_city_list(state, type, placename):
city_dir = os.path.join(baseDir, type + ".csv")
city_df = pd.read_csv(city_dir, quotechar = '"', skipinitialspace = True, sep = ",")
state_df = city_df.loc[city_df["state"] == state]
city_list = state_df.placename.unique()
return city_list
However, when I call this function, it throws a attribute error saying 'DataFrame' object has no attribute "placename". It seems that "placename" should not be a string, and when I substitute it as
city_list = state_df.cityname.unique(), it works, where cityname (without " ") is the actual header of the column in the original csv file. Since I want to make my function versatile,I want to find a way to deal with this case so that I dont have to manually change the content of "placename" every time.
Your help is greatly appreciated!
Thanks
The dot operator . is reserved to access attributes of an object. pandas is nice enough to make column names accessible via an attribute. But you can't do something like df."myplace"
Change your code to:
state_df[placename].unique()
This way, you are passing placename on to the getitem method.

List Members based on extended profile fields in buddypress

I'm working on getting a list of members based on the fields they selected on the extended profiles fields in buddypress. Here is my code:
<?php
$membership_group = "Orange Membership";
$db_query = "SELECT user_id FROM wp_bp_xprofile_data WHERE field_id = 33 AND value = \"" .$membership_group ."\"";
$match_ids = $wpdb->get_var($db_query);
$get_these_members = 'include=' .$match_ids;
if (bp_has_members($get_these_members, 'per_page optional=9')) {
//Some Codes here
}
?>
The result is returning just the first member it gets from the query instead of a list of members. Please say what I'm doing wrong.
Thanks
I think you should dive into the class BP_Core_User and its method get_users. It supports meta_key and meta_value.
You can also try to make just a search by field value. So pass an argument s to bp_has_members.
And per_page optional=9 is a wrong syntax.
This:
$wpdb->get_var($db_query);
returns a single var !
This is what you want:
$wpdb->get_col($db_query);
Then fix the syntax error mentioned by slaFFik