Commit 18267649 authored by Sergey Markelov's avatar Sergey Markelov

Merge remote-tracking branch 'remotes/upstream/master'

parents 26742fb6 cfeaa030
......@@ -292,8 +292,8 @@ class BaseView(with_metaclass(AdminViewMeta, BaseViewClass)):
"""
This method will be executed before calling any view method.
By default, it will check if the admin class is accessible and if it is not it will
throw HTTP 404 error.
It will execute the ``inaccessible_callback`` if the view is not
accessible.
:param name:
View function name
......@@ -301,7 +301,17 @@ class BaseView(with_metaclass(AdminViewMeta, BaseViewClass)):
View function arguments
"""
if not self.is_accessible():
return abort(403)
return self.inaccessible_callback(name, **kwargs)
def inaccessible_callback(self, name, **kwargs):
"""
Handle the response to inaccessible views.
By default, it throw HTTP 403 error. Override this method to
customize the behaviour.
"""
return abort(403)
@property
def _debug(self):
......
......@@ -334,8 +334,8 @@ class ModelView(BaseModelView):
# TODO: Optimize me
for pk in ids:
self.coll.remove({'_id': self._get_valid_id(pk)})
count += 1
if self.delete_model(self.get_one(pk)):
count += 1
flash(ngettext('Model was successfully deleted.',
'%(count)s models were successfully deleted.',
......
......@@ -333,6 +333,9 @@ class ModelView(BaseModelView):
else:
column = p.columns[0]
if column.foreign_keys:
continue
if not self.column_display_pk and column.primary_key:
continue
......@@ -420,12 +423,12 @@ class ModelView(BaseModelView):
Verify if the provided column type is text-based.
:returns:
``True`` for ``String``, ``Unicode``, ``Text``, ``UnicodeText``
``True`` for ``String``, ``Unicode``, ``Text``, ``UnicodeText``, ``varchar``
"""
if name:
name = name.lower()
return name in ('string', 'unicode', 'text', 'unicodetext')
return name in ('string', 'unicode', 'text', 'unicodetext', 'varchar')
def scaffold_filters(self, name):
"""
......@@ -605,6 +608,11 @@ class ModelView(BaseModelView):
def get_count_query(self):
"""
Return a the count query for the model type
A query(self.model).count() approach produces an excessive
subquery, so query(func.count('*')) should be used instead.
See #45a2723 commit message for details.
"""
return self.session.query(func.count('*')).select_from(self.model)
......@@ -783,7 +791,7 @@ class ModelView(BaseModelView):
flash(gettext('Integrity error. %(message)s', message=exc.message), 'error')
return True
return super(BaseModelView, self).handle_view_exception(exc)
return super(ModelView, self).handle_view_exception(exc)
# Model handlers
def create_model(self, form):
......@@ -882,8 +890,8 @@ class ModelView(BaseModelView):
count = 0
for m in query.all():
self.session.delete(m)
count += 1
if self.delete_model(m):
count += 1
self.session.commit()
......
......@@ -181,9 +181,10 @@ class FileUploadField(fields.StringField):
map(lambda x: x.lower(), self.allowed_extensions))
def pre_validate(self, form):
if (self.data and
isinstance(self.data, FileStorage) and
not self.is_file_allowed(self.data.filename)):
if (self.data
and self.data.filename
and isinstance(self.data, FileStorage)
and not self.is_file_allowed(self.data.filename)):
raise ValidationError(gettext('Invalid file extension'))
def process(self, formdata, data=unset_value):
......@@ -237,7 +238,7 @@ class FileUploadField(fields.StringField):
def _save_file(self, data, filename):
path = self._get_path(filename)
if not op.exists(op.dirname(path)):
os.makedirs(os.path.dirname(path), self.permission)
os.makedirs(os.path.dirname(path), self.permission | 0o111)
data.save(path)
......@@ -355,7 +356,9 @@ class ImageUploadField(FileUploadField):
def pre_validate(self, form):
super(ImageUploadField, self).pre_validate(form)
if self.data and isinstance(self.data, FileStorage):
if (self.data and
isinstance(self.data, FileStorage) and
self.data.filename):
try:
self.image = Image.open(self.data)
except Exception as e:
......
......@@ -366,13 +366,13 @@ class BaseModelView(BaseView, ActionsMixin):
}
}
Note, changing the format of a DateTimeField will require changes to both form_widget_args and form_args:
Note, changing the format of a DateTimeField will require changes to both form_widget_args and form_args::
form_args = dict(
start=dict(format='%Y-%m-%d %H:%M') # changes how the input is parsed by strptime
start=dict(format='%Y-%m-%d %I:%M %p') # changes how the input is parsed by strptime (12 hour time)
)
form_widget_args = dict(
start={'data-date-format': u'yyyy-mm-dd hh:ii'} # changes how the DateTimeField displays the time
start={'data-date-format': u'yyyy-mm-dd HH:ii P', 'data-show-meridian': 'True'} # changes how the DateTimeField displays the time
)
"""
......
......@@ -140,7 +140,7 @@
var $parentForm = $el.parent().closest('.inline-field');
if ($parentForm.length > 0) {
if ($parentForm.length > 0 && elID.indexOf($parentForm.attr('id')) !== 0) {
id = $parentForm.attr('id') + '-' + elID;
}
......
from nose.tools import ok_, eq_, raises
from flask import Flask, request
from flask import Flask, request, abort
from flask.views import MethodView
from flask.ext.admin import base
......@@ -232,6 +232,20 @@ def test_permissions():
eq_(rv.status_code, 403)
def test_inaccessible_callback():
app = Flask(__name__)
admin = base.Admin(app)
view = MockView()
admin.add_view(view)
client = app.test_client()
view.allow_access = False
view.inaccessible_callback = lambda *args, **kwargs: abort(418)
rv = client.get('/admin/mockview/')
eq_(rv.status_code, 418)
def get_visibility():
app = Flask(__name__)
admin = base.Admin(app)
......
# Portuguese translations for Flask-Admin.
# Copyright (C) 2014 Koneksa Automação
# This file is distributed under the same license as the Flask-Admin
# project.
# Jonnas Fonini <jonnas@koneksa.com.br>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: Flask-Admin\n"
"Report-Msgid-Bugs-To: jonnas@koneksa.com.br\n"
"POT-Creation-Date: 2014-05-28 13:45-0300\n"
"PO-Revision-Date: 2014-05-28 14:18-0300\n"
"Last-Translator: Jonnas Fonini <jonnas@koneksa.com.br>\n"
"Language-Team: pt <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 1.3\n"
"X-Generator: Poedit 1.5.4\n"
#: ../flask_admin/base.py:339
msgid "Home"
msgstr "Início"
#: ../flask_admin/contrib/fileadmin.py:33
msgid "Invalid directory name"
msgstr "Nome de diretório inválido"
#: ../flask_admin/contrib/fileadmin.py:41
msgid "File to upload"
msgstr "Arquivo para upload"
#: ../flask_admin/contrib/fileadmin.py:50
msgid "File required."
msgstr "Arquivo requerido."
#: ../flask_admin/contrib/fileadmin.py:55
msgid "Invalid file type."
msgstr "Tipo de arquivo inválido."
#: ../flask_admin/contrib/fileadmin.py:59
msgid "Content"
msgstr "Conteúdo"
#: ../flask_admin/contrib/fileadmin.py:423
#, python-format
msgid "File \"%(name)s\" already exists."
msgstr "O arquivo \"%(name)s\" já existe."
#: ../flask_admin/contrib/fileadmin.py:442
#: ../flask_admin/contrib/fileadmin.py:505
#: ../flask_admin/contrib/fileadmin.py:558
#: ../flask_admin/contrib/fileadmin.py:595
#: ../flask_admin/contrib/fileadmin.py:638
#: ../flask_admin/contrib/fileadmin.py:684
msgid "Permission denied."
msgstr "Permissão negada."
#: ../flask_admin/contrib/fileadmin.py:501
msgid "File uploading is disabled."
msgstr "O Upload de arquivos está desabilitado."
#: ../flask_admin/contrib/fileadmin.py:514
#, python-format
msgid "Failed to save file: %(error)s"
msgstr "Falha ao gravar arquivo: %(error)s"
#: ../flask_admin/contrib/fileadmin.py:554
msgid "Directory creation is disabled."
msgstr "A criação de diretórios está desabilitada."
#: ../flask_admin/contrib/fileadmin.py:569
#, python-format
msgid "Failed to create directory: %(error)s"
msgstr "Falha ao criar diretório: %(error)s"
#: ../flask_admin/contrib/fileadmin.py:591
msgid "Deletion is disabled."
msgstr "Exclusão está desabilitada."
#: ../flask_admin/contrib/fileadmin.py:600
msgid "Directory deletion is disabled."
msgstr "Exclusão de diretórios está desabilitada"
#: ../flask_admin/contrib/fileadmin.py:606
#, python-format
msgid "Directory \"%(path)s\" was successfully deleted."
msgstr "Diretório \"%(path)s\" foi excluído com sucesso."
#: ../flask_admin/contrib/fileadmin.py:608
#, python-format
msgid "Failed to delete directory: %(error)s"
msgstr "Falha ao excluir diretório: %(error)s"
#: ../flask_admin/contrib/fileadmin.py:613
#: ../flask_admin/contrib/fileadmin.py:750
#, python-format
msgid "File \"%(name)s\" was successfully deleted."
msgstr "Arquivo \"%(name)s\" foi excluído com sucesso."
#: ../flask_admin/contrib/fileadmin.py:615
#: ../flask_admin/contrib/fileadmin.py:752
#, python-format
msgid "Failed to delete file: %(name)s"
msgstr "Falha ao excluir arquivo: %(name)s"
#: ../flask_admin/contrib/fileadmin.py:634
msgid "Renaming is disabled."
msgstr "Renomear está desabilitado."
#: ../flask_admin/contrib/fileadmin.py:642
msgid "Path does not exist."
msgstr "O caminho não existe."
#: ../flask_admin/contrib/fileadmin.py:654
#, python-format
msgid "Successfully renamed \"%(src)s\" to \"%(dst)s\""
msgstr "Renomeado com sucesso: de \"%(src)s\" para \"%(dst)s\""
#: ../flask_admin/contrib/fileadmin.py:657
#, python-format
msgid "Failed to rename: %(error)s"
msgstr "Falha ao renomear: %(error)s"
#: ../flask_admin/contrib/fileadmin.py:700
#, python-format
msgid "Error saving changes to %(name)s."
msgstr "Erro ao salvar alterações para %(name)s."
#: ../flask_admin/contrib/fileadmin.py:704
#, python-format
msgid "Changes to %(name)s saved successfully."
msgstr "Alterações para %(name)s salvas com sucesso."
#: ../flask_admin/contrib/fileadmin.py:711
#, python-format
msgid "Error reading %(name)s."
msgstr "Erro ao ler %(name)s."
#: ../flask_admin/contrib/fileadmin.py:714
#: ../flask_admin/contrib/fileadmin.py:723
#, python-format
msgid "Unexpected error while reading from %(name)s"
msgstr "Erro inesperado ao ler %(name)s"
#: ../flask_admin/contrib/fileadmin.py:720
#, python-format
msgid "Cannot edit %(name)s."
msgstr "Não é ṕossível editar %(name)s."
#: ../flask_admin/contrib/fileadmin.py:737
#: ../flask_admin/contrib/mongoengine/view.py:587
#: ../flask_admin/contrib/peewee/view.py:405
#: ../flask_admin/contrib/pymongo/view.py:329
#: ../flask_admin/contrib/sqla/view.py:873
msgid "Delete"
msgstr "Excluir"
#: ../flask_admin/contrib/fileadmin.py:738
msgid "Are you sure you want to delete these files?"
msgstr "Você tem certeza que deseja excluir estes arquivos?"
#: ../flask_admin/contrib/fileadmin.py:741
msgid "File deletion is disabled."
msgstr "Exclusão de arquivos desabilitada."
#: ../flask_admin/contrib/fileadmin.py:754
msgid "Edit"
msgstr "Editar"
#: ../flask_admin/contrib/rediscli.py:125
msgid "Cli: Invalid command."
msgstr "Cli: Comando inválido"
#: ../flask_admin/contrib/mongoengine/filters.py:36
#: ../flask_admin/contrib/peewee/filters.py:35
#: ../flask_admin/contrib/pymongo/filters.py:38
#: ../flask_admin/contrib/sqla/filters.py:36
msgid "equals"
msgstr "igual"
#: ../flask_admin/contrib/mongoengine/filters.py:45
#: ../flask_admin/contrib/peewee/filters.py:43
#: ../flask_admin/contrib/pymongo/filters.py:47
#: ../flask_admin/contrib/sqla/filters.py:44
msgid "not equal"
msgstr "diferente"
#: ../flask_admin/contrib/mongoengine/filters.py:55
#: ../flask_admin/contrib/peewee/filters.py:52
#: ../flask_admin/contrib/pymongo/filters.py:57
#: ../flask_admin/contrib/sqla/filters.py:53
msgid "contains"
msgstr "contém"
#: ../flask_admin/contrib/mongoengine/filters.py:65
#: ../flask_admin/contrib/peewee/filters.py:61
#: ../flask_admin/contrib/pymongo/filters.py:67
#: ../flask_admin/contrib/sqla/filters.py:62
msgid "not contains"
msgstr "não contém"
#: ../flask_admin/contrib/mongoengine/filters.py:74
#: ../flask_admin/contrib/peewee/filters.py:69
#: ../flask_admin/contrib/pymongo/filters.py:76
#: ../flask_admin/contrib/sqla/filters.py:70
msgid "greater than"
msgstr "maior que"
#: ../flask_admin/contrib/mongoengine/filters.py:83
#: ../flask_admin/contrib/peewee/filters.py:77
#: ../flask_admin/contrib/pymongo/filters.py:85
#: ../flask_admin/contrib/sqla/filters.py:78
msgid "smaller than"
msgstr "menor que"
#: ../flask_admin/contrib/mongoengine/view.py:478
#, python-format
msgid "Failed to get model. %(error)s"
msgstr "Falha ao obter model. %(error)s"
#: ../flask_admin/contrib/mongoengine/view.py:499
#: ../flask_admin/contrib/peewee/view.py:355
#: ../flask_admin/contrib/pymongo/view.py:264
#: ../flask_admin/contrib/sqla/view.py:806
#, python-format
msgid "Failed to create model. %(error)s"
msgstr "Falha ao criar model. %(error)s"
#: ../flask_admin/contrib/mongoengine/view.py:526
#: ../flask_admin/contrib/peewee/view.py:375
#: ../flask_admin/contrib/pymongo/view.py:289
#: ../flask_admin/contrib/sqla/view.py:832
#, python-format
msgid "Failed to update model. %(error)s"
msgstr "Falha ao atualizar model. %(error)s"
#: ../flask_admin/contrib/mongoengine/view.py:551
#: ../flask_admin/contrib/peewee/view.py:392
#: ../flask_admin/contrib/pymongo/view.py:315
#: ../flask_admin/contrib/sqla/view.py:859
#, python-format
msgid "Failed to delete model. %(error)s"
msgstr "Falha ao excluir model. %(error)s"
#: ../flask_admin/contrib/mongoengine/view.py:588
#: ../flask_admin/contrib/peewee/view.py:406
#: ../flask_admin/contrib/pymongo/view.py:330
#: ../flask_admin/contrib/sqla/view.py:874
msgid "Are you sure you want to delete selected models?"
msgstr "Você tem certeza que deseja excluir os models selecionados?"
#: ../flask_admin/contrib/mongoengine/view.py:597
#: ../flask_admin/contrib/peewee/view.py:422
#: ../flask_admin/contrib/pymongo/view.py:340
#: ../flask_admin/contrib/sqla/view.py:890
#, python-format
msgid "Model was successfully deleted."
msgid_plural "%(count)s models were successfully deleted."
msgstr[0] "Model was successfully deleted."
msgstr[1] "%(count)s models foram excluídos com sucesso."
#: ../flask_admin/contrib/mongoengine/view.py:605
#: ../flask_admin/contrib/peewee/view.py:430
#: ../flask_admin/contrib/pymongo/view.py:345
#: ../flask_admin/contrib/sqla/view.py:898
#, python-format
msgid "Failed to delete models. %(error)s"
msgstr "Falha ao excluir models. %(error)s"
#: ../flask_admin/contrib/sqla/fields.py:123
#: ../flask_admin/contrib/sqla/fields.py:173
#: ../flask_admin/contrib/sqla/fields.py:178
#: ../flask_admin/model/fields.py:164 ../flask_admin/model/fields.py:213
msgid "Not a valid choice"
msgstr "Não é uma escolha válida"
#: ../flask_admin/contrib/sqla/validators.py:38
msgid "Already exists."
msgstr "Já existe."
#: ../flask_admin/contrib/sqla/view.py:783
#, python-format
msgid "Integrity error. %(message)s"
msgstr "Erro de integridade. %(message)s"
#: ../flask_admin/form/fields.py:89
msgid "Invalid time format"
msgstr "Formato de hora inválido"
#: ../flask_admin/form/fields.py:133
msgid "Invalid Choice: could not coerce"
msgstr "Escolha inválida: não é possível converter"
#: ../flask_admin/form/upload.py:187
msgid "Invalid file extension"
msgstr "Extensão de arquivo inválida"
#: ../flask_admin/model/base.py:1012
msgid "There are no items in the table."
msgstr "Não existem itens na tabela."
#: ../flask_admin/model/base.py:1257
msgid "Model was successfully created."
msgstr "Model criado com sucesso."
#: ../flask_admin/model/base.py:1294
msgid "Model was successfully saved."
msgstr "Model salvo com sucesso."
#: ../flask_admin/model/filters.py:91
msgid "Yes"
msgstr "Sim"
#: ../flask_admin/model/filters.py:92
msgid "No"
msgstr "Não"
#: ../flask_admin/templates/bootstrap2/admin/actions.html:4
#: ../flask_admin/templates/bootstrap3/admin/actions.html:4
msgid "With selected"
msgstr "Com o(s) selecionado(s)"
#: ../flask_admin/templates/bootstrap2/admin/lib.html:151
#: ../flask_admin/templates/bootstrap3/admin/lib.html:144
msgid "Submit"
msgstr "Salvar"
#: ../flask_admin/templates/bootstrap2/admin/lib.html:156
#: ../flask_admin/templates/bootstrap3/admin/lib.html:149
msgid "Cancel"
msgstr "Cancelar"
#: ../flask_admin/templates/bootstrap2/admin/file/edit.html:5
#: ../flask_admin/templates/bootstrap3/admin/file/edit.html:5
#, python-format
msgid "You are editing %(path)s"
msgstr "Você está editando %(path)s"
#: ../flask_admin/templates/bootstrap2/admin/file/list.html:9
#: ../flask_admin/templates/bootstrap3/admin/file/list.html:9
msgid "Root"
msgstr "Raíz"
#: ../flask_admin/templates/bootstrap2/admin/file/list.html:62
#: ../flask_admin/templates/bootstrap3/admin/file/list.html:62
#, python-format
msgid "Are you sure you want to delete \\'%(name)s\\' recursively?"
msgstr "Você tem certeza que deseja excluir \\'%(name)s\\' recursivamente?"
#: ../flask_admin/templates/bootstrap2/admin/file/list.html:70
#: ../flask_admin/templates/bootstrap3/admin/file/list.html:70
#, python-format
msgid "Are you sure you want to delete \\'%(name)s\\'?"
msgstr "Você tem certeza que deseja excluir \\'%(name)s\\'?"
#: ../flask_admin/templates/bootstrap2/admin/file/list.html:105
#: ../flask_admin/templates/bootstrap3/admin/file/list.html:105
msgid "Upload File"
msgstr "Upload de arquivo"
#: ../flask_admin/templates/bootstrap2/admin/file/list.html:110
#: ../flask_admin/templates/bootstrap3/admin/file/list.html:110
msgid "Create Directory"
msgstr "Criar diretório"
#: ../flask_admin/templates/bootstrap2/admin/file/list.html:127
#: ../flask_admin/templates/bootstrap3/admin/file/list.html:127
msgid "Please select at least one file."
msgstr "Por favor, selecione pelo menos um arquivo."
#: ../flask_admin/templates/bootstrap2/admin/file/rename.html:5
#: ../flask_admin/templates/bootstrap3/admin/file/rename.html:5
#, python-format
msgid "Please provide new name for %(name)s"
msgstr "Por favor, informe um novo nome para %(name)s"
#: ../flask_admin/templates/bootstrap2/admin/model/create.html:6
#: ../flask_admin/templates/bootstrap3/admin/model/create.html:6
msgid "Save and Add"
msgstr "Salvar e Adicionar"
#: ../flask_admin/templates/bootstrap2/admin/model/create.html:18
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:17
#: ../flask_admin/templates/bootstrap3/admin/model/create.html:18
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:17
msgid "List"
msgstr "Listar"
#: ../flask_admin/templates/bootstrap2/admin/model/create.html:21
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:21
#: ../flask_admin/templates/bootstrap3/admin/model/create.html:21
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:21
msgid "Create"
msgstr "Criar"
#: ../flask_admin/templates/bootstrap2/admin/model/edit.html:6
#: ../flask_admin/templates/bootstrap3/admin/model/edit.html:6
msgid "Save and Continue"
msgstr "Salvar e Continuar"
#: ../flask_admin/templates/bootstrap2/admin/model/inline_list_base.html:10
#: ../flask_admin/templates/bootstrap3/admin/model/inline_list_base.html:10
msgid "Delete?"
msgstr "Excluir?"
#: ../flask_admin/templates/bootstrap2/admin/model/inline_list_base.html:33
#: ../flask_admin/templates/bootstrap3/admin/model/inline_list_base.html:33
msgid "Add"
msgstr "Adicionar"
#: ../flask_admin/templates/bootstrap2/admin/model/layout.html:3
#: ../flask_admin/templates/bootstrap3/admin/model/layout.html:3
msgid "Add Filter"
msgstr "Adicionar Filtro"
#: ../flask_admin/templates/bootstrap2/admin/model/layout.html:17
#: ../flask_admin/templates/bootstrap3/admin/model/layout.html:17
msgid "Apply"
msgstr "Aplicar"
#: ../flask_admin/templates/bootstrap2/admin/model/layout.html:19
#: ../flask_admin/templates/bootstrap3/admin/model/layout.html:19
msgid "Reset Filters"
msgstr "Limpar Filtros"
#: ../flask_admin/templates/bootstrap2/admin/model/layout.html:30
#: ../flask_admin/templates/bootstrap3/admin/model/layout.html:30
msgid "Remove Filter"
msgstr "Remover Filtros"
#: ../flask_admin/templates/bootstrap2/admin/model/layout.html:69
#: ../flask_admin/templates/bootstrap2/admin/model/layout.html:76
#: ../flask_admin/templates/bootstrap3/admin/model/layout.html:69
#: ../flask_admin/templates/bootstrap3/admin/model/layout.html:76
msgid "Search"
msgstr "Pesquisar"
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:21
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:21
msgid "Create new record"
msgstr "Criar novo registro"
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:57
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:57
msgid "Select all records"
msgstr "Selecionar todos os registros"
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:68
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:77
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:68
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:77
#, python-format
msgid "Sort by %(name)s"
msgstr "Ordenar por %(name)s"
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:99
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:99
msgid "Select record"
msgstr "Selecionar registro"
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:115
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:115
msgid "You sure you want to delete this item?"
msgstr "Você tem certeza que deseja excluir este item?"
#: ../flask_admin/templates/bootstrap2/admin/model/list.html:152
#: ../flask_admin/templates/bootstrap3/admin/model/list.html:152
msgid "Please select at least one model."
msgstr "Por favor, selecione pelo menos um model."
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