Commit 4955d10d authored by Serge S. Koval's avatar Serge S. Koval

Fixed #264. Now it is possible to delete files/images in MongoEngine backend....

Fixed #264. Now it is possible to delete files/images in MongoEngine backend. Also improved Save and Continue
parent 31f6c86c
from flask import request from flask import request
from wtforms import fields from wtforms import fields
from wtforms.fields.core import _unset_value
from . import widgets from . import widgets
...@@ -25,9 +26,27 @@ class ModelFormField(fields.FormField): ...@@ -25,9 +26,27 @@ class ModelFormField(fields.FormField):
class MongoFileField(fields.FileField): class MongoFileField(fields.FileField):
widget = widgets.MongoFileInput() widget = widgets.MongoFileInput()
def __init__(self, label=None, validators=None, **kwargs):
super(MongoFileField, self).__init__(label, validators, **kwargs)
self.should_delete = False
def process(self, formdata, data=_unset_value):
if formdata:
marker = '_%s-delete' % self.name
if marker in formdata:
self.should_delete = True
return super(MongoFileField, self).process(formdata, data)
def populate_obj(self, obj, name): def populate_obj(self, obj, name):
field = getattr(obj, name, None) field = getattr(obj, name, None)
if field is not None: if field is not None:
# If field should be deleted, clean it up
if self.should_delete:
field.delete()
return
data = request.files.get(self.name) data = request.files.get(self.name)
if data: if data:
......
...@@ -10,6 +10,9 @@ from . import helpers ...@@ -10,6 +10,9 @@ from . import helpers
def grid_formatter(view, value): def grid_formatter(view, value):
if not value.grid_id:
return ''
args = helpers.make_gridfs_args(value) args = helpers.make_gridfs_args(value)
return Markup( return Markup(
...@@ -25,6 +28,9 @@ def grid_formatter(view, value): ...@@ -25,6 +28,9 @@ def grid_formatter(view, value):
def grid_image_formatter(view, value): def grid_image_formatter(view, value):
if not value.grid_id:
return ''
return Markup( return Markup(
('<div class="image-thumbnail">' + ('<div class="image-thumbnail">' +
'<a href="%(url)s" target="_blank"><img src="%(thumb)s"/></a>' + '<a href="%(url)s" target="_blank"><img src="%(thumb)s"/></a>' +
......
...@@ -343,7 +343,13 @@ class ModelView(BaseModelView): ...@@ -343,7 +343,13 @@ class ModelView(BaseModelView):
:param id: :param id:
Model ID Model ID
""" """
return self.get_query().filter(pk=id).first() try:
return self.get_query().filter(pk=id).first()
except mongoengine.ValidationError as ex:
flash(gettext('Failed to get model. %(error)s',
error=format_error(ex)),
'error')
return None
def create_model(self, form): def create_model(self, form):
""" """
......
...@@ -12,7 +12,10 @@ class MongoFileInput(object): ...@@ -12,7 +12,10 @@ class MongoFileInput(object):
""" """
Renders a file input chooser field. Renders a file input chooser field.
""" """
template = '<div><i class="icon-file"></i>%(name)s %(size)dk (%(content_type)s)</div>' template = ('<div>'
' <i class="icon-file"></i>%(name)s %(size)dk (%(content_type)s)'
' <input type="checkbox" name="%(marker)s">Delete</input>'
'</div>')
def __call__(self, field, **kwargs): def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id) kwargs.setdefault('id', field.id)
...@@ -24,7 +27,8 @@ class MongoFileInput(object): ...@@ -24,7 +27,8 @@ class MongoFileInput(object):
placeholder = self.template % { placeholder = self.template % {
'name': escape(data.name), 'name': escape(data.name),
'content_type': escape(data.content_type), 'content_type': escape(data.content_type),
'size': data.length // 1024 'size': data.length // 1024,
'marker': '_%s-delete' % field.name
} }
return HTMLString('%s<input %s>' % (placeholder, return HTMLString('%s<input %s>' % (placeholder,
...@@ -37,7 +41,10 @@ class MongoImageInput(object): ...@@ -37,7 +41,10 @@ class MongoImageInput(object):
""" """
Renders a file input chooser field. Renders a file input chooser field.
""" """
template = '<div class="image-thumbnail"><img src="%(thumb)s"/></div>' template = ('<div class="image-thumbnail">'
' <img src="%(thumb)s"/>'
' <input type="checkbox" name="%(marker)s">Delete</input>'
'</div>')
def __call__(self, field, **kwargs): def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id) kwargs.setdefault('id', field.id)
...@@ -46,7 +53,8 @@ class MongoImageInput(object): ...@@ -46,7 +53,8 @@ class MongoImageInput(object):
if field.data and isinstance(field.data, ImageGridFsProxy): if field.data and isinstance(field.data, ImageGridFsProxy):
args = helpers.make_thumb_args(field.data) args = helpers.make_thumb_args(field.data)
placeholder = self.template % { placeholder = self.template % {
'thumb': url_for('.api_file_view', **args) 'thumb': url_for('.api_file_view', **args),
'marker': '_%s-delete' % field.name
} }
return HTMLString('%s<input %s>' % (placeholder, return HTMLString('%s<input %s>' % (placeholder,
......
...@@ -1092,9 +1092,7 @@ class BaseModelView(BaseView, ActionsMixin): ...@@ -1092,9 +1092,7 @@ class BaseModelView(BaseView, ActionsMixin):
if self.update_model(form, model): if self.update_model(form, model):
if '_continue_editing' in request.form: if '_continue_editing' in request.form:
flash(gettext('Model was successfully saved.')) flash(gettext('Model was successfully saved.'))
return redirect(request.full_path)
# Recreate form
form = self.edit_form(obj=model)
else: else:
return redirect(return_url) return redirect(return_url)
......
import sys import sys
import warnings
import traceback import traceback
# Python 3 compatibility # Python 3 compatibility
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment