Working with Passwords
It's a comment use-case that you have a model
with a Password
field which needs a custom behaviour.
Let's say you have the following User
model:
class User(Base):
__tablename__ = "user"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(50))
hashed_password: Mapped[str] = mapped_column(String)
In this specific case we want the following features to be available in the Admin console:
- We only want
hashed_password
when creating a newUser
, and we want to hide it when editing aUser
. - When a User is created, the password should be hashed and stored in the
hashed_password
column.
So we define the following UserAdmin
class for it:
class UserAdmin(ModelView, model=User):
column_labels = {"hashed_password": "password"}
form_create_rules = ["name", "hashed_password"]
form_edit_rules = ["name"]
async def on_model_change(self, data, model, is_created, request) -> None:
if is_created:
# Hash the password before saving into DB !
data["hashed_password"] = data["hashed_password"] + "_hashed"
So let's see what is happening.
The column_labels
is just saying to rename hashed_password
to password
when displaying or creating a form for the User
.
Next we have defined two extra attributes called form_create_rules
and form_edit_rules
which
controls how the create and edit forms are created.
In the form_create_rules
declaration we specify we want name
and hashed_password
when creating a User
.
But in form_edit_rules
we specifically excluded hashed_password
so we only want to edit name
of the User
.
And finally the last step is to hash the password before saving into the database.
There could be a few options to do this, but in this case we are overriding on_model_change
and only hashing the password
when we are creating a User
.