Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

248 lignes
7.2 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # License: MIT. See LICENSE
  3. import json
  4. import frappe
  5. from frappe import _
  6. from frappe.model.document import Document, get_controller
  7. from frappe.utils import cint, quoted
  8. from frappe.website.path_resolver import resolve_path
  9. no_cache = 1
  10. def get_context(context, **dict_params):
  11. """Returns context for a list standard list page.
  12. Will also update `get_list_context` from the doctype module file"""
  13. frappe.local.form_dict.update(dict_params)
  14. doctype = frappe.local.form_dict.doctype
  15. context.parents = [{"route": "me", "title": _("My Account")}]
  16. context.meta = frappe.get_meta(doctype)
  17. context.update(get_list_context(context, doctype) or {})
  18. context.doctype = doctype
  19. context.txt = frappe.local.form_dict.txt
  20. context.update(get(**frappe.local.form_dict))
  21. @frappe.whitelist(allow_guest=True)
  22. def get(doctype, txt=None, limit_start=0, limit=20, pathname=None, **kwargs):
  23. """Returns processed HTML page for a standard listing."""
  24. limit_start = cint(limit_start)
  25. raw_result = get_list_data(doctype, txt, limit_start, limit=limit + 1, **kwargs)
  26. show_more = len(raw_result) > limit
  27. if show_more:
  28. raw_result = raw_result[:-1]
  29. meta = frappe.get_meta(doctype)
  30. list_context = frappe.flags.list_context
  31. if not raw_result:
  32. return {"result": []}
  33. if txt:
  34. list_context.default_subtitle = _('Filtered by "{0}"').format(txt)
  35. result = []
  36. row_template = list_context.row_template or "templates/includes/list/row_template.html"
  37. list_view_fields = [df for df in meta.fields if df.in_list_view][:4]
  38. for doc in raw_result:
  39. doc.doctype = doctype
  40. new_context = frappe._dict(doc=doc, meta=meta, list_view_fields=list_view_fields)
  41. if not list_context.get_list and not isinstance(new_context.doc, Document):
  42. new_context.doc = frappe.get_doc(doc.doctype, doc.name)
  43. new_context.update(new_context.doc.as_dict())
  44. if not frappe.flags.in_test:
  45. pathname = pathname or frappe.local.request.path
  46. new_context["pathname"] = pathname.strip("/ ")
  47. new_context.update(list_context)
  48. set_route(new_context)
  49. rendered_row = frappe.render_template(row_template, new_context, is_path=True)
  50. result.append(rendered_row)
  51. from frappe.utils.response import json_handler
  52. return {
  53. "raw_result": json.dumps(raw_result, default=json_handler),
  54. "result": result,
  55. "show_more": show_more,
  56. "next_start": limit_start + limit,
  57. }
  58. @frappe.whitelist(allow_guest=True)
  59. def get_list_data(
  60. doctype, txt=None, limit_start=0, fields=None, cmd=None, limit=20, web_form_name=None, **kwargs
  61. ):
  62. """Returns processed HTML page for a standard listing."""
  63. limit_start = cint(limit_start)
  64. if frappe.is_table(doctype):
  65. frappe.throw(_("Child DocTypes are not allowed"), title=_("Invalid DocType"))
  66. if not txt and frappe.form_dict.search:
  67. txt = frappe.form_dict.search
  68. del frappe.form_dict["search"]
  69. controller = get_controller(doctype)
  70. meta = frappe.get_meta(doctype)
  71. filters = prepare_filters(doctype, controller, kwargs)
  72. list_context = get_list_context(frappe._dict(), doctype, web_form_name)
  73. list_context.title_field = getattr(controller, "website", {}).get(
  74. "page_title_field", meta.title_field or "name"
  75. )
  76. if list_context.filters:
  77. filters.update(list_context.filters)
  78. _get_list = list_context.get_list or get_list
  79. kwargs = dict(
  80. doctype=doctype,
  81. txt=txt,
  82. filters=filters,
  83. limit_start=limit_start,
  84. limit_page_length=limit,
  85. order_by=list_context.order_by or "modified desc",
  86. )
  87. # allow guest if flag is set
  88. if not list_context.get_list and (list_context.allow_guest or meta.allow_guest_to_view):
  89. kwargs["ignore_permissions"] = True
  90. raw_result = _get_list(**kwargs)
  91. # list context to be used if called as rendered list
  92. frappe.flags.list_context = list_context
  93. return raw_result
  94. def set_route(context):
  95. """Set link for the list item"""
  96. if context.web_form_name:
  97. context.route = "{0}?name={1}".format(context.pathname, quoted(context.doc.name))
  98. elif context.doc and getattr(context.doc, "route", None):
  99. context.route = context.doc.route
  100. else:
  101. context.route = "{0}/{1}".format(
  102. context.pathname or quoted(context.doc.doctype), quoted(context.doc.name)
  103. )
  104. def prepare_filters(doctype, controller, kwargs):
  105. for key in kwargs.keys():
  106. try:
  107. kwargs[key] = json.loads(kwargs[key])
  108. except ValueError:
  109. pass
  110. filters = frappe._dict(kwargs)
  111. meta = frappe.get_meta(doctype)
  112. if hasattr(controller, "website") and controller.website.get("condition_field"):
  113. filters[controller.website["condition_field"]] = 1
  114. if filters.pathname:
  115. # resolve additional filters from path
  116. resolve_path(filters.pathname)
  117. for key, val in frappe.local.form_dict.items():
  118. if key not in filters and key != "flags":
  119. filters[key] = val
  120. # filter the filters to include valid fields only
  121. for fieldname, val in list(filters.items()):
  122. if not meta.has_field(fieldname):
  123. del filters[fieldname]
  124. return filters
  125. def get_list_context(context, doctype, web_form_name=None):
  126. from frappe.modules import load_doctype_module
  127. list_context = context or frappe._dict()
  128. meta = frappe.get_meta(doctype)
  129. def update_context_from_module(module, list_context):
  130. # call the user defined method `get_list_context`
  131. # from the python module
  132. if hasattr(module, "get_list_context"):
  133. out = frappe._dict(module.get_list_context(list_context) or {})
  134. if out:
  135. list_context = out
  136. return list_context
  137. # get context from the doctype module
  138. if not meta.custom:
  139. # custom doctypes don't have modules
  140. module = load_doctype_module(doctype)
  141. list_context = update_context_from_module(module, list_context)
  142. # get context for custom webform
  143. if meta.custom and web_form_name:
  144. webform_list_contexts = frappe.get_hooks("webform_list_context")
  145. if webform_list_contexts:
  146. out = frappe._dict(frappe.get_attr(webform_list_contexts[0])(meta.module) or {})
  147. if out:
  148. list_context = out
  149. # get context from web form module
  150. if web_form_name:
  151. web_form = frappe.get_doc("Web Form", web_form_name)
  152. list_context = update_context_from_module(web_form.get_web_form_module(), list_context)
  153. # get path from '/templates/' folder of the doctype
  154. if not meta.custom and not list_context.row_template:
  155. list_context.row_template = meta.get_row_template()
  156. if not meta.custom and not list_context.list_template:
  157. list_context.template = meta.get_list_template() or "www/list.html"
  158. return list_context
  159. def get_list(
  160. doctype,
  161. txt,
  162. filters,
  163. limit_start,
  164. limit_page_length=20,
  165. ignore_permissions=False,
  166. fields=None,
  167. order_by=None,
  168. ):
  169. meta = frappe.get_meta(doctype)
  170. if not filters:
  171. filters = []
  172. if not fields:
  173. fields = "distinct *"
  174. or_filters = []
  175. if txt:
  176. if meta.search_fields:
  177. for f in meta.get_search_fields():
  178. if f == "name" or meta.get_field(f).fieldtype in ("Data", "Text", "Small Text", "Text Editor"):
  179. or_filters.append([doctype, f, "like", "%" + txt + "%"])
  180. else:
  181. if isinstance(filters, dict):
  182. filters["name"] = ("like", "%" + txt + "%")
  183. else:
  184. filters.append([doctype, "name", "like", "%" + txt + "%"])
  185. return frappe.get_list(
  186. doctype,
  187. fields=fields,
  188. filters=filters,
  189. or_filters=or_filters,
  190. limit_start=limit_start,
  191. limit_page_length=limit_page_length,
  192. ignore_permissions=ignore_permissions,
  193. order_by=order_by,
  194. )