widgets.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # coding:utf-8
  2. from django import forms
  3. from django.conf import settings
  4. from django.contrib.admin.widgets import AdminTextareaWidget
  5. from django.template.loader import render_to_string
  6. from django.utils.safestring import mark_safe
  7. from django.utils.http import urlencode
  8. from . import settings as USettings
  9. from .commands import *
  10. from django.utils.six import string_types
  11. # 修正输入的文件路径,输入路径的标准格式:abc,不需要前后置的路径符号
  12. # 如果输入的路径参数是一个函数则执行,否则可以拉接受时间格式化,用来生成如file20121208.bmp的重命名格式
  13. def calc_path(OutputPath, instance=None):
  14. if callable(OutputPath):
  15. try:
  16. OutputPath = OutputPath(instance)
  17. except:
  18. OutputPath = ""
  19. else:
  20. try:
  21. import datetime
  22. OutputPath = datetime.datetime.now().strftime(OutputPath)
  23. except:
  24. pass
  25. return OutputPath
  26. # width=600, height=300, toolbars="full", imagePath="", filePath="", upload_settings={},
  27. # settings={},command=None,event_handler=None
  28. class UEditorWidget(forms.Textarea):
  29. def __init__(self, attrs=None):
  30. params = attrs.copy()
  31. width = params.pop("width")
  32. height = params.pop("height")
  33. toolbars = params.pop("toolbars", "full")
  34. imagePath = params.pop("imagePath", "")
  35. filePath = params.pop("filePath", "")
  36. upload_settings = params.pop("upload_settings", {})
  37. settings = params.pop("settings", {})
  38. command = params.pop("command", None)
  39. event_handler = params.pop("event_handler", None)
  40. # 扩展命令
  41. self.command = command
  42. self.event_handler = event_handler
  43. # 上传路径
  44. self.upload_settings = upload_settings.copy()
  45. self.upload_settings.update({
  46. "imagePathFormat": imagePath,
  47. "filePathFormat": filePath
  48. })
  49. # 保存
  50. self._upload_settings = self.upload_settings.copy()
  51. self.recalc_path(None)
  52. self.ueditor_settings = {
  53. 'toolbars': toolbars,
  54. 'initialFrameWidth': width,
  55. 'initialFrameHeight': height
  56. }
  57. # 以下处理工具栏设置,将normal,mini等模式名称转化为工具栏配置值
  58. if toolbars == "full":
  59. del self.ueditor_settings['toolbars']
  60. elif isinstance(toolbars, string_types) and toolbars in USettings.TOOLBARS_SETTINGS:
  61. self.ueditor_settings[
  62. "toolbars"] = USettings.TOOLBARS_SETTINGS[toolbars]
  63. else:
  64. self.ueditor_settings["toolbars"] = toolbars
  65. # raise ValueError('toolbars should be a string defined in DjangoUeditor.settings.TOOLBARS_SETTINGS, options are full(default), besttome, mini and normal!')
  66. self.ueditor_settings.update(settings)
  67. super(UEditorWidget, self).__init__(attrs)
  68. def recalc_path(self, model_inst):
  69. """计算上传路径,允许是function"""
  70. try:
  71. uSettings = self.upload_settings
  72. if 'filePathFormat' in self._upload_settings:
  73. uSettings['filePathFormat'] = calc_path(
  74. self._upload_settings['filePathFormat'], model_inst)
  75. if 'imagePathFormat' in self._upload_settings:
  76. uSettings['imagePathFormat'] = calc_path(
  77. self._upload_settings['imagePathFormat'], model_inst)
  78. if 'scrawlPathFormat' in self._upload_settings:
  79. uSettings['scrawlPathFormat'] = calc_path(
  80. self._upload_settings['scrawlPathFormat'], model_inst)
  81. if 'videoPathFormat' in self._upload_settings:
  82. uSettings['videoPathFormat'] = calc_path(
  83. self._upload_settings['videoPathFormat'], model_inst),
  84. if 'snapscreenPathFormat' in self._upload_settings:
  85. uSettings['snapscreenPathFormat'] = calc_path(
  86. self._upload_settings['snapscreenPathFormat'], model_inst)
  87. if 'catcherPathFormat' in self._upload_settings:
  88. uSettings['catcherPathFormat'] = calc_path(
  89. self._upload_settings['catcherPathFormat'], model_inst)
  90. if 'imageManagerListPath' in self._upload_settings:
  91. uSettings['imageManagerListPath'] = calc_path(
  92. self._upload_settings['imageManagerListPath'], model_inst)
  93. if 'fileManagerListPath' in self._upload_settings:
  94. uSettings['fileManagerListPath'] = calc_path(
  95. self._upload_settings['fileManagerListPath'], model_inst)
  96. # 设置默认值,未指定涂鸦、截图、远程抓图、图片目录时,默认均等于imagePath
  97. if uSettings['imagePathFormat'] != "":
  98. default_path = uSettings['imagePathFormat']
  99. uSettings['scrawlPathFormat'] = uSettings.get(
  100. 'scrawlPathFormat', default_path)
  101. uSettings['videoPathFormat'] = uSettings.get(
  102. 'videoPathFormat', default_path)
  103. uSettings['snapscreenPathFormat'] = uSettings.get(
  104. 'snapscreenPathFormat', default_path)
  105. uSettings['catcherPathFormat'] = uSettings.get(
  106. 'catcherPathFormat', default_path)
  107. uSettings['imageManagerListPath'] = uSettings.get(
  108. 'imageManagerListPath', default_path)
  109. if uSettings['filePathFormat'] != "":
  110. uSettings['fileManagerListPath'] = uSettings.get(
  111. 'fileManagerListPath', uSettings['filePathFormat'])
  112. except:
  113. pass
  114. def render(self, name, value, attrs=None):
  115. if value is None:
  116. value = ''
  117. # 传入模板的参数
  118. editor_id = "id_%s" % name.replace("-", "_")
  119. uSettings = {
  120. "name": name,
  121. "id": editor_id,
  122. "value": value
  123. }
  124. if isinstance(self.command, list):
  125. cmdjs = ""
  126. if isinstance(self.command, list):
  127. for cmd in self.command:
  128. cmdjs = cmdjs + cmd.render(editor_id)
  129. else:
  130. cmdjs = self.command.render(editor_id)
  131. uSettings["commands"] = cmdjs
  132. uSettings["settings"] = self.ueditor_settings.copy()
  133. uSettings["settings"].update({
  134. "serverUrl": "/ueditor/controller/?%s" % urlencode(self._upload_settings)
  135. })
  136. # 生成事件侦听
  137. if self.event_handler:
  138. uSettings["bindEvents"] = self.event_handler.render(editor_id)
  139. context = {
  140. 'UEditor': uSettings,
  141. 'STATIC_URL': settings.STATIC_URL,
  142. 'STATIC_ROOT': settings.STATIC_ROOT,
  143. 'MEDIA_URL': settings.MEDIA_URL,
  144. 'MEDIA_ROOT': settings.MEDIA_ROOT
  145. }
  146. return mark_safe(render_to_string('ueditor.html', context))
  147. class Media:
  148. js = ("ueditor/ueditor.config.js",
  149. "ueditor/ueditor.all.min.js")
  150. class AdminUEditorWidget(AdminTextareaWidget, UEditorWidget):
  151. def __init__(self, **kwargs):
  152. super(AdminUEditorWidget, self).__init__(**kwargs)