fastapi-amis-admin
fastapi-amis-admin copied to clipboard
如何实现一个动态内容的下拉选择?
我希望能在每一次加载页面的时候根据情况生成下拉选择框的成员, 我尝试在get_form_item里截取当前item然后往里面添加一些新的选项, 但是新的选项过不了FastApi的校验, 我尝试修改枚举也无效, 似乎fastapi总是持有最开始的那个枚举. 当前代码如下:
class NtpVersionEnum(Choices):
t = "t"
q = 'asd'
@site.register_admin
class 生成区域掩码(admin.FormAdmin):
page_schema = '生成'
form = Form(title='生成区域参数', submitText='提交')
class schema(BaseModel):
ntp_version: NtpVersionEnum = Field(NtpVersionEnum.t, title='NTP版本')
async def handle(self, request: Request, data: BaseModel, **kwargs) -> BaseApiOut[Any]:
return BaseApiOut(msg='登录成功!', data={'token': 'xxxxxx'})
async def get_form_item(self, request: Request, modelfield: ModelField) -> Form:
item = await super().get_form_item(request, modelfield)
if item.label == 'NTP版本':
global NtpVersionEnum
new_enum = Choices('NtpVersionEnum', {'t': 't', 'q': 'q', 'apple': 'apple'})
print(NtpVersionEnum._member_map_, NtpVersionEnum._member_names_)
NtpVersionEnum._member_map_ = new_enum._member_map_
NtpVersionEnum._member_names_ = new_enum._member_names_
NtpVersionEnum._member_type_ = new_enum._member_type_
objprint.objprint(NtpVersionEnum._member_map_, NtpVersionEnum._member_names_)
objprint.objprint(NtpVersionEnum.__dict__)
item.options.append(Select(value='apple', label='apple'))
return item
报错为:
{"detail":[{"loc":["body","ntp_version"],"msg":"value is not a valid enumeration member; permitted: 't', 'q', 'apple'","type":"type_error.enum","ctx":{"enum_values":["t","q","apple"]}}]}
说是不允许 apple, 实际上传入的就是 apple.
我已经搜了一些关于如何动态定于应用于fastapi的enum的东西, 不过看起来很难, amis这里是否可能给出一个动态选项并且不使用枚举来约束呢? 如果不太复杂, 也可以给我一些指引, 我来做一个PR
你可以参考amis相关组件文档,自定义相关属性: https://aisuda.bce.baidu.com/amis/zh-CN/components/form/select
class schema(BaseModel):
ntp_version: str= Field('', title='NTP版本',amis_form_item=amis.Select(value='apple', label='apple',source='xxxxxxx'),)
你好, 我注意到另一个问题, 无论怎么改 schema 里的字段, 到前端的时候都是一个 input-text 或者 input-number, 比如写
ntp_version: str = Field(
"",
title="NTP版本",
amis_form_item=amis.Select(
value="apple", label="apple", source="/test-source"
),
)
会得到
{
"type": "input-text",
"name": "ntp_version",
"label": "NTP版本",
"required": false
}
而其他属性都消失, 目前我唯一发现能影响到前端的 json 的方式是在get_form_item里覆写. 比如在 class 里添加这段代码, 才能得到预期的 json:
async def get_form_item(self, request: Request, modelfield: ModelField) -> Form:
'''删掉这个方法后, ntp_version 就不会显示下拉框了'''
item = await super().get_form_item(request, modelfield)
print(item)
if item.label == 'NTP版本':
item = Select(
name='ntp_version', value="apple", label="NTP版本", source="/test-source"
)
return item
{
"type": "select",
"name": "ntp_version",
"label": "NTP版本",
"value": "apple",
"source": "/test-source"
}
我的fastapi_amis_admin版本是 0.2.0, amis版本是0.1.1.
目前所有代码如下:
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
from starlette.requests import Request
from fastapi_amis_admin.amis.components import Form, Select
from fastapi_amis_admin.admin import admin
from fastapi_amis_admin.admin.settings import Settings
from fastapi_amis_admin.admin.site import AdminSite
from fastapi_amis_admin.crud.schema import BaseApiOut
from fastapi_amis_admin.models.fields import Field
import amis
from pydantic.fields import ModelField
app = FastAPI()
site = AdminSite(
settings=Settings(database_url_async="sqlite+aiosqlite:///amisadmin.db")
)
@app.get("/test-source")
def test_source():
return {"message": "Hello World", 'zxc': 'zxc'}
@site.register_admin
class UserLoginFormAdmin(admin.FormAdmin):
page_schema = "UserLoginForm"
form = Form(title="这是一个测试登录表单", submitText="登录")
class schema(BaseModel):
username: str = Field(..., title="用户名", min_length=3, max_length=30)
password: str = Field(..., title="密码")
ntp_version: str = Field(
'orange',
title="NTP版本",
amis_form_item=amis.Select(
value="apple", label="apple", source="/test-source"
),
)
async def handle(
self, request: Request, data: BaseModel, **kwargs
) -> BaseApiOut[Any]:
print(data)
return BaseApiOut(msg="登录成功!", data={"token": "xxxxxx"})
async def get_form_item(self, request: Request, modelfield: ModelField) -> Form:
'''删掉这个方法后, ntp_version 就不会显示下拉框了'''
item = await super().get_form_item(request, modelfield)
print(item)
if item.label == 'NTP版本':
item = Select(
name='ntp_version', value="apple", label="NTP版本", source="/test-source"
)
return item
site.mount_app(app)
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", debug=True, reload=True, workers=1)