Dynamic domain apply while other field's value changed - odoo - odoo-8

class procurement(models.Model)
_name="procurement"
procurement_line_ids = fields.One2many(comodel_name='procurement.line', inverse_name='procurement_id', string='Procurement Lines')
global_procurement = fields.Boolean("Global Procurement",default=True)
class procurement_line(models.Model)
_name="procurement.line"
procurement_id = fields.Many2one(comodel_name='procurement', string='Procurement')
warehouse_id = fields.Many2one(comodel_name='stock.warehouse', string='Warehouse')
class stock_warehouse(models.Model)
_name="stock.warehouse"
is_default_warehouse = fields.Boolean(string="Is Default Warehouse?",default=False)
If global_procurement is True then I want to load only default warehouses in procurement lines otherwise I want to load all warehouses. So how could I do this.

We may try with following way.
Pass value in context. For example:
<field name="warehouse_id"
context="{'global_procurement': parent.global_procurement}"/>
Check context value name_search() of stock.warehouse object. For example:
#api.model
def name_search(self, name, args=None, operator='ilike', limit=100):
if self._context and self._context.get('global_procurement'):
default_list = [1,2,3] # set your logic to search list of default warehouse
return self.browse(default_list).name_get()
return super(Warehouse, self).name_search(name=name, args=new_args, operator=operator, limit=limit)
I have written answer in air. I didn't try it.

I have done it by just defining domain in field (idea is taken from then #Odedra's answer).
<field name="warehouse_id" required="1" domain="[('field_name','=',parent.global_procurement)]" options="{'no_create': True, 'no_quick_create':True, 'no_create_edit':True}" />

Related

How to get word2index from gensim

By doc we can use this to read a word2vec model with genism
model = KeyedVectors.load_word2vec_format('word2vec.50d.txt', binary=False)
This is an index-to-word mapping, that is, e.g., model.index2word[2], how to derive an inverted mapping (word-to-index) based on this?
The mappings from word-to-index are in the KeyedVectors vocab property, a dictionary with objects that include an index property.
For example:
word = "whatever" # for any word in model
i = model.vocab[word].index
model.index2word[i] == word # will be true
Even simpler solution would be to enumerate index2word
word2index = {token: token_index for token_index, token in enumerate(w2v.index2word)}
word2index['hi'] == 30308 # True

How can I compare strings case sensitive in xforms:select1 ref attribute?

I have to provide the ref attribute value in an xf:select1. I need to select names of properties only if they are present in the supportedProperties instance which can be done with the following:
<xf:select1
ref="
instance('properties')/property[
name = instance('supportedProperties')/property/name
]/name">
However, the problem is that supportedProperties can contain names which are in capital letters. Assuming we cannot change the instance, is there a way we can do a case sensitive comparison?
Tried to use the lower-case() XPath function as follows but it didn't work:
<xf:select1
ref="
instance('properties')/property[
name = instance('supportedProperties')/property/name
]/lower-case(name)">
Assuming you are using XPath 2, you can write:
<xf:select1
ref="
instance('properties')/property[
name = instance('supportedProperties')/property/name/lower-case(.)
]/name">
What this does is that the lower-case(.) function applies to all elements in the sequence returned by instance('supportedProperties')/property/name.
You can also write it:
<xf:select1
ref="
instance('properties')/property[
name = (
for $name in instance('supportedProperties')/property/name
return lower-case($name)
)
]/name">

Is Django REST Framework's HyperlinkedRelatedField unable to reference url patterns with multiple kwargs?

I have a REST api url endpoint that represents a Song within an Album:
/api/album/(?P<album_id>)/song/(?P<id>)/
and I want to refer to it from another resource, e.g. Chart that contains Top-1000 songs ever. Here's an implementation of ChartSerializer:
class ChartSerializer(HyperlinkedModelSerializer):
songs = HyperlinkedRelatedField(
queryset=Song.objects.all(),
view_name='api:song-detail',
lookup_field='id'
)
class Meta:
model = Chart
fields = ('songs', )
Clearly, I can pass id as lookup_field, but it seems to me that I won't be able to pass album_id by any means. I'm looking into HyperlinkedModelSerializer.get_url() method:
def get_url(self, obj, view_name, request, format):
"""
Given an object, return the URL that hyperlinks to the object.
May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
attributes are not configured to correctly match the URL conf.
"""
# Unsaved objects will not yet have a valid URL.
if hasattr(obj, 'pk') and obj.pk in (None, ''):
return None
lookup_value = getattr(obj, self.lookup_field)
kwargs = {self.lookup_url_kwarg: lookup_value}
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
As you can see, it constructs kwargs for reverse url lookup from scratch and doesn't allow to pass additional parameters to it. Am I right that this is not supported?
UPDATE:
Found a reference to this problem in the issue list of DRF: https://github.com/tomchristie/django-rest-framework/issues/3204
So, the answer is YES. There is even a paragraph about this issue in the DRF documentation:
http://www.django-rest-framework.org/api-guide/relations/#custom-hyperlinked-fields

Getting model value and generated ID from within simple_form custom input

I'm trying to make a custom input type with simple_form that will implement combobox-type functionality using jQuery-Autocomplete
. What I need to do is output a hidden field that will hold the ID of the value selected and a text field for the user to type in.
Here's what I have so far:
class ComboboxInput < SimpleForm::Inputs::Base
def input
html = #builder.hidden_field(attribute_name, input_html_options)
id = '' #what?
value = '' #what?
return "#{html}<input class='combobox-entry' data-id-input='#{id}' value='#{value}'".html_safe
end
end
I need to get the ID of the hidden field that simple_form is generating to place as an HTML attribute on the text entry to allow the JavaScript to "hook up" the two fields. I also need to get the value from the model to prepopulate the text input. How do I do this from within my custom input?
I'm looking for the id as well, but I did get the value:
def input
current_value = object.send("#{attribute_name}")
end
I just found a hokey id workaround:
html = #builder.hidden_field(attribute_name, input_html_options)
id = html.scan(/id="([^"]*)"/).first.first.to_s
I know it's a hack, but it does work. Since we don't have access directly to this type of resolution, it is likely to keep working even if the underlying id creation code changes.

