Can not filter in Link Field

In my custom App, displaying Users in a link field.
but I want to show only some users, for that I have used set_query
below is my code,

++++
frm.set_query(“user”, function() {
return {
filters: [
[“User”,“email”, “in”, [“abc@gmail.com”, “xyz@gmail.com”]]
//[“User”,“first_name”, “in”, [“abc”, “xyz”]]
]
}
});

+++
getting below exception,

Traceback (most recent call last):
File “/home/frappe/frappe-bench/apps/frappe/frappe/app.py”, line 62, in application
response = frappe.handler.handle()
File “/home/frappe/frappe-bench/apps/frappe/frappe/handler.py”, line 22, in handle
data = execute_cmd(cmd)
File “/home/frappe/frappe-bench/apps/frappe/frappe/handler.py”, line 53, in execute_cmd
return frappe.call(method, **frappe.form_dict)
File “/home/frappe/frappe-bench/apps/frappe/frappe/init.py”, line 941, in call
return fn(*args, **newargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/desk/search.py”, line 14, in search_link
search_widget(doctype, txt, query, searchfield=searchfield, page_length=page_length, filters=filters)
File “/home/frappe/frappe-bench/apps/frappe/frappe/desk/search.py”, line 39, in search_widget
searchfield, start, page_length, filters)
File “/home/frappe/frappe-bench/apps/frappe/frappe/desk/search.py”, line 35, in search_widget
searchfield, start, page_length, filters, as_dict=as_dict)
File “/home/frappe/frappe-bench/apps/frappe/frappe/init.py”, line 941, in call
return fn(*args, **newargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/core/doctype/user/user.py”, line 819, in user_query
if filters and filters.get(‘ignore_user_type’):
AttributeError: ‘list’ object has no attribute ‘get’

what’s wrong here?
Any help?

Edit: This code has worked for other doctype then User in Link field.
Do I need to pass additional flag or something while filtering User Data??

1 Like

Hi @hetal1110

set_query of User will call this API frappe.core.doctype.user.user.user_query (frappe app hook this api for user). It not support search by filters.

So you need to create new api in your app to query user support search email.

frm.set_query('user', function () {
    return {
        query: "yourapp.api.user_query",
        "filters": {
            "email": ["in",["abc@gmail.com", "xyz@gmail.com"]]
        }
    }
});

frappe.core.doctype.user.user.user_query

def user_query(doctype, txt, searchfield, start, page_len, filters):
	from frappe.desk.reportview import get_match_cond

	user_type_condition = "and user_type = 'System User'"
	if filters and filters.get('ignore_user_type'):
		user_type_condition = ''

	txt = "%{}%".format(txt)
	return frappe.db.sql("""select name, concat_ws(' ', first_name, middle_name, last_name)
		from `tabUser`
		where enabled=1
			{user_type_condition}
			and docstatus < 2
			and name not in ({standard_users})
			and ({key} like %(txt)s
				or concat_ws(' ', first_name, middle_name, last_name) like %(txt)s)
			{mcond}
		order by
			case when name like %(txt)s then 0 else 1 end,
			case when concat_ws(' ', first_name, middle_name, last_name) like %(txt)s
				then 0 else 1 end,
			name asc
		limit %(start)s, %(page_len)s""".format(
			user_type_condition = user_type_condition,
			standard_users=", ".join(["'{0}'".format(frappe.db.escape(u)) for u in STANDARD_USERS]),
			key=searchfield, mcond=get_match_cond(doctype)),
			dict(start=start, page_len=page_len, txt=txt))
1 Like

Thanks @vinhnguyent090

By creating new API it works…

1 Like

Here are some notes for people in the future, these helped me. Maybe they can save someone some time.

Adding Filter to a Linked Field in a Document
    frappe.ui.form.on('CurrentDocName',{
        setup: function(frm) {
    		cur_frm.set_query("LinkedFieldNameFromCurrentDoc", function() {
    			return {
    				filters: {
    					"FieldNameFromLinkedDocument:'YourFilter'
    				}
    			}
    		});
    	}
    })

Adding Filter to a Linked Field from a Child Table Link
In the event that you have a child table that has a link in it, and you want to add a filter to that

frappe.ui.form.on('CurrentDocName',{
        setup: function(frm) {
    		cur_frm.fields_dict['ChildTableNameInCurrentDoc'].grid.get_field("ChildTableLinkedFieldName").get_query = function(doc, cdt, cdn) 
    		{
    			return {
    				filters: {
    				"FieldNameFromLinkedDocument":'YourFilter'
    				}

    					}
    		}
    	}
    });
5 Likes