Skip to content
Open
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
42 changes: 39 additions & 3 deletions examples/sqla/admin/data.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import datetime
import random
from datetime import date
from datetime import datetime
from datetime import time
from datetime import timedelta

import arrow
from admin import db
from admin.models import AVAILABLE_USER_TYPES
from admin.models import Model1
from admin.models import Post
from admin.models import Tag
from admin.models import Tree
Expand Down Expand Up @@ -69,7 +74,7 @@ def build_sample_db():
"Davies",
"Rodriguez",
"Cox",
"Alexander",
None,
]

countries = [
Expand Down Expand Up @@ -181,7 +186,7 @@ def build_sample_db():
post.text = entry["content"]
post.background_color = random.choice(["#cccccc", "red", "lightblue", "#0f0"])
tmp_days = int(1000 * random.random())
post.date = datetime.datetime.now() - datetime.timedelta(days=tmp_days)
post.date = datetime.now() - timedelta(days=tmp_days)
post.tags = random.sample(tag_list, 2)
db.session.add(post)

Expand All @@ -198,5 +203,36 @@ def build_sample_db():
leaf.parent = branch
db.session.add(leaf)

obj1 = Model1("test1_val_1", "test2_val_1", bool_field=True)
obj4 = Model1(
"test1_val_4",
"test2_val_4",
date_field=date(2014, 11, 17),
time_field=time(11, 10, 9),
datetime_field=datetime(2014, 4, 3, 1, 9, 0),
email_field="test@test.com",
choice_field="choice-1",
enum_field="model1_v2",
enum_type_field=Model1.EnumChoices.second,
)
obj4.sqla_utils_choice = "choice-2"
obj4.sqla_utils_enum = Model1.EnumChoices.second
obj4.sqla_utils_arrow = arrow.utcnow()
obj4.sqla_utils_uuid = "123e4567-e89b-12d3-a456-426614174000"
obj4.sqla_utils_url = "https://www.example.com"
obj4.sqla_utils_ip_address = "192.168.1.1"
obj4.sqla_utils_currency = "USD"
obj4.sqla_utils_color = "#123456"

empty_obj = Model1(test2="empty_obj")

db.session.add_all(
[
obj1,
obj4,
empty_obj,
]
)

db.session.commit()
return
52 changes: 50 additions & 2 deletions examples/sqla/admin/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from . import app
from . import db
from .models import AVAILABLE_USER_TYPES
from .models import Model1
from .models import Post
from .models import Tag
from .models import Tree
Expand Down Expand Up @@ -104,7 +105,7 @@ class UserAdmin(ModelView):
"phone_number",
"email",
]
column_editable_list = ["type", "currency", "timezone"]
column_editable_list = ["type", "currency", "timezone", "last_name"]
column_details_list = [
"id",
"featured_post",
Expand All @@ -129,6 +130,7 @@ class UserAdmin(ModelView):
"ip_address",
"timezone",
]

create_template = "admin/users/create.html"
form_create_rules = [
rules.Header("Users"), # HTML header
Expand Down Expand Up @@ -192,7 +194,11 @@ class UserAdmin(ModelView):
"currency",
"timezone",
]
column_formatters = {"phone_number": phone_number_formatter}

column_formatters = {
"phone_number": phone_number_formatter,
"last_name": lambda v, c, m, p: m.last_name.upper() if m.last_name else "",
}

# setup edit forms so that only posts created by this user can be selected as
# 'featured'
Expand Down Expand Up @@ -304,11 +310,53 @@ def render(self, template, **kwargs):
return super().render(template, foo="bar", **kwargs)


class EditableView(ModelView):
column_list = [
"test1",
"bool_field",
"date_field",
"time_field",
"datetime_field",
"email_field",
"choice_field",
"enum_field",
"enum_type_field",
"sqla_utils_choice",
"sqla_utils_enum",
"sqla_utils_arrow",
"sqla_utils_uuid",
"sqla_utils_url",
"sqla_utils_ip_address",
"sqla_utils_currency",
"sqla_utils_color",
]
column_editable_list = [
"test1",
"bool_field",
"date_field",
"time_field",
"datetime_field",
"email_field",
"choice_field",
"enum_field",
"enum_type_field",
"sqla_utils_choice",
"sqla_utils_enum",
"sqla_utils_arrow",
"sqla_utils_uuid",
"sqla_utils_url",
"sqla_utils_ip_address",
"sqla_utils_currency",
"sqla_utils_color",
]


admin = Admin(app, name="Example: SQLAlchemy", theme=Bootstrap4Theme(swatch="default"))

