Try ERPNext Buy Support Partners Foundation

Difference of is_new() and __islocal

Continuing the discussion from __islocal equivalent in server side script:

I know that __islocal depends on flag 1 or 0 and it is not yet in database.

But is_new() is on server side so I guess it should be in database.

My question is what make a doc is_new?
Is it based on flag too, or on time?

Thanks

You could also use frappe.db.exists if you want to know if the record is new. here’s the documentation

Thank you @Javier_Lopez,

Yes I know that. But what I meant is what define a doc as new?

while:
__islocal defines by the state 1 (never saved)
frappe.db.exist defines by not having the doc in database.

Because is_new() runs from the server side so I guess the doc must already in database. Otherwise we use frappe.db.exist.
And islocal is client side so it can check the browser.

islocal can be defined like local vs server.
db.exist can be defined like exist (in database) vs non-exist.
now can is_new defined like new vs old?

@rahy Hello

now can is_new defined like new vs old?

I don’t know what you mean by old vs new. For me new is a document that is not in the database, hasn’t been inserted, and old is something that already is.

And islocal is client side so it can check the browser.

Not exactly, when using frappe.new_doc() in the backend, you will get a document that has __islocal == 1, but not when creted with frappe.get_doc which is weird behavior, I’ve asked about in an issue

But exactly what’s your question or goal for new vs old.

New vs old is just an analogy.
What I want to know is how a doc is stated as new. Is it by time or by what, I can’t find documentation. And not many examples explaining it.

According to your explanation, when a doc is saved using doc.save() then followed by if doc.is_new() will return False.

Then when is doc.is_new() return True when we are working from code? As long as there is not yet doc.saved() the doc is new.

Am I right?

And in many references still using get_doc() then save() to create new doc.

And by the way, I think the way to write get_doc with fieldname keyword is:

frappe.get_doc('Package', {'name':'This cool'})

will this return the same?

It’s easy to test.

In [1]: doc = frappe.new_doc('Task')

In [2]: doc.subject = 'Testing new'

In [3]: doc.as_dict()
Out[3]:
{'name': None,
 'owner': 'Administrator',
 'creation': None,
 'modified': None,
 'modified_by': None,
 'parent': None,
 'parentfield': None,
 'parenttype': None,
 'idx': 0,
 'docstatus': 0,
 'github_sync_id': None,
 'subject': 'Testing new',
 'project': None,
 'issue': None,
 'type': None,
 'is_group': 0,
 'status': 'Open',
 'priority': 'Low',
 'task_weight': 0,
 'completed_by': None,
 'color': None,
 'parent_task': None,
 'exp_start_date': None,
 'expected_time': 0.0,
 'exp_end_date': None,
 'progress': 0,
 'is_milestone': 0,
 'description': None,
 'depends_on_tasks': None,
 'act_start_date': None,
 'actual_time': 0,
 'act_end_date': None,
 'total_costing_amount': 0,
 'total_expense_claim': 0,
 'total_billing_amount': 0,
 'review_date': None,
 'closing_date': None,
 'department': None,
 'company': 'Login Cargo',
 'lft': 0,
 'rgt': 0,
 'old_parent': None,
 'doctype': 'Task',
 'depends_on': [],
 '__islocal': 1} # Here it is

In [4]: doc.is_new()
Out[4]: 1

In [5]: doc.save()

In [6]: doc.is_new() # As you can see is not new anymore

