I got this code in default.py :
form_0 = SQLFORM(db.base_folder, record=db.base_folder(1))
query = db.base_folder.folder != ''
set = db(query)
rows = set.select()
if rows:
form_0.vars.folder = rows[0]['folder']
and in db.py :
db.define_table(
'base_folder',
Field('folder',
type='string',
default='You need to set up a directory to backup to !',
),
format='%(folder)s'
)
and unfortunately, the form displayed, displays also :
id: 1
above the field value. This issue disappears when I omit the record option.
How could I avoid that behavior please - as I need to keep the update
function ?
Thank you,
SQLFORM(db.base_folder, record=db.base_folder(1), showid=False)
Related
With our team, we would like to implement a feature where the user is warned whenever the record he/she is updating have also been updated by one of his collegue since he/she opened the record.
We dug into the source code because we did not find any official documentation, only some module that did not fit our Odoo version (11).
We found in the file /odoo/odoo/models.py the method def _check_concurrency(self): with the following code:
#api.multi
def _check_concurrency(self):
if not (self._log_access and self._context.get(self.CONCURRENCY_CHECK_FIELD)):
return
check_clause = "(id = %s AND %s < COALESCE(write_date, create_date, (now() at time zone 'UTC'))::timestamp)"
for sub_ids in self._cr.split_for_in_conditions(self.ids):
nclauses = 0
params = []
for id in sub_ids:
id_ref = "%s,%s" % (self._name, id)
update_date = self._context[self.CONCURRENCY_CHECK_FIELD].pop(id_ref, None)
if update_date:
nclauses += 1
params.extend([id, update_date])
if not nclauses:
continue
query = "SELECT id FROM %s WHERE %s" % (self._table, " OR ".join([check_clause] * nclauses))
self._cr.execute(query, tuple(params))
res = self._cr.fetchone()
if res:
# mention the first one only to keep the error message readable
raise ValidationError(_('A document was modified since you last viewed it (%s:%d)') % (self._description, res[0]))
=> This method is called before any "write". It compares :
the __last_update value of the record at the time of write
with a value of __last_update get from the context, which therefore should have been set in the context beforehand
PROBLEM
We did not find anywhere in the code (python or javascript) the value set in the context => NOTHING HAPPENS ! THe function returns from the beginning.
When we tried to hardcode it in the context, the function check_concurrency seems to work properly.
QUESTION
Does anyone one know where the __last_update is set or SHOULD BE set in the context ? And how ?
I would e.g. imagine setting it somehow when clicking on edit button of a record ??? Or at read time ??
CONCURRENCY_CHECK_FIELD = '__last_update'
concurrency field is a dynamic field which computing method defined dynamically and also you can see this is updated by
last_modified_name = 'compute_concurrency_field_with_access' or last_modified_name = 'compute_concurrency_field' according to access and later added to the class. Following functions will take part in the workaround.
#api.model
def _add_magic_fields(self):
""" Introduce magic fields on the current class
* id is a "normal" field (with a specific getter)
* create_uid, create_date, write_uid and write_date have become
"normal" fields
* $CONCURRENCY_CHECK_FIELD is a computed field with its computing
method defined dynamically. Uses ``str(datetime.datetime.utcnow())``
to get the same structure as the previous
``(now() at time zone 'UTC')::timestamp``::
# select (now() at time zone 'UTC')::timestamp;
timezone
----------------------------
2013-06-18 08:30:37.292809
>>> str(datetime.datetime.utcnow())
'2013-06-18 08:31:32.821177'
"""
def add(name, field):
""" add ``field`` with the given ``name`` if it does not exist yet """
if name not in self._fields:
self._add_field(name, field)
# cyclic import
from . import fields
# this field 'id' must override any other column or field
self._add_field('id', fields.Id(automatic=True))
add('display_name', fields.Char(string='Display Name', automatic=True,
compute='_compute_display_name'))
if self._log_access:
add('create_uid', fields.Many2one('res.users', string='Created by', automatic=True))
add('create_date', fields.Datetime(string='Created on', automatic=True))
add('write_uid', fields.Many2one('res.users', string='Last Updated by', automatic=True))
add('write_date', fields.Datetime(string='Last Updated on', automatic=True))
last_modified_name = 'compute_concurrency_field_with_access'
else:
last_modified_name = 'compute_concurrency_field'
# this field must override any other column or field
self._add_field(self.CONCURRENCY_CHECK_FIELD, fields.Datetime(
string='Last Modified on', compute=last_modified_name, automatic=True))
def compute_concurrency_field(self):
for record in self:
record[self.CONCURRENCY_CHECK_FIELD] = odoo.fields.Datetime.now()
#api.depends('create_date', 'write_date')
def compute_concurrency_field_with_access(self):
for record in self:
record[self.CONCURRENCY_CHECK_FIELD] = \
record.write_date or record.create_date or odoo.fields.Datetime.now()
I'm trying to make this table with a clickable field which changes the boolean for the entry to its opposite value. It works, but I want an alternative text as "False" or "True" does not look nice, and the users are mainly Norwegian.
def bool_to_norwegian(boolean):
if boolean:
return "Ja"
else:
return "Nei"
class OrderTable(tables.Table):
id = tables.LinkColumn('admin_detail', args=[A('id')])
name = tables.Column()
address = tables.Column()
order = tables.Column()
order_placed_at = tables.DateTimeColumn()
order_delivery_at = tables.DateColumn()
price = tables.Column()
comment = tables.Column()
sent = tables.LinkColumn('status_sent', args=[A('id')])
paid = tables.LinkColumn('status_paid', args=[A('id')], text=[A('paid')])
class Meta:
attrs = {'class': 'order-table'}
If you look under the "paid" entry I am testing this right now, why can't I access the data with the same accessor as I do in the args? If I change the args to args=[A('paid')] and look at the link, it does indeed have the correct data on it. The model names are the same as the ones in this table, and "paid" and "sent" are BooleanFields.
This is kind of what I ultimately want:
text=bool_to_norwegian([A('paid')])
Here is what I send to the table:
orders = Order.objects.order_by("-order_delivery_at")
orders = orders.values()
table = OrderTable(orders)
RequestConfig(request).configure(table)
The text argument expects a callable that accepts a record, and returns a text value. You are passing it a list (which it will just ignore), and your function is expecting a boolean instead of a record. There is also no need for using accessors here.
Something like this should work:
def bool_to_norwegian(record):
if record.paid:
return "Ja"
else:
return "Nei"
Then in your column:
paid = tables.LinkColumn('status_paid', text=bool_to_norwegian)
(Note, it is not clear from your question where the data is coming from - is paid a boolean? You may need to adjust this to fit).
As an aside, the way you are passing args to your columns is weird (it seems the documentation also recommends this, but I don't understand why - it's very confusing). A more standard approach would be:
id = tables.LinkColumn('admin_detail', A('id'))
or using named arguments:
id = tables.LinkColumn('admin_detail', accessor=A('id'))
I have HTML form with one optional field like this
<input type="number" name="total_amount" id="total_amount" class="completedtype" onchange="add()"/>
When I input some number in the field then I the whole form data gets saved in to the database. But when there is no data then I get Validation Error
ValidationError at /oms_data/ [u"'' value must be a decimal number."]
I have tried to resolve this issue for more than half a day but nothing helped me. I have tried the following to resolve this error.
I have used something like this which was suggested in some SO answer:
total_amount = request.POST.get("total_amount",0) ## get total_amount or take default value 0
That didn't work so I used the famous try: except: as shown below:
try:
total_amount = request.POST["total_amount"]
except: ## whatever the exception and not just Validation Error
total_amount = 0
I don't know why none of this worked.The error occurs when trying to save the form.
save_Order_Selling_Pricing = models.Order_Selling_Pricing(order_id=order_id,vendor_name = vendor_name,total_amount =total_amount,
vendor_discount_percent=vendor_discount_percent,dg_percent = dg_percent,
vendor_discount_amount=vendor_discount_amount,vendor_percent = vendor_percent,
dg_discount_percent = dg_discount_percent,dg_discount_amount=dg_discount_amount,
final_selling_price = final_selling_price,order_selling_pricing_id=order_selling_pricing_id,
order_payment_mode = order_payment_mode,present_datetime=present_datetime)
save_Order_Selling_Pricing.save()
Any help in this regard would be great!
Thanks in advance! I'm using Django 1.8 python 2.7 if this helps.
UPDATE 1:
I have my models defined as shown below:
total_amount = models.DecimalField(max_digits=10,decimal_places=2,blank = True,null = True,default = Decimal('0.00'))
I have a very simple "guestbook" script on GAE/Python. It often happens however, that entries which I put() into the datastore are not showing right away - I almost always need to refresh.
def post(self):
t = NewsBase(
date = datetime.now(),
text = self.request.get('text'),
title = self.request.get('title'),
link = self.request.get('link'),
upvotes = [],
downvotes = [],
)
t.put()
q = db.GqlQuery('SELECT * FROM NewsBase ORDER BY date DESC')
template_values = {
'q' : q,
'user' : user,
'search' : search
}
template = jinja_environment.get_template('finaggnews.html')
self.response.out.write(template.render(template_values))
I'm sure there is a solution to this?
Best,
Oliver
This is due to the eventual consistency model of HRD.
You should really read some of the intro docs, Structuring Data for Strong Consistency - https://developers.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency and do some searching of SO. This question has been asked many times before.
con = pymongo.Connection(MONGO_DOC_HOST, MONGO_DOC_PORT)
db = con.testdb
datasets = db.datasets
for post in db.datasets.find({"test_set":"xyz"}).sort("num_favs",pymongo.DESCENDING).limit(2):
print post #this works, and it prints fine!
post = {"hi":"abc"}
mongo_id = datasets.insert(post)
When I do datasets.insert, and print out the mongo_id. The id prints!
However, when I do: db.datasets.find().count() in the mongo console, the count is still the same...
Weird. When I do this in console..I get this error:
> db.datasets.insert({"gooder":"absdlk"})
E11000 duplicate key error index: fabletest.datasets.$flickr_original_1 dup key: { : null }
That's weird, I didn't index "gooder" at all.
are you definitely hitting the same database ("testdb") in both cases?
the default db in the shell is "test"