Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ['3.10', '3.11', '3.12', '3.13']
python: ['3.10', '3.11', '3.12', '3.13', '3.14']
tox: ['normal']
include:
- python: '3.10'
tox: 'py310-min'
- python: '3.13'
tox: 'py313-noflaskbabel'
- python: '3.14'
tox: 'py314-noflaskbabel'
- python: '3.10'
tox: 'py310-sqlalchemy1'
- python: '3.13'
tox: 'py313-sqlalchemy1'
- python: '3.14'
tox: 'py314-sqlalchemy1'
services:
# Label used to access the service container
postgres:
Expand Down
1 change: 1 addition & 0 deletions examples/mongoengine/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class TweetView(ModelView):
column_sortable_list = ("name", "text")

column_filters = (
"text",
filters.FilterEqual("name", "Name"),
filters.FilterNotEqual("name", "Name"),
filters.FilterLike("name", "Name"),
Expand Down
5 changes: 4 additions & 1 deletion flask_admin/contrib/mongoengine/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,10 @@ def convert(self, type_name, column, name):
filter_name = type_name.lower()

if filter_name in self.converters:
return self.converters[filter_name](column, name)
if isinstance(column, str):
return self.converters[filter_name](column, name)

return self.converters[filter_name](column.name, name)

return None

Expand Down
13 changes: 7 additions & 6 deletions flask_admin/contrib/mongoengine/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from flask_admin.model import BaseModelView
from flask_admin.model.form import create_editable_list_form

from ...model.filters import BaseFilter
from .ajax import create_ajax_loader
from .ajax import process_ajax_references
from .filters import BaseMongoEngineFilter
Expand Down Expand Up @@ -60,13 +59,15 @@ class ModelView(BaseModelView):
MongoEngine model scaffolding.
"""

column_filters: t.Collection[str | BaseFilter] | None = None
column_filters: t.Collection[str | BaseMongoEngineFilter] | None = None
"""
Collection of the column filters.
Collection of column filters used in the list view.

Can contain either field names or instances of
:class:`flask_admin.contrib.mongoengine.filters.BaseMongoEngineFilter`
classes.
Can contain either:
- Field names (str): allow any appropriate filter operation based on the
field’s data type.
- Instances of :class:`~flask_admin.contrib.mongoengine.filters.BaseFilter`
classes: restrict or customize which filters are available for a specific field.

Filters will be grouped by name when displayed in the drop-down.

Expand Down
5 changes: 4 additions & 1 deletion flask_admin/tests/geoa/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@


@pytest.fixture
def db():
def db(app):
db = SQLAlchemy()
yield db
with app.app_context():
db.session.close()
db.engine.dispose()


@pytest.fixture
Expand Down
20 changes: 18 additions & 2 deletions flask_admin/tests/mongoengine/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class TestView(ModelView):
form = TestForm

column_filters = (
"test1",
filters.FilterEqual("test1", "test1"),
filters.FilterEqual("test2", "test2"),
)
Expand All @@ -52,8 +53,23 @@ def test_model(app, db, admin):
assert view._edit_form_class is not None
assert not view._search_supported
assert view._filters
assert all(isinstance(f, filters.FilterEqual) for f in view._filters)
assert [f.__dict__ for f in view._filters] == [
for f, f_type in zip(
view._filters,
(
filters.FilterLike,
filters.FilterNotLike,
filters.FilterEqual,
filters.FilterNotEqual,
filters.FilterEmpty,
filters.FilterInList,
filters.FilterNotInList,
filters.FilterEqual,
filters.FilterEqual,
),
strict=True,
):
assert isinstance(f, f_type)
assert [f.__dict__ for f in view._filters[-2:]] == [
{
"name": "test1",
"options": None,
Expand Down
5 changes: 3 additions & 2 deletions flask_admin/tests/peeweemodel/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@


@pytest.fixture
def db():
def db(app):
db = peewee.SqliteDatabase(":memory:")
yield db
db.close()
with app.app_context():
db.close()


@pytest.fixture
Expand Down
8 changes: 8 additions & 0 deletions flask_admin/tests/sqla/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def db(app):
db = SQLAlchemy(app)
yield db

with app.app_context():
db.session.close()
db.engine.dispose()


@pytest.fixture
def postgres_db(app):
Expand All @@ -40,6 +44,10 @@ def postgres_db(app):
db = SQLAlchemy(app)
yield db

with app.app_context():
db.session.close()
db.engine.dispose()


@pytest.fixture
def admin(app, babel, db):
Expand Down
1 change: 1 addition & 0 deletions flask_admin/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ def test_add_views(admin):
assert len(admin.menu()) == 3


@pytest.mark.filterwarnings("ignore:unclosed file:ResourceWarning")
def test_add_category(admin):
admin.add_category("Category1", "class-name", "icon-type", "icon-value")
admin.add_view(MockView(name="Test 1", endpoint="test1", category="Category1"))
Expand Down
24 changes: 14 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ classifiers = [
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
]
requires-python = ">=3.10"
dependencies = [
Expand Down Expand Up @@ -164,8 +165,11 @@ filterwarnings = [
# `flask.testing` accesses this attribute; remove when they have updated their code.
"default:The '__version__' attribute is deprecated and will be removed in Werkzeug 3\\.1\\.:DeprecationWarning",

# raised by flask-sqlalchemy https://github.com/pallets-eco/flask-sqlalchemy/issues/137
# raised by flask-sqlalchemy https://github.com/pallets-eco/flask-sqlalchemy/issues/1379
"ignore:Exception ignored in.*sqlite3.Connection:pytest.PytestUnraisableExceptionWarning",

# raised by flask-sqlalchemy https://github.com/pallets-eco/flask-sqlalchemy/issues/1379
"ignore:unclosed database in <sqlite3\\.Connection object at 0x[0-9a-f]+>:ResourceWarning",
]

[tool.coverage.run]
Expand Down Expand Up @@ -262,9 +266,9 @@ order-by-type = false

[tool.tox]
env_list = [
"py310", "py311", "py312", "py313",
"py310-sqlalchemy1", "py313-sqlalchemy1",
"py313-noflaskbabel",
"py310", "py311", "py312", "py313", "py314",
"py310-sqlalchemy1", "py314-sqlalchemy1",
"py314-noflaskbabel",
"py310-min",
"style",
"typing",
Expand Down Expand Up @@ -338,10 +342,10 @@ commands = [
],
]

[tool.tox.env.py313-sqlalchemy1]
description = "pytest with SQLAlchemy 1.x on Python 3.13"
[tool.tox.env.py314-sqlalchemy1]
description = "pytest with SQLAlchemy 1.x on Python 3.14"
base = ["env_run_base"]
base_python = ["3.13"]
base_python = ["3.14"]
commands = [
["uv", "pip", "install", "sqlalchemy>=1.4,<2"],
["uv", "pip", "install", "flask-sqlalchemy<=3.0.5"],
Expand All @@ -351,7 +355,7 @@ commands = [
],
]

[tool.tox.env.py313-noflaskbabel]
[tool.tox.env.py314-noflaskbabel]
description = "pytest without flask-babel"
base = ["env_run_base"]
commands = [
Expand All @@ -374,8 +378,8 @@ description = "run static type checkers"
dependency_groups = ["typing"]
commands = [
["mypy", "--python-version", "3.10"],
["mypy", "--python-version", "3.13"],
["mypy", "--python-version", "3.13",
["mypy", "--python-version", "3.14"],
["mypy", "--python-version", "3.14",
"--ignore-missing-imports",
"--disable-error-code", "name-defined", # allow flask_sqlalchemy's db.Model in examples
"--no-warn-unused-ignores", # prevent conflict with mypy 1st run on src folder
Expand Down
Loading