Odoo error: return self.models[model_name] KeyError: 'res_groups_users_rel' - python-2.7

I need to make UI many2one dopdown list where I can identify users which depend to Manager group role.
Now I have dropdown field:
test = fields.Many2one('res.groups', 'Purchase request type', default=_get_users, track_visibility='onchange')
And I tried to write a function which can identify all users which depend to manager group role.
def _get_users(self):
pickings = self.env['res_groups_users_rel'].search([('gid','=',61)])
pickings_available = []
for picking in pickings:
pickings_available.append(picking)
return pickings_available
And I got an error:
return self.models[model_name]
KeyError: 'res_groups_users_rel'
I don't know how can I change this function and get value from amy2many relation.
I changed my function to:
def _get_users(self):
pickings = self.env['res.groups'].browse(61).users
pickings_available = []
for picking in pickings:
pickings_available.append(picking)
return pickings_available
and field:
test = fields.Many2one('res.users', 'Some text', default=_get_users, track_visibility='onchange')
I logged function _get_users and get values: [res.users(9,), res.users(65,)]
But I still can't get these values on my test field dropdown. What I am doing wrong?

If you are trying to get all users that belong to a group, why not do the following:
self.env['res_groups'].browse(61).users
On a side note, you might get an error, trying to assign a list as default value to a Many2one field.
Also you seem to be assigning users belonging to a group to a field that is specified to store reference to groups.
If you need to have a field to select a user that belongs to group with id 61, you can do the following:
test = fields.Many2one('res.users', 'Some description', domain="[('groups_id', 'in', [61])]")

Related

`op_name` parameter for `graphene_django`

The django graphene documentation shows a test example like this:
class MyFancyTestCase(GraphQLTestCase):
def test_some_query(self):
response = self.query(
'''
query {
myModel {
id
name
}
}
''',
op_name='myModel'
)
content = json.loads(response.content)
# This validates the status code and if you get errors
self.assertResponseNoErrors(response)
# Add some more asserts if you like
...
They don't have any API documentation for what op_name is, and what we should set it as. I tried to set it to my query name, but get the error:
[{'message': 'Unknown operation named "myQuery".'}]
Operation name is only needed when there are multiple operations in the query string. You only have one operation so the default (None) is fine.
https://docs.graphene-python.org/en/latest/execution/execute/#operation-name
As per my comment:
If the query is a mutation or named query, you must supply the op_name. For annon queries ("{ ... }"), should be None (default)
I am not sure how to create a "named query" with django graphene, but apparently my query is NOT a named query. Leaving op_name as None got my query to work via my unit test.

Django get_or_create with icontains

I'm getting an unexpected result using icontains in my get_or_create call.
Take the following example:
>>>team_name = "Bears"
>>>Team.objects.get(name__icontains=team_name) # returns DoesNotExist as expected
>>>team, created = Team.objects.get_or_create(name__icontains=team_name)
>>>print(created) # Prints True as expected
>>>print(team.name) # Prints an empty string!
Why does this create a team with a blank name rather than "Bears"? The reason I'm using get_or_create here is that if a subsequent user posts something like "BearS" I want to get the correct team, not create a duplicate team with incorrect capitalization.
I think here you should split the get() and create() functionalities instead of using get_or_create(), because the __icontains lookup works for get() only.
Try doing something like this:
>>> team_name = 'Bears'
>>> teams = Team.objects.filter(name__icontains=team_name)
# This will filter the teams with this name
>>> team = teams.first() if teams.exists() else Team.objects.create(name=team_name)
# Now your team is the first element of your previous query (it returns a QuerySet with single element) if it exists
# Otherwise, you create a new Team.
Another option besides wencakisa's answer is to include the defaults parameter in get_or_create, because Django strips lookups containing the __ separator. See answers to this question.
The code would be:
Team.objects.get_or_create(
name__icontains=team_name,
defaults = {
"name": team_name
}
)
The right way to do it is using Django's function get_or_create(). But instead of "icontains", you should use "iexact" (), unless you want an exact match, in wich case you should use just "exact":
Team.objects.get_or_create(
name__iexact=team_name,
defaults = {
"name": team_name
}
)
Outside "defaults" you should put your search terms. If the objects doesn't exist, you should write your creation terms inside 'defaults'

