amisadmin / fastapi-amis-admin

FastAPI-Amis-Admin is a high-performance, efficient and easily extensible FastAPI admin framework. Inspired by django-admin, and has as many powerful functions as django-admin.
http://docs.amis.work
Apache License 2.0
1.05k stars 154 forks source link

Show 'id' column in creation dialog #88

Closed lastochka364 closed 1 year ago

lastochka364 commented 1 year ago

Hello. I can't figure out how to show 'id' field when adding new object through admin panel dialog.

I have the following SQL model:

from datetime import datetime as dt

from sqlmodel import SQLModel
from fastapi_amis_admin.models.fields import Field

class Users(SQLModel, table=True):
    id: str = Field(primary_key=True, nullable=False)
    registration_date: dt = Field(nullable=False)
    username: str = Field(nullable=False)
    first_name: str = Field(nullable=False)
    last_name: str = Field(nullable=True)
    language: str = Field(nullable=False)

Now, I'm registering it as model admin like this way:

from .models import Users

site = AdminSite(settings=Settings(database_url_async=...))

@site.register_admin
class UsersAdmin(admin.ModelAdmin):
    page_schema = 'Users'
    model = Users
    create_fields = [
        Users.id, Users.username, Users.registration_date, Users.language
        ]

Now, when I visit http://localhost:8000/admin/#/admin/UsersAdmin, and tying to add some data to model, I can't see 'id' field:

image

I'm stuck, because thoght that class create_fields var will done this job.

amisadmin commented 1 year ago

You can do this by defining the schema_create class instead of create_fields.

lastochka364 commented 1 year ago

It seems like I need some example.

I tried to define the schema_create, taking example from the source code in fastapi_amis_admin.crud.base.BaseCrud, setting schema_create with schema_create_by_schema(),

from fastapi_amis_admin.crud.utils import schema_create_by_schema

@site.register_admin
class UsersAdmin(admin.ModelAdmin):
    page_schema = 'Users'
    model = Users

    schema_create = schema_create_by_schema(
        model,
        f'{model.__name__}Create',
        include={
            'id', 'username',
        },
        exclude=None
    )

but still no luck:

image

lastochka364 commented 1 year ago

So I managed to get the 'id' field on the dialog, but now I'm getting <class 'asyncpg.exceptions.NotNullViolationError'>: null value in column "id" of relation "users" violates not-null constraint error, when trying to create any data.

I overloaded get_create_form(),

from fastapi_amis_admin.amis.components import Form, InputExcel, InputTable
from fastapi_amis_admin.crud.base import schema_create_by_schema
from fastapi_amis_admin.amis.constants import DisplayModeEnum
from fastapi_amis_admin.crud.schema import CrudEnum
from fastapi_amis_admin.amis.types import AmisAPI
from fastapi_amis_admin.admin import ModelAdmin

from fastapi import Request

class CustomModelAdmin(ModelAdmin):
    async def get_create_form(self, request: Request, bulk: bool = False) -> Form:
        self.schema_create = schema_create_by_schema(
            self.schema_model,
            f"{self.schema_name_prefix}Create",
        )
        fields = [field for field in self.schema_create.__fields__.values()]
        if not bulk:
            return Form(
                api=f"post:{self.router_path}/item",
                name=CrudEnum.create,
                body=await self._conv_modelfields_to_formitems(request, fields, CrudEnum.create),
            )
        columns, keys = [], {}
        for field in fields:
            column = await self.get_list_column(request, self.parser.get_modelfield(field))
            keys[column.name] = "${" + column.label + "}"
            column.name = column.label
            columns.append(column)
        return Form(
            api=AmisAPI(
                method="post",
                url=f"{self.router_path}/item",
                data={"&": {"$excel": keys}},
            ),
            mode=DisplayModeEnum.normal,
            body=[
                InputExcel(name="excel"),
                InputTable(
                    name="excel",
                    showIndex=True,
                    columns=columns,
                    addable=True,
                    copyable=True,
                    editable=True,
                    removable=True,
                ),
            ],
        )

this gets me to the next result:

image

This is getting more complex that I thinked. It seems that I need to implement my own logic of inserting data in database, but at this point I have no idea how. Maybe I'm digging in the wrong direction, and if so, please correct me.

1219295581 commented 1 year ago

please try as below:


from pydantic import BaseModel
class UserAdmin(ModelAdmin):
    model=Users
    class schema_create(BaseModel):
        user_id: int = Field(title="ID", alias="id",nullable=False)
        registration_date: dt = Field(nullable=False)
        username: str = Field(nullable=False)
        first_name: str = Field(nullable=False)
        last_name: str = Field(nullable=True)
        language: str = `Field(nullable=False)
lastochka364 commented 1 year ago

It seems that @amisadmin didn't just say that I need "schema_create class". But I didn't even think it was possible like that :)

Big thanks, it works! I also tried schema_update, all is perfectly updating and works just as expected.