I've read other topics and also the full documentation.
I'm trying to write to a record.
API returns "True", but there is no effect to the field.
write_to_db = models.execute_kw(db, uid, password,
'mail.mass_mailing.contact', 'write', [ [the_contact[0]["id"]], { 'tag_ids': the_contact[0]["tag_ids"]}])
the_contact[0]["id"] is the id of the contact whose tags I want to change (add a new tag).
the_contact[0]["tag_ids"] contains [1,2] ==> the new list of tags
I'm aware that for one2many and many2many fields I need special syntax:
https://www.odoo.com/documentation/10.0/reference/orm.html
From (0, _, values) ... to (6, _, ids)
But some of those syntax don't even has a place for new values!!! Just options 0 and 1... for the others one have just place to id??? But id is already in the command...
Tried many combinations but none worked.
(Bottom line: I'm a beginner in both Odoo and Python)
Got the answer.
The problem was not the syntax.
"tag_ids" in fact are related to res.partner, not to mail.mass_mailing.tag
Related
I am trying to integrate SharePoint in one of my Python Scripts and I need to grab the users from a SP list. Until now, I managed to log in, search for a specific list, and enumerate all of its items.
def enum_items(list):
items = list.items # .top(1220)
ctx.load(items)
ctx.execute_query()
for index, item in enumerate(items):
print("{0}: {1}".format(index, item.properties['Email']))
The 'Email' column's value is set to User.email like so:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"txtContent": "[$User.email]"
}
Basically the Email is automatically set when a new user is added in the User column.
Some entries where manually added, and others use the above code. For those that were manually added it prints the email, but for the other, it prints: "None".
If I change the 'Email' to 'User', I get the following error, like it cannot find that column or so:
print("{0}: {1}".format(index, item.properties['User']))
KeyError: 'User'
Is there anyway I can grab the USER object, and then use its properties (which ever those are) to grab some information about it?
Thanks!
I need a help please.
So I wanted when I change the Internal Category (field name is categ_id) value to 500 final product,
and then the Routes field changes to :
Manufacture checked,
Make To Order checked,
Buy checked
and also the Value of Tracking field is changes as well to:
By Lots checked
How can I do that? Any suggestion ? Or my is it my question are not clear enough ?
Sorry for asking , I never done this before so yeah kind a confusing.
Here I got the picture the interface and the information about the field as well.
Routes field name
Tracking field name
Please anyone kindly to help me. I am so confused.
You could achieve this by using api onchange in Odoo 9.
#api.onchange('categ_id')
def onchange_categ_id(self):
for record in self:
# I prefer to check by id, but here I show how to check by string name in case you want it
if record.categ_id.name == '500 final product':
# because route_ids is many2many field,
# you need special commands to change the value
# here I use (6, _, ids) to set value.
# But before that, you have to get the ids of the routes you want from model stock.location.route
# (you could use search method to get the ids)
record.route_ids = [(6,0, list_of_id)]
record.tracking = 'lot'
...
You could refer to Odoo Doc to learn more about O2m and M2m commands
I'm new to Python and I'm trying to make a simple bulletin board system app using web2py. I am trying to add a post into a certain board and I linked the post and board by including the following field in my post table: Field('board_id', db.board). When I try to create a post inside a particular board it gives me an error: "OperationalError: no such column: board.id". My code for create_posts:
def add_post():
board = db.board(request.args(0))
form = SQLFORM(db.post)
db.pst.board_id.default = db.board.id
if form.process().accepted:
session.flash = T('The data was inserted')
redirect(URL('default', 'index'))
return dict(form=form, board=board)
When I try to do {{=board}} on the page that shows the posts in a certain board, I get Row {'name': 'hi', 'id': 1L, 'pst': Set (pst.board_id = 1), 'description': 'hi'} so I know it's there in the database. But when I do the same thing for the "add post" form page, it says "board: None". I'm extremely confused, please point me in the right direction!
There appear to be several problems with your function. First, you are assigning the default value of the board_id field to be a Field object (i.e., db.board.id) rather than an actual id value (e.g., board.id). Second, any default values should be assigned before creating the SQLFORM.
Finally, you pass db.post to SQLFORM, but in the next line, the post table appears to be called db.pst -- presumably these are not two separate tables and one is just a typo.
Regarding the issue of {{=board}} displaying None, that indicates that board = db.board(request.args(0)) is not retrieving a record, which would be due to request.args(0) itself being None or being a value that does not match any record id in db.board. You should check how you are generating the links that lead to add_post and confirm that there is a valid db.board id in the first URL arg. In any case, it might be a good idea to detect when there is no valid board record and either redirect or display an error message.
So, your function should look something like this:
def add_post():
board = db.board(request.args(0)) or redirect(URL('default', 'index'))
db.pst.board_id.default = board.id
form = SQLFORM(db.pst)
if form.process(next=URL('default', 'index'),
message_onsuccess=T('The data was inserted'))
return dict(form=form, board=board)
Note, if your are confident that links to add_post will include valid board IDs, then you can eliminate the first line altogether, as there is no reason to retrieve a record based on its ID if the only field you need from it is the ID (which you already have). Instead, the second line could be:
db.pst.board_id.default = request.args(0) or redirect(URL('default', 'index'))
I am trying to write a simple Liferay portlet in Python. The portlet will show a list of categories and when clicked will show a list of Web Content articles (journal articles) of a certain structure.
I am able to get the list of categories but cannot find a way using the liferay api to get a list of articles by category?
I have searched allover but it seems to me the method should be on this page:
http://docs.liferay.com/portal/6.1/javadocs/com/liferay/portlet/journal/service/JournalArticleLocalServiceUtil.html
It is a Java implementation but really easy to convert into python.
<%
String languageId = LanguageUtil.getLanguageId( renderRequest );
List<JournalArticle> journalArticleList = new ArrayList<JournalArticle>();
AssetEntryQuery assetEntryQuery = new AssetEntryQuery();
assetEntryQuery.setAnyCategoryIds(new long[] { 12704 }); //category Id
assetEntryQuery.setOrderByCol1("modifiedDate");
assetEntryQuery.setEnd(5);
List<AssetEntry> assetEntryList = AssetEntryLocalServiceUtil.getEntries(assetEntryQuery);
for (AssetEntry ae : assetEntryList) {
JournalArticleResource journalArticleResource = JournalArticleResourceLocalServiceUtil.getJournalArticleResource(ae.getClassPK());
JournalArticle journalArticle = JournalArticleLocalServiceUtil.getLatestArticle(journalArticleResource.getResourcePrimKey());
JournalContentUtil.clearCache();
String content = JournalContentUtil.getContent(journalArticleResource.getGroupId(), journalArticle.getArticleId(), "view", languageId, themeDisplay);
out.println("<br>"+journalArticle.getTitle(languageId)+"<br>");
out.println(content);
}
%>
The proposed solution is good yet needs one extra piece. It will return all Assets - web-content-articles are a subset of assets. For example, you will get documents (which have been categorized the same way) as well. To refine your search, add a className, classNameid, or classTypeId to the AssetEntryQuery (in addition to the category id). Alternatively, within the for-loop you could pick out the web-content, ignore the others.
Thanks, AssetEntryQuery was the solution:
from com.liferay.portlet.asset.service.persistence import AssetEntryQuery
from com.liferay.portlet.asset.service import AssetEntryServiceUtil
aq = AssetEntryQuery()
aq.setAllCategoryIds([442492])
articles = AssetEntryServiceUtil.getEntries(aq)
for a in articles:
out.write(str(a.title))
out.write(str(a))
I'm trying to parse an html form using mechanize. The form itself has an arbitrary number of hidden fields and the field names and id's are randomly generated so I have no obvious way to directly select them. Clearly using a name or id is out, and due to the random number of hidden fields I cannot select them based on the sequence number since this always changes too.
However there are always two TextControl fields right after each other, and then below that is a TextareaControl. These are the 3 fields I need access too, basically I need to parse their names and all is well. I've been looking through the mechanize documentation for the past couple hours and haven't come up with anything that seems to be able to do this, however simple it should seem to be (to me anyway).
I have come up with an alternate solution that involves making a list of the form controls, iterating through it to find the controls that contain the string 'Text' returning a new list of those, and then finally stripping out the name using a regular expression. While this works it seems unnecessary and I'm wondering if there's a more elegant solution. Thanks guys.
edit: Here's what I'm currently doing to extract that info if anyone's curious. I think I'm probably just going to stick with this. It seems unnecessary but it gets the job done and it's nothing intensive so I'm not worried about efficiency or anything.
def formtextFieldParse(browser):
'''Expects a mechanize.Browser object with a form already selected. Parses
through the fields returning a tuple of the name of those fields. There
SHOULD only be 3 fields. 2 text followed by 1 textarea corresponding to
Posting Title, Specific Location, and Posting Description'''
import re
pattern = '\(.*\)'
fields = str(browser).split('\n')
textfields = []
for field in fields:
if 'Text' in field: textfields.append(field)
titleFieldName = re.findall(pattern, textfields[0])[0][1:-2]
locationFieldName = re.findall(pattern, textfields[1])[0][1:-2]
descriptionFieldName = re.findall(pattern, textfields[2])[0][1:-2]
I don't think mechanize has the exact functionality you require; could you use mechanize to get the HTML page, then parse the latter for example with BeautifulSoup?