What happen if I try to evaluate non-existing property of entries?(Datastore, Python)

I am making a web app using GAE datastore and need to update model schema. Currently, I have model like this.
class Group(db.Model):
name = db.StringProperty()
div = db.StringProperty()
But I want to add mid property with default value.
class Group(db.Model):
name = db.StringProperty()
div = db.StringProperty()
mid = db.IntegerProperty(default=0)
I understand this won't update existing entries reading through this article.
https://cloud.google.com/appengine/articles/update_schema
It is ok for me existing entries stay without mid property because I will not use this property for query. But I need to use this to assert the situation. If I retrieved all the entries from datastore and evaluate mid property, does this result in AttributeError or something?
groups = [e for e in Group.all()]
for group in groups:
if group.mid == 3:
dosomething...
If attribute error will happen, is there any to avoid the error? I am a bit expecting this might not result in error since I set a default value....
You could try this,
groups = [e for e in Group.all()]
for group in groups:
try:
if group.mid == 3:
#do_your_thing...
except: #or except AttributeError
pass

Adding new line on a one2many computed field with inverse odoo

I have a one2many computed field which i also want users to be able to add new line of records into. i added an inverse field to it, but the only thing it does is to allow already existing records to be modified
#api.one
def accumulate_files(self):
documents = self.env['document.customer']
document_gotten = documents.search([('name','=', self.name)])
for docs in document_gotten:
self.res_line_ids |= docs.customer_line_ids
#api.one
def edit_accumulate_files(self):
documents = self.env['document.customer']
for lines in documents.customer_line_ids:
lines.write(self.res_line_ids)
I did a workaround, not sure how can I get values of one2many field in inverse method, in new api, like it was in old api. however it works for me
#api.multi
def _save_telefone(self):
for partner in self:
for phone in partner.phone_number_ids:
try:
# write on exisiting record
int(phone.id)
# write all possible values
phone.write({'partner_id': partner.id})
except:
# create new record with all possible values
phone.create({
'partner_id': partner.id,
'type_id': phone.type_id.id,
'status_id': phone.status_id.id,
'sequence': phone.sequence,
'graph_value': phone.graph_value,
'name': phone.name,
})
return True
Basically, create a record if it doesn't exist otherwise write on it.
how to know if record exists in DB? if the ID is integer it already
exists, otherwise it will have ID something like "odoo.model.NewID"
that means ID hasn't been assigned yet record is in memory yet.

Wizard input - DB View - Dynamic where clause

I was trying to pass where condition values onto a database view.
View was created in init method of class defined.
Input to where clause was taken from a popped up wizard.
Issue is that the wizard form values are inserted into model bound database table.
This is happening on all submits.
Currently I am reading the latest record from table on wizard input.
And the view definition is modified to generate result set based on latest input record from wizard table.
select v.col1, v.expre2
from view_name v,
( select fld1, fld2 from wizrd_tbl_1 order by id desc limit 1 ) as w
where
v.colM between w.fld1 and w.fld2
Currently I am following the above sequence of steps and results are fetched.
But I think, this would fail if at least two users are using the same wizard concurrently.
How can I change my approach, so that
1. Wizard input is not sent to database table,
2. The inputs are sent to a where clause dynamically and the result set is bound to a List View
As a summary, I was trying to:
Creates a database view joining multiple table.
Take user input ( and saves in db table, which is not expected and
not required ).
Pass the user input to db view's where clause. ( Any alternative to wizard ? )
Bind the result set to List View
It is definitely a bad idea to morph a database view based on user input, when that view is likely to be accessed by multiple users.
The 'correct' way to do this would be to have a static database view which contains all possible records from the joined tables, and then filter that data for individual users by generating a "domain" and redirecting the user to a tree view with that domain applied.
You can redirect the user by creating a <button type="object"> which calls a function such as the below:
def action_get_results(self, cr, uid, ids, context={}):
# Redirect user to results
my_domain = ['&', ('col1','=','testval'), ('col2','>',33)]
return {
'type': 'ir.actions.act_window',
'name': 'Search Results',
'view_mode': 'tree',
'res_model': 'your.osv_memory.model.name',
'target': 'new', # or 'current'
'context': context,
'domain': my_domain,
}