django-tinymce结合django-filebrowser无图片上传按钮问题求助
Django-TinyMCE 与 django-filebrowser 集成问题:图片对话框无上传按钮
我正在为博客的文本编辑器集成django-tinymce与django-filebrowser,实现媒体文件插入功能。目前整体运行看似正常,但点击编辑器中的图片按钮后,弹出的对话框里没有文件上传按钮。查过相关论坛帖子,没找到解决办法,以下是我的配置信息:
settings.py 配置
INSTALLED_APPS = [ # file-browser 'grappelli', 'filebrowser', ... 'tinymce', ...] STATIC_URL = '/static/' STATICFILES_DIRS = [BASE_DIR / 'static'] STATIC_ROOT = BASE_DIR / 'staticfiles' MEDIA_ROOT = BASE_DIR / 'media' MEDIA_URL = '/media/' #django-filebrowser: # Path to filebrowser static files FILEBROWSER_DIRECTORY = 'filebrowser/' FILEBROWSER_STATIC_URL = STATIC_URL + 'filebrowser/' FILEBROWSER_MEDIA_ROOT = BASE_DIR / 'media/uploads/' FILEBROWSER_MEDIA_URL = '/filebrowser/media/' FILEBROWSER_SORT_BY = 'date' FILEBROWSER_MAX_UPLOAD_SIZE = 10485760 # 10 MB EXTENSIONS = { 'Image': ['.jpg','.jpeg','.gif','.png','.tif','.tiff'], 'Video': ['.mov','.wmv','.mpeg','.mpg','.avi','.rm'], 'Audio': ['.mp3','.mp4','.wav','.aiff','.midi','.m4p'], 'Document': ['.pdf','.doc','.rtf','.txt','.xls','.csv','.docx','.xlsx'] } SELECT_FORMATS = { 'File': ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'zip', 'rar', 'tar', 'gz', 'bz2', 'csv'], 'Image': ['jpg', 'jpeg', 'png', 'gif', 'tif', 'tiff'], 'Video': ['swf', 'flv', 'mpg', 'mpeg', 'mp4', 'mov', 'avi', 'wmv'], } #django-tinymce TINYMCE_JS_URL = 'https://cdn.tiny.cloud/1/{api-key}/tinymce/5/tinymce.min.js?referrerpolicy=origin' TINYMCE_DEFAULT_CONFIG = { "theme": "silver", "height": 500, "menubar": True, "plugins": "advlist,autolink,lists,link,image,charmap,print,preview,anchor,searchreplace,visualblocks,code,fullscreen,insertdatetime,media,table,paste,code,help,wordcount," "searchreplace,visualblocks,code,fullscreen,insertdatetime,media,table,paste," "code,help,wordcount", "toolbar": "undo redo | formatselect | bold italic backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | image | help | imageupload", "image_upload_url": "/media/uploads/images/", "file_picker_callback": "upload_image", 'file_browser_callback': 'mce_filebrowser' } TINYMCE_SPELLCHECKER = False TINYMCE_COMPRESSOR = False TINYMCE_FILEBROWSER = True
项目 urls.py 配置
... from filebrowser.sites import site ... urlpatterns = i18n_patterns( path('admin/filebrowser/', site.urls), path('grappelli/', include('grappelli.urls')), ... path('tinymce/', include('tinymce.urls')), ... if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
models.py 配置
... from filebrowser.fields import FileBrowseField class Post(TranslatableModel): ... translations = TranslatedFields( title = models.CharField(_('title'), max_length=250, blank=True, null=True), slug = models.SlugField(_('slug'), max_length=250, allow_unicode=True, blank=True, null=True), body = models.TextField(_('body'), blank=True, null=True) ) class Media(models.Model): MEDIA_TYPES = ( ('image', 'Image'), ('video', 'Video'), ('audio', 'Audio'), ) post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='media') media_file = FileBrowseField("File", max_length=200, directory="media/") media_type = models.CharField(max_length=10, choices=MEDIA_TYPES, default='image') def __str__(self): return f"{self.media_type} for post {self.post.title}"
forms.py 配置
... from django.conf import settings ... from tinymce.widgets import TinyMCE class PostForm(TranslatableModelForm): body = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}, mce_attrs={ 'file_browser_callback': 'filebrowser', 'file_browser_callback_url': '/admin/filebrowser/browse/', 'file_picker_callback': 'filebrowser', 'file_picker_callback_url': '/admin/filebrowser/browse/', })) language = LanguageField() class Meta: model = Post fields = ['featured_image', 'language', 'title', 'body', 'tags', 'publish', 'status'] widgets = { 'title': forms.TextInput(attrs={'class': 'hidden'}), 'slug': forms.TextInput(attrs={'class': 'hidden'}), }
解决方法
修正 TinyMCE 回调配置
TinyMCE 5+版本优先使用file_picker_callback,且你当前配置的upload_image未定义,会导致回调失效。修改TINYMCE_DEFAULT_CONFIG:TINYMCE_DEFAULT_CONFIG = { # 保留原有其他配置 "file_picker_callback": lambda callback, value, meta: mce_filebrowser(callback, value, meta), # 移除 file_browser_callback 配置 }统一表单回调设置
forms.py中同时设置两种回调会造成冲突,保留file_picker_callback即可:body = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}, mce_attrs={ 'file_picker_callback': 'mce_filebrowser', 'file_picker_callback_url': '/admin/filebrowser/browse/', }))检查文件目录与权限
- 确保
media/uploads目录存在,运行mkdir -p media/uploads并给目录设置读写权限 - 核对
FILEBROWSER_MEDIA_ROOT与FILEBROWSER_DIRECTORY的路径匹配,保证目录结构正确
- 确保
重新收集静态文件
执行python manage.py collectstatic,确保grappelli和filebrowser的静态资源被正确加载,避免因资源缺失导致按钮不显示验证 filebrowser 独立功能
直接访问/admin/filebrowser/browse/,检查是否能看到上传按钮。如果这里也没有,确认:INSTALLED_APPS中grappelli在filebrowser之前(顺序不能错)- 当前登录用户拥有filebrowser的操作权限
内容的提问来源于stack exchange,提问作者Rodrigo Yanez
相关产品推荐
相关产品推荐

