diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c94bba..d4582fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,14 +1,20 @@ name: FastAdmin CI -on: [create, push] +on: + push: + branches: + - main + pull_request: + workflow_dispatch: permissions: contents: read id-token: write + pull-requests: write -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} jobs: ci: @@ -20,14 +26,14 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.13' + python-version: "3.13" cache: "poetry" - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: v24.3.0 - cache: 'yarn' - cache-dependency-path: 'frontend/yarn.lock' + cache: "yarn" + cache-dependency-path: "frontend/yarn.lock" - name: Install Dependencies run: make install - name: Run Lint diff --git a/docs/build.py b/docs/build.py index 875aa76..050008c 100644 --- a/docs/build.py +++ b/docs/build.py @@ -44,6 +44,13 @@ def read_cls_docstring(cls): def get_versions(): return [ + { + "version": "0.4.9", + "changes": [ + "Add obj parameter to upload_file method.", + "Add get_file_url method to model admin.", + ], + }, { "version": "0.4.8", "changes": [ @@ -426,7 +433,6 @@ def read_example(rel_path: str) -> str: def get_page_context(page_url): - from fastadmin import InlineModelAdmin, ModelAdmin, WidgetType, widget_action from fastadmin.models.base import BaseModelAdmin from fastadmin.models.schemas import ( @@ -759,7 +765,27 @@ async def save_model(self, id, payload): }, { "type": "text", - "content": "For file and image fields use UploadFile and UploadImage widgets in formfield_overrides. Implement upload_file(obj, field_name, file_name, file_content) on the model admin to handle uploads; it must return the file URL (e.g. after saving to disk or S3).", + "content": "For file and image fields use UploadFile and UploadImage widgets in formfield_overrides. Implement upload_file(field_name, file_name, file_content, obj=None) on the model admin to handle uploads; it must return the file URL (e.g. after saving to disk or S3).", + }, + { + "type": "text", + "content": "To customise the URL shown in the upload widget (e.g. generate an S3 presigned URL instead of displaying the raw s3:// key), override get_file_url on the model admin. The display URL is emitted as {field_name}__url in the serialised object and passed to the widget as valueRepr; the raw stored value is never changed, so form saves are unaffected.", + }, + { + "type": "code-python", + "content": """async def get_file_url(self, field_name: str, value: str, obj=None) -> str: + # value is the raw stored key, e.g. "s3://bucket/key" + # Return a presigned URL so the file can be viewed in the admin. + # Example using aiobotocore: + # + # bucket, key = value.replace("s3://", "").split("/", 1) + # async with aiobotocore.session.get_session().create_client("s3") as s3: + # return await s3.generate_presigned_url( + # "get_object", + # Params={"Bucket": bucket, "Key": key}, + # ExpiresIn=3600, + # ) + return value""", }, { "type": "text", diff --git a/docs/index.html b/docs/index.html index 865e616..1027047 100644 --- a/docs/index.html +++ b/docs/index.html @@ -192,6 +192,10 @@

FastAdmin