pallets-eco / pallets-eco/flask-admin
fix(peewee): QueryAjaxModelLoader.get_one() raises DoesNotExist for a stale/absent pk
@hasansezertasan is already working on this.
Since Jul 31, 2026.
- Dominant language
- Python
- Stars
- 6.1k
- Forks
- 1.6k
- Avg merge
- 6d 14h
- Merged PRs (30d)
- 1
Description
Summary
QueryAjaxModelLoader.get_one() in the peewee backend calls self.model.get(...), which raises peewee's DoesNotExist when no row matches. Its caller, AjaxSelectField._get_data, guards with if model is not None — expecting None, not an exception — so a form referencing a since-deleted (or otherwise unmatched) pk crashes instead of rendering with no selection.
This is the autocomplete/ajax-select twin of the view-layer bug fixed in #2939 / #2924. That PR fixed ModelView.get_one(); this one was left deliberately out of scope there.
Location
flask_admin/contrib/peewee/ajax.py:57 get_one -> self.model.get(**{self.pk: pk})
flask_admin/model/fields.py:195 AjaxSelectField._get_data -> model = self.loader.get_one(...)
flask_admin/model/fields.py:197 if model is not None: # expects None on miss
Other backends
Both sibling loaders already return None on a miss, so peewee is the only one that lets the exception escape:
- sqla —
flask_admin/contrib/sqla/ajax.py:90:session.get(self.model, pk)returnsNone - mongoengine —
flask_admin/contrib/mongoengine/ajax.py:69:self.model.objects.filter(pk=pk).first()returnsNone
Proposed fix
Catch the module-level peewee.DoesNotExist in QueryAjaxModelLoader.get_one and return None, mirroring the fix in #2939:
def get_one(self, pk: t.Any) -> t.Any:
try:
return self.model.get(**{self.pk: pk})
except DoesNotExist:
return None
(Module-level DoesNotExist rather than self.model.DoesNotExist — each model subclasses it, and the module-level name is what passes mypy --strict.)
Scope note
As with #2939, a malformed pk against an integer primary key raises no error on sqlite (DoesNotExist covers it) but would raise a driver-specific DataError on Postgres. That's left out here too rather than importing driver exceptions into the backend.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.