mirror of
https://github.com/fastapi-admin/fastapi-admin.git
synced 2025-08-14 18:58:13 +08:00
add request to parse_value
This commit is contained in:
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
@ -1,7 +1,7 @@
|
|||||||
name: deploy
|
name: deploy
|
||||||
on: [ push, pull_request ]
|
on: [ push, pull_request ]
|
||||||
jobs:
|
jobs:
|
||||||
example:
|
examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy
|
- name: Deploy
|
||||||
|
@ -62,10 +62,10 @@ class AdminResource(Model):
|
|||||||
return {"class": "bg-danger text-white"}
|
return {"class": "bg-danger text-white"}
|
||||||
return await super().cell_attributes(request, obj, field)
|
return await super().cell_attributes(request, obj, field)
|
||||||
|
|
||||||
def get_actions(self) -> List[Action]:
|
async def get_actions(self, request: Request) -> List[Action]:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def get_bulk_actions(self) -> List[Action]:
|
async def get_bulk_actions(self, request: Request) -> List[Action]:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ class ConfigResource(Model):
|
|||||||
async def row_attributes(self, request: Request, obj: dict) -> dict:
|
async def row_attributes(self, request: Request, obj: dict) -> dict:
|
||||||
if obj.get("status") == enums.Status.on:
|
if obj.get("status") == enums.Status.on:
|
||||||
return {"class": "bg-green text-white"}
|
return {"class": "bg-green text-white"}
|
||||||
return await super().row_attributes(obj)
|
return await super().row_attributes(request, obj)
|
||||||
|
|
||||||
|
|
||||||
@app.register
|
@app.register
|
||||||
@ -138,7 +138,7 @@ class GithubLink(Link):
|
|||||||
@app.register
|
@app.register
|
||||||
class DocumentationLink(Link):
|
class DocumentationLink(Link):
|
||||||
label = "Documentation"
|
label = "Documentation"
|
||||||
url = "https://long2ice.github.io/fastadmin"
|
url = "https://fastapi-admin-docs.long2ice.cn"
|
||||||
icon = "fas fa-file-code"
|
icon = "fas fa-file-code"
|
||||||
target = "_blank"
|
target = "_blank"
|
||||||
|
|
||||||
|
@ -19,12 +19,12 @@ def get_model(resource: Optional[str] = Path(...)):
|
|||||||
return model
|
return model
|
||||||
|
|
||||||
|
|
||||||
def get_model_resource(request: Request, model=Depends(get_model)):
|
async def get_model_resource(request: Request, model=Depends(get_model)):
|
||||||
model_resource = request.app.get_model_resource(model) # type:Model
|
model_resource = request.app.get_model_resource(model) # type:Model
|
||||||
if not model_resource:
|
if not model_resource:
|
||||||
raise HTTPException(status_code=HTTP_404_NOT_FOUND)
|
raise HTTPException(status_code=HTTP_404_NOT_FOUND)
|
||||||
actions = model_resource.get_actions()
|
actions = await model_resource.get_actions(request)
|
||||||
bulk_actions = model_resource.get_bulk_actions()
|
bulk_actions = await model_resource.get_bulk_actions(request)
|
||||||
model_resource.actions = actions
|
model_resource.actions = actions
|
||||||
model_resource.bulk_actions = bulk_actions
|
model_resource.bulk_actions = bulk_actions
|
||||||
return model_resource
|
return model_resource
|
||||||
|
@ -77,13 +77,13 @@ class Model(Resource):
|
|||||||
async def cell_attributes(self, request: Request, obj: dict, field: Field) -> dict:
|
async def cell_attributes(self, request: Request, obj: dict, field: Field) -> dict:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def get_actions(self) -> List[Action]:
|
async def get_actions(self, request: Request) -> List[Action]:
|
||||||
return [
|
return [
|
||||||
Action(label=_("update"), icon="ti ti-edit", name="update", ajax=False),
|
Action(label=_("update"), icon="ti ti-edit", name="update", ajax=False),
|
||||||
Action(label=_("delete"), icon="ti ti-trash", name="delete", method="DELETE"),
|
Action(label=_("delete"), icon="ti ti-trash", name="delete", method="DELETE"),
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_bulk_actions(self) -> List[Action]:
|
async def get_bulk_actions(self, request: Request) -> List[Action]:
|
||||||
return [
|
return [
|
||||||
Action(
|
Action(
|
||||||
label=_("delete_selected"),
|
label=_("delete_selected"),
|
||||||
@ -94,7 +94,7 @@ class Model(Resource):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_inputs(cls, obj: Optional[TortoiseModel] = None):
|
async def get_inputs(cls, request: Request, obj: Optional[TortoiseModel] = None):
|
||||||
ret = []
|
ret = []
|
||||||
for field in cls.get_fields(is_display=False):
|
for field in cls.get_fields(is_display=False):
|
||||||
input_ = field.input
|
input_ = field.input
|
||||||
@ -103,21 +103,21 @@ class Model(Resource):
|
|||||||
if isinstance(input_, inputs.File):
|
if isinstance(input_, inputs.File):
|
||||||
cls.enctype = "multipart/form-data"
|
cls.enctype = "multipart/form-data"
|
||||||
name = input_.context.get("name")
|
name = input_.context.get("name")
|
||||||
ret.append(await input_.render(getattr(obj, name, None)))
|
ret.append(await input_.render(request, getattr(obj, name, None)))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def resolve_query_params(cls, values: dict):
|
async def resolve_query_params(cls, request: Request, values: dict):
|
||||||
ret = {}
|
ret = {}
|
||||||
for f in cls.filters:
|
for f in cls.filters:
|
||||||
name = f.context.get("name")
|
name = f.context.get("name")
|
||||||
v = values.get(name)
|
v = values.get(name)
|
||||||
if v is not None and v != "":
|
if v is not None and v != "":
|
||||||
ret[name] = await f.parse_value(v)
|
ret[name] = await f.parse_value(request, v)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def resolve_data(cls, data: FormData):
|
async def resolve_data(cls, request: Request, data: FormData):
|
||||||
ret = {}
|
ret = {}
|
||||||
m2m_ret = {}
|
m2m_ret = {}
|
||||||
for field in cls.get_fields(is_display=False):
|
for field in cls.get_fields(is_display=False):
|
||||||
@ -127,11 +127,11 @@ class Model(Resource):
|
|||||||
name = input_.context.get("name")
|
name = input_.context.get("name")
|
||||||
if isinstance(input_, inputs.ManyToMany):
|
if isinstance(input_, inputs.ManyToMany):
|
||||||
v = data.getlist(name)
|
v = data.getlist(name)
|
||||||
value = await input_.parse_value(v)
|
value = await input_.parse_value(request, v)
|
||||||
m2m_ret[name] = await input_.model.filter(pk__in=value)
|
m2m_ret[name] = await input_.model.filter(pk__in=value)
|
||||||
else:
|
else:
|
||||||
v = data.get(name)
|
v = data.get(name)
|
||||||
value = await input_.parse_value(v)
|
value = await input_.parse_value(request, v)
|
||||||
ret[name] = value
|
ret[name] = value
|
||||||
return ret, m2m_ret
|
return ret, m2m_ret
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ async def list_view(
|
|||||||
fields_name = model_resource.get_fields_name()
|
fields_name = model_resource.get_fields_name()
|
||||||
fields_label = model_resource.get_fields_label()
|
fields_label = model_resource.get_fields_label()
|
||||||
fields = model_resource.get_fields()
|
fields = model_resource.get_fields()
|
||||||
params = await model_resource.resolve_query_params(dict(request.query_params))
|
params = await model_resource.resolve_query_params(request, dict(request.query_params))
|
||||||
filters = await model_resource.get_filters(request, params)
|
filters = await model_resource.get_filters(request, params)
|
||||||
qs = model.filter(**params)
|
qs = model.filter(**params)
|
||||||
total = await qs.count()
|
total = await qs.count()
|
||||||
@ -84,7 +84,7 @@ async def update(
|
|||||||
model=Depends(get_model),
|
model=Depends(get_model),
|
||||||
):
|
):
|
||||||
form = await request.form()
|
form = await request.form()
|
||||||
data, m2m_data = await model_resource.resolve_data(form)
|
data, m2m_data = await model_resource.resolve_data(request, form)
|
||||||
async with in_transaction() as conn:
|
async with in_transaction() as conn:
|
||||||
obj = (
|
obj = (
|
||||||
await model.filter(pk=pk)
|
await model.filter(pk=pk)
|
||||||
@ -172,7 +172,7 @@ async def create_view(
|
|||||||
resources=Depends(get_resources),
|
resources=Depends(get_resources),
|
||||||
model_resource: ModelResource = Depends(get_model_resource),
|
model_resource: ModelResource = Depends(get_model_resource),
|
||||||
):
|
):
|
||||||
inputs = await model_resource.get_inputs()
|
inputs = await model_resource.get_inputs(request)
|
||||||
context = {
|
context = {
|
||||||
"request": request,
|
"request": request,
|
||||||
"resources": resources,
|
"resources": resources,
|
||||||
@ -203,9 +203,9 @@ async def create(
|
|||||||
model_resource: ModelResource = Depends(get_model_resource),
|
model_resource: ModelResource = Depends(get_model_resource),
|
||||||
model=Depends(get_model),
|
model=Depends(get_model),
|
||||||
):
|
):
|
||||||
inputs = await model_resource.get_inputs()
|
inputs = await model_resource.get_inputs(request)
|
||||||
form = await request.form()
|
form = await request.form()
|
||||||
data, m2m_data = await model_resource.resolve_data(form)
|
data, m2m_data = await model_resource.resolve_data(request, form)
|
||||||
async with in_transaction() as conn:
|
async with in_transaction() as conn:
|
||||||
obj = await model.create(**data, using_db=conn)
|
obj = await model.create(**data, using_db=conn)
|
||||||
for k, items in m2m_data.items():
|
for k, items in m2m_data.items():
|
||||||
|
@ -20,9 +20,9 @@ class DatetimeDisplay(Display):
|
|||||||
self.format_ = format_
|
self.format_ = format_
|
||||||
|
|
||||||
async def render(self, request: Request, value: datetime):
|
async def render(self, request: Request, value: datetime):
|
||||||
if value:
|
return await super(DatetimeDisplay, self).render(
|
||||||
value = value.strftime(self.format_)
|
request, value.strftime(self.format_) if value else None
|
||||||
return await super(DatetimeDisplay, self).render(request, value)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DateDisplay(DatetimeDisplay):
|
class DateDisplay(DatetimeDisplay):
|
||||||
|
@ -63,7 +63,8 @@ class Datetime(Filter):
|
|||||||
)
|
)
|
||||||
self.context.update(format=format_)
|
self.context.update(format=format_)
|
||||||
|
|
||||||
async def parse_value(self, value: Optional[str]):
|
async def parse_value(self, request: Request, value: Optional[str]):
|
||||||
|
if value:
|
||||||
return value.split(" - ")
|
return value.split(" - ")
|
||||||
|
|
||||||
async def render(self, request: Request, value: Any):
|
async def render(self, request: Request, value: Any):
|
||||||
@ -122,7 +123,7 @@ class Enum(Select):
|
|||||||
self.enum = enum
|
self.enum = enum
|
||||||
self.enum_type = enum_type
|
self.enum_type = enum_type
|
||||||
|
|
||||||
async def parse_value(self, value: Any):
|
async def parse_value(self, request: Request, value: Any):
|
||||||
return self.enum(self.enum_type(value))
|
return self.enum(self.enum_type(value))
|
||||||
|
|
||||||
async def get_options(self):
|
async def get_options(self):
|
||||||
|
@ -18,7 +18,7 @@ class Input(Widget):
|
|||||||
super().__init__(null=null, **context)
|
super().__init__(null=null, **context)
|
||||||
self.default = default
|
self.default = default
|
||||||
|
|
||||||
async def parse_value(self, value: Any):
|
async def parse_value(self, request: Request, value: Any):
|
||||||
"""
|
"""
|
||||||
Parse value from frontend
|
Parse value from frontend
|
||||||
:param value:
|
:param value:
|
||||||
@ -139,7 +139,7 @@ class Enum(Select):
|
|||||||
self.enum = enum
|
self.enum = enum
|
||||||
self.enum_type = enum_type
|
self.enum_type = enum_type
|
||||||
|
|
||||||
async def parse_value(self, value: Any):
|
async def parse_value(self, request: Request, value: Any):
|
||||||
return self.enum(self.enum_type(value))
|
return self.enum(self.enum_type(value))
|
||||||
|
|
||||||
async def get_options(self):
|
async def get_options(self):
|
||||||
@ -203,7 +203,7 @@ class File(Input):
|
|||||||
)
|
)
|
||||||
self.upload_provider = upload_provider
|
self.upload_provider = upload_provider
|
||||||
|
|
||||||
async def parse_value(self, value: Optional[UploadFile]):
|
async def parse_value(self, request: Request, value: Optional[UploadFile]):
|
||||||
if value:
|
if value:
|
||||||
return await self.upload_provider.upload(value)
|
return await self.upload_provider.upload(value)
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ class RadioEnum(Enum):
|
|||||||
class Switch(Input):
|
class Switch(Input):
|
||||||
template = "widgets/inputs/switch.html"
|
template = "widgets/inputs/switch.html"
|
||||||
|
|
||||||
async def parse_value(self, value: str):
|
async def parse_value(self, request: Request, value: str):
|
||||||
if value == "on":
|
if value == "on":
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
Reference in New Issue
Block a user