How to get django ModelForm to not clean a ManyToManyField before running clean_ for that field?

class MyModel(models.Model) :
people = models.ManyToManyField(User,related_name='people')
...
class MyForm(ModelForm) :
class Meta :
model = MyModel
widgets = {'people':TextInput(),}
def clean_people(self) :
# turn a comma-separated list of names into a Python list
return [name0,name1,...]
def clean(self) :
# if no other errors, turn list of names into list of Users
This doesn't work, because clean_people doesn't get called before field.clean gets called, where field is an instance of ModelMultipleChoiceField, which checks for a Python list or tuple and so raises a ValidationError and skips clean_people.
Is there a reason why the order of calls is the way it is, and is there some standard provision for avoiding this problem? I could set field.clean to lambda x:x in each instance of MyForm, but that seems really ugly. Is perhaps the right thing to do to explicitly define the people field in MyForm as a CharField ?
why don't you override clean's behaviour?
class MyForm(ModelForm):
class Meta:
model = MyModel
widgets = {'people':TextInput(),}
def clean_people(self):
# turn a comma-separated list of names into a Python list
return [name0,name1,...]
# override below!
def clean(self):
super(MyForm, self).clean()
# do stuff you need, eg: call clean_people(self)
return self.cleaned_data
I'm not sure I understood your problem 100%, but just by defining clean_people() before clean() doesn't mean that's going to be called before, or even called at all.
It seems that the right? thing is to define the people field in the form, overriding the model's idea of that field
class MyModel(models.Model) :
people = models.ManyToManyField(User,related_name='people')
...
class MyForm(ModelForm):
people = CharField(...)
class Meta :
model = MyModel
def clean_people(self) :
# turn a comma-separated list of names into a Python list
return [name0,name1,...]
def clean(self) :
# if no other errors, turn list of names into list of Users

Resources