I am trying this form a while. I have a page which displays a form and whose databse definition looks like:
db.define_table('nskrelease',
Field('sprid',length=128,requires=IS_IN_SET(['R3.2', 'R3.3', 'R3.4'],zero=T('choose one'),error_message='must be R3.2 or R3.3 or R3.4 '),label = T('SPR')),
Field('releaseid',length=128, requires = IS_NOT_EMPTY(error_message='Release ID cant be empty'),label = T('Release')),
Field('coordinator',requires=IS_EMAIL(error_message='invalid email!') ,label=T('Co-ordinator Email')),
Field('startdate', 'datetime', default=request.now,requires = IS_NOT_EMPTY(error_message='Start date cant be empty'), label=T('Start date')),
Field('enddate', 'datetime', default=request.now, requires = IS_NOT_EMPTY(error_message='End date cant be empty'), label=T('End Date')),format='%(%releaseid)s')
db.nskrelease.releaseid.requires = IS_NOT_IN_DB(db,'nskrelease.releaseid')
db.nskrelease.coordinator.requires = IS_IN_DB(db,'auth_user.email','%(email)s')
But the problem here is the Coordinator field displays all the user in present in db.auth_user. Instead i need that to be restricted only to the Logged in user. So I tried:
db.nskrelease.coordinator.requires = IS_IN_DB(db(db.nskrelease.coordinator == 'auth.user.email'))
But it gives me error:
TypeError: __init__() takes at least 3 arguments (2 given)
Please help. Thanks in advance.
If the only email address allowed in this field is that of the currently logged in user, then maybe just set that as the default value and don't make the field writable:
Field('coordinator', writable=False,
default=auth.user.email if auth.user else None,
update=auth.user.email if auth.user else None)
However, a better approach might be to make this a reference field, so you don't have to worry about updating this field whenever there is a profile update:
Field('coordinator', 'reference auth_user', writable=False,
default=auth.user_id, represent=lambda v, r: v.email)
Related
This is my UI
End user can able to update Summary or my_story one at a time, This is my endpoint URL http:localhost:3000/api/account/profile, once user update any one of the field, the URL will work
This is Request payload for summary field
If the user update the Summary field the above endpoint URL will work.
This is Request payload for my_story field
If the user update the my_story field the above endpoint URL will work.
My code(Once the user update anyone of the field. I want to check which field is updated, for this how can I check whether the user is updated Summary or my_story,after accessing the field I want to sanitize the field and send it to response below one is my code):
from lxml.html import clean
def account_update():
data = json.loads(request.data)
cleaner = clean.Cleaner()
if data['other_details']['summary']:
clean_overview = (data['other_details']['summary'])
sanitized_html = cleaner.clean_html(clean_overview)
else:
clean_overview = (data['other_details']['my_story'])
sanitized_html = cleaner.clean_html(clean_overview)
return jsonify({"account": data})
Guys , in the above code I am getting the request payload as data, after that I am accessing the summary and my_story fields as data['other_details']['summary'] and data['other_details']['summary'], here I wrote if condition to check if the user update summary field if condition will work suppose user update my_story field it will goes to else part, but in my case if I update my_story field getting error.
Error:
if data['other_details']['summary']:
KeyError: 'summary'
NOTE:
Sanitizing the field is working fine (I mean cleaner = clean.Cleaner() and sanitized_html = cleaner.clean_html(clean_overview), I just want to know which field the user is updating. Please help me guys.
Most likely, the request.data doesn't always have the summary field in data['other_details'].
This means, you have to check for it in you if-else block before trying to access it.
Best to check for other_details as well.
Here is one way of doing this:
from lxml.html import clean
def account_update():
data = json.loads(request.data)
cleaner = clean.Cleaner()
if 'other_details' in data:
other_details = data['other_details']
if 'summary' in other_details:
clean_overview = other_details['summary']
sanitized_html = cleaner.clean_html(clean_overview)
elif 'my_story' in other_details:
clean_overview = other_details['my_story']
sanitized_html = cleaner.clean_html(clean_overview)
return jsonify({"account": data})
What i see your program just can't find summary atribute.
Solution 1
Im not sure this will work but function getattr() can help you.
Change this line
data['other_details']['summary']
To this
getattr(getattr(data,'other_details'),'summary', False)
Here you can learn more about getattr()
What is getattr() exactly and how do I use it?
Solution 2
Just use some try: and except:
I'm super new in development in general. I'm currently building a webapp that get data from Rally/CA Agile Central and put them in a neat table.
My code:
response = rally.get('UserStory', fetch = True, query=query_criteria)
response_defect = rally.get('Defect', fetch = True, query=query_criteria)
story_list = []
if not response.errors:
for story in response:
#print (story.details())
a_story={}
#a_story['State'] = story.State.Name #if story.State else "Backlog"
a_story['State']=story.BusOpsKanban if story.BusOpsKanban else "unassigned"
#a_story['Status']=Story.Status if story.Status else "unassigned"
a_story['id'] = story.FormattedID
a_story['name'] = story.Name
a_story['Opened']=(datetime.strptime(story.CreationDate, '%Y-%m-%dT%H:%M:%S.%fZ').strftime('%Y-%d-%b'))
a_story['Requester']= story.Owner.Name if story.Owner else "unassigned"
a_story['Blocked']= story.Blocked
a_story['Service']=story.c_ServiceNowID
My issue is to get access to the value of the linkid of my customfield (c_ServiceNowID).
When I run a Dict = I see that I have LinkID attributes but when I type
story.c_ServiceNowID.LinkID, I receive an error message telling me there is no such attributes.... How do I access this value using python ?
Thank you
According to the documentation at http://pyral.readthedocs.io/en/latest/overview.html#custom-fields, pyral allows you to reference the field without the c_ prefix
Most Artifact types in Rally can be augmented with custom fields. As of Rally WSAPI v2.0, the ElementName for a custom field is prefixed with ‘c_’. The pyral toolkit allows you to reference these fields without having to use the ‘c_’ prefix. For example, if your custom field has a DisplayName of ‘Burnt Offerings Index’ you can use the String of ‘BurntOfferingsIndex’ in a fetch clause or a query clause or refer to the field directly on an artifact as artifact.BurntOfferingsIndex.
I think what you have should work, unless the ServiceNowID is empty. In that case there will not be a LinkID or DisplayString available on the ServiceNowID object.
If you update your code to check to make sure the Attribute is there, does it work?
if hasattr(story.c_ServiceNowID, 'LinkID'):
a_story['Service']=story.c_ServiceNowID.DisplayString
a_story['Link']=story.c_ServiceNowID.LinkID
I have this form that gets built from the SQLFORM method,
flow_step_forms[step.name] = SQLFORM(db.approval_flows_progress_steps,
record=thisstep.id if thisstep is not None else None,
readonly=not __userCanPerformStep(step) or flow_completed)
the db for approval_flows_progress_steps is as follows
db.define_table('approval_flows_progress_steps',
Field('flow_progress', 'reference approval_flows_progress'),
Field('flow_step', 'reference approval_flows_steps'),
Field('completed', 'boolean'),
Field('completed_on', 'datetime'),
Field('completed_by', 'reference auth_user'),
Field('notes', 'text', writable = True),
auth.signature
)
the field notes gets rendered as a textbox.
After I assign the SQLFORM there is this code:
if __userCanPerformStep(step) and not flow_completed:
flow_step_forms[step.name].element('textarea')['_rows'] = 5
I figured I can reference properties of the db like they do here but I get the following error:
'NoneType' object has no attribute 'writable'
Q: How can I make the text box conditionally enabled for certain users??
I am not sure about why you are getting a NoneType. But to make the textarea readonly you can do something like this:
if __userCanPerformStep(step) and not flow_completed:
flow_step_forms[step.name].element('textarea')['_readonly'] = True
else:
flow_step_forms[step.name].element('textarea')['_readonly'] = False
If your NoneType problem is only occurring when the user is not authorized. You could catch it with a Try/Except block. Saying except NoneType: _readonly = True.
I'm trying to get a field from openERPs mail_message model using python code which is executed in a server action (so its not a module where I can debug! I cannot even print in this state) (when a new eMail is being fetched) but I am unable to get anything useful from it.
Basicly when someone is throwing me a email, a new Task is created by openERP. But the newely created ticket is not connected to the user which send me the mail.
When a new email is fetched, this server action gets executed.
In a table called mail_message you can then find the email (+ author_id, + email, + res_id (which is the id of the created Task), therefore I'd like to fetch the author_id from that table.
(A query would look like this:
SELECT author_id FROM mail_message WHERE type = 'email' AND res_id = '<Task.id>')
This is my current code
#Initialize object. That one points to the mail_message model.
mailMessage_obj = self.pool.get('mail.message')
#Created Id in project_task
myId = object.id
#browse whole object with that id
#message = mailMessage_obj.browse(cr,uid,[myId])
#Select field where
messageIds = mailMessage_obj.search(cr,uid,[('type','=','email'),('res_id','=',myId)],context=context)
if messageIds:
#messageRecord = mailMessage_obj.browse(cr,uid,[myId],context=context)
#object.write({'partner_id':messageRecord.author_id.id})
res = mailMessage_obj.read(messageIds, ['author_id'])
partnerId = res[0]
#Author id
#partnerId = message[0]['author_id']
#partnerId = message.author_id
#res = [(r['id'], r['author_id']) for r in messageRecord]
#partnerId = res
#partnerId = 259866
object.write({'partner_id':partnerId})
I dont know how to get my hands on the author_id properly. If I hardcode a ID and let it write to the database (last two lines) It'll work just fine, but I cant hardcode a users id. ;)
Could someone explain to me how its done correctly?
I dont know whether I should use .browse or .read or something else..
I think you have an error on you python method.
you wrote :
res = mailMessage_obj.read(messageIds, ['author_id'])
partnerId = res[0]
But read() method returns here a list of dict (because messageIds is a list). Then, you have not specified the field you wanted to retrieve from res variable, and finally, as author_id is a many2one, it returns something like this : (2, 'myusers').
You should have done :
res = mailMessage_obj.read(cr, uid, messageIds, ['author_id'])
partnerId = res[0]['author_id'][0]
Hope i helped you,
Greatings
my first question here, perhaps a noob question but I really don't understand what I'm doing wrong, and I can't find any clue on the web.py documentation.
Is it possible to use a db select to validate a field?
What I'm doing:
I'm building a registration form, I'm having trouble with the username validation.
In every example I found, users are declared in a variable before the registration Class with code like this:
allowed = (
('jon','pass1'),
('tom','pass2')
)
and used in the validation like this:
form.Validator('Username already exists.', lambda x: x not in allowed)
Since I'm saving in db, I can change the allowed tuples with a db.select, but this mean the select is performed only once.
I want to check the users every time the POST is called, so I just replaced the "allowed" variable with a db.select this way:
form.Validator('Username already exists.', lambda x: x not in [o.usr for o in db.select('users',what='usr')])
If I test "x not in [o.usr..etc..etc..]" on the interpreter, this work..
>>> [o.usr for o in db.select('users',what='usr')]
0.0 (1): SELECT usr FROM users
[u'hhh', u'Fede', u'Vinz', u'Patro', u'Codino', u'Codino']
>>> x = "Fede"
>>> x not in [o.usr for o in db.select('users',what='usr')]
0.0 (2): SELECT usr FROM users
False
But when I run the code and I make a new registration with an existing username nothing happens.. as you can see the "Codino" username is been registered twice.
What I'm doing wrong?
..and more interesting: there is a smarter way to block the registration of an already used username?
Thanks,
Federico
I don't know if you already have an answer with this one since it's an old thread.
Here's what I did on checking if username already exist.
I create a validator such as these:
vuser_exist = form.Validator("Username already exist.", lambda u: u is None or model.get_user(u.username) is None)
register_form = form.Form(
form.Textbox("username", vuser_req, vuser_length, description="Username"),
form.Button("submit", type="submit", description="Register"),
validators = [vuser_exist],
)
In model.py
def get_user(user):
try:
return db.select('users', where='user=$user', vars=locals())[0]
except IndexError:
return None