In [7]: doc.as_dict()
Out[7]:
{'name': 'TASK-2020-00001',
 'owner': 'Administrator',
 'creation': datetime.datetime(2020, 7, 22, 10, 42, 18, 556870),
 'modified': datetime.datetime(2020, 7, 22, 10, 42, 18, 585971),
 'modified_by': 'Administrator',
 'parent': None,
 'parentfield': None,
 'parenttype': None,
 'idx': 0,
 'docstatus': 0,
 'github_sync_id': None,
 'subject': 'Testing new',
 'project': None,
 'issue': None,
 'type': None,
 'is_group': 0,
 'status': 'Open',
 'priority': 'Low',
 'task_weight': 0.0,
 'completed_by': None,
 'color': None,
 'parent_task': None,
 'exp_start_date': None,
 'expected_time': 0.0,
 'exp_end_date': None,
 'progress': 0.0,
 'is_milestone': 0,
 'description': None,
 'depends_on_tasks': '',
 'act_start_date': None,
 'actual_time': 0.0,
 'act_end_date': None,
 'total_costing_amount': 0.0,
 'total_expense_claim': 0.0,
 'total_billing_amount': 0.0,
 'review_date': None,
 'closing_date': None,
 'department': None,
 'company': 'Login Cargo',
 'lft': 1,
 'rgt': 2,
 'old_parent': '',
 'doctype': 'Task',
 'depends_on': []} # __islocal is __isgone lol

But check what happens if the document is created with get_doc as specified in the documentation

In [1]: doc = frappe.get_doc(doctype='Task', subject='Testing')

In [2]: doc.is_new()

In [3]: doc.as_dict()
Out[3]:
{'name': None,
 'owner': None,
 'creation': None,
 'modified': None,
 'modified_by': None,
 'parent': None,
 'parentfield': None,
 'parenttype': None,
 'idx': 0,
 'docstatus': 0,
 'github_sync_id': None,
 'subject': 'Testing',
 'project': None,
 'issue': None,
 'type': None,
 'is_group': 0,
 'status': None,
 'priority': None,
 'task_weight': 0,
 'completed_by': None,
 'color': None,
 'parent_task': None,
 'exp_start_date': None,
 'expected_time': 0,
 'exp_end_date': None,
 'progress': 0,
 'is_milestone': 0,
 'description': None,
 'depends_on_tasks': None,
 'act_start_date': None,
 'actual_time': 0,
 'act_end_date': None,
 'total_costing_amount': 0,
 'total_expense_claim': 0,
 'total_billing_amount': 0,
 'review_date': None,
 'closing_date': None,
 'department': None,
 'company': None,
 'lft': 0,
 'rgt': 0,
 'old_parent': None,
 'doctype': 'Task',
 'depends_on': []}

In [4]: doc.save()

So because is new can be unreliable. I’d rather check if it’s in the database.

Yes maybe that is why in my code sometimes a line returns True and in other line it returns error :smiley:
So yes, I also use db_exist()

I don’t know haven’t tested, But don’t you think you should be able to actually get the doc when you call things with key word arguments?

Because what is doing is creating a document, and is not even checking if a document with that name exists. So you do frappe.get_doc(doctype='My Doctype', name='The name of an existing document') and you’re getting a new document, with the name of a document that already exists .

So when you do your thing with the document and go to save it. You get an error that the document has been modified after you opened it. Why? Because before saving it goes and get’s the modified_date from the database for the document name which you got (you’re thinking is the document you want because you passed keyword arguments) but you actually got a new one, but with duplicate name. And when checking the las modified date of the doc you have vs the one in the databse. They are not the same. And will error out.

In my opinion it should error out as soon as you create a new doc with an existing doc name.

In [1]: cust_doc = frappe.new_doc('Customer')

In [2]: cust_doc.is_new()
Out[2]: 1

In [3]: cust_doc.save()
MandatoryError: [Customer, CUST-2020-00001]: customer_name

In [4]: cust_doc.is_new()
Out[4]: True

:smiley:

Since you didn’t specified the customer_name required field your document wasn’t saved. It won’t save if you don’t pass all the validation methods. :smile:

No I just want to show
Out[2]: 1
and
Out[4]:True

Trying to catch 1 might return error or false.

Yeah, that’s why you do type cohersion. But ideally It should standarize.

Python

if doc.is_new():

Js

if (doc.is_new()) {
}
1 Like

Well @Javier_Lopez,
Thank you for the discussion.

1 Like