admin.add_view(UserAdmin(User, db))
admin.add_view(ModelView(Tag, db))
admin.add_view(PostAdmin(db))
admin.add_view(EditableView(Model1, db, name="Editable View", category="Other"))
admin.add_view(TreeView(Tree, db, category="Other"))
admin.add_sub_category(name="Links", parent_name="Other")
admin.add_link(MenuLink(name="Back Home", url="/", category="Links"))
Expand Down
58 changes: 58 additions & 0 deletions examples/sqla/admin/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,61 @@ class Tree(db.Model):

def __str__(self):
return f"{self.name}"


class Model1(db.Model): # type: ignore[name-defined, misc]
def __init__(
self,
test1=None,
test2=None,
bool_field=False,
date_field=None,
time_field=None,
datetime_field=None,
email_field=None,
choice_field=None,
enum_field=None,
enum_type_field=None,
):
self.test1 = test1
self.test2 = test2
self.bool_field = bool_field
self.date_field = date_field
self.time_field = time_field
self.datetime_field = datetime_field
self.email_field = email_field
self.choice_field = choice_field
self.enum_field = enum_field
self.enum_type_field = enum_type_field

class EnumChoices(enum.Enum):
first = 1
second = 2

id = db.Column(db.Integer, primary_key=True)
test1 = db.Column(db.String(20))
test2 = db.Column(db.Unicode(20))
bool_field = db.Column(db.Boolean)
date_field = db.Column(db.Date)
time_field = db.Column(db.Time)
datetime_field = db.Column(db.DateTime)
email_field = db.Column(EmailType)
choice_field = db.Column(db.String, nullable=True)
enum_field = db.Column(db.Enum("model1_v1", "model1_v2"), nullable=True)
enum_type_field = db.Column(db.Enum(EnumChoices), nullable=True)
sqla_utils_choice = db.Column(
ChoiceType([("choice-1", "First choice"), ("choice-2", "Second choice")])
)
sqla_utils_enum = db.Column(ChoiceType(EnumChoices, impl=db.Integer()))
sqla_utils_arrow = db.Column(ArrowType, default=arrow.utcnow())
sqla_utils_uuid = db.Column(UUIDType(binary=False), default=uuid.uuid4)
sqla_utils_url = db.Column(URLType)
sqla_utils_ip_address = db.Column(IPAddressType)
sqla_utils_currency = db.Column(CurrencyType)
sqla_utils_color = db.Column(ColorType)

def __unicode__(self):
return self.test1

def __str__(self):
return self.test1
23 changes: 23 additions & 0 deletions flask_admin/model/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2109,6 +2109,28 @@ def _get_list_value(

return value

@pass_context
def get_unformatted_value(
self, context: Context, model: T_ORM_MODEL, name: str
) -> t.Any:
"""
Returns the actual value (Unformatted) to be displayed in editable form.

:param context:
:py:class:`jinja2.runtime.Context`
:param model:
Model instance
:param name:
Field name
"""
return self._get_list_value(
context,
model,
name,
{}, # no column formatters
{}, # no column type formatters
)

@pass_context
def get_list_value(self, context: Context, model: T_ORM_MODEL, name: str) -> t.Any:
"""
Expand Down Expand Up @@ -2330,6 +2352,7 @@ def page_size_url(s: int) -> str:
enumerate=enumerate,
get_pk_value=self.get_pk_value,
get_value=self.get_list_value,
get_unformatted_value=self.get_unformatted_value,
return_url=self._get_list_url(view_args), # Extras
extra_args=view_args.extra_args,
)
Expand Down
4 changes: 3 additions & 1 deletion flask_admin/model/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ class XEditableWidget:

def __call__(self, field: Field, **kwargs: t.Any) -> str:
display_value = kwargs.pop("display_value", "")
kwargs.setdefault("data-value", display_value)
# kwargs.setdefault("data-value", display_value)
value = kwargs.pop("value", "")
kwargs.setdefault("data-value", value)

kwargs.setdefault("data-role", "x-editable")
kwargs.setdefault("data-url", "./ajax/update/")
Expand Down
6 changes: 3 additions & 3 deletions flask_admin/templates/bootstrap4/admin/model/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@
{% if admin_view.is_editable(c) %}
{% set form = list_forms[get_pk_value(row)] %}
{% if form.csrf_token is defined and form.csrf_token %}
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c), csrf=form.csrf_token._value()) }}
{{ form[c](pk=get_pk_value(row), value=get_unformatted_value(row, c), display_value=get_value(row, c), csrf=form.csrf_token._value()) }}
{% elif csrf_token is defined and csrf_token %}
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c), csrf=csrf_token()) }}
{{ form[c](pk=get_pk_value(row), value=get_unformatted_value(row, c), display_value=get_value(row, c), csrf=csrf_token()) }}
{% else %}
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c)) }}
{{ form[c](pk=get_pk_value(row), value=get_unformatted_value(row, c), display_value=get_value(row, c)) }}
{% endif %}
{% else %}
{{ get_value(row, c) }}
Expand Down
Loading