Add column_attributes

This commit is contained in:
long2ice
2021-05-13 16:10:04 +08:00
parent b2405bc147
commit 88ae0f9278
11 changed files with 53 additions and 73 deletions

View File

@@ -2,6 +2,10 @@
## 1.0
### 1.0.1
- Add `column_attributes`.
### 1.0.0
**This is a completely different version and rewrite all code. If you are using old version, you can't upgrade directly,

View File

@@ -52,11 +52,11 @@ async def startup():
Admin,
settings.GOOGLE_CLIENT_ID,
settings.GOOGLE_CLIENT_SECRET,
redirect_uri="https://fastapi-admin-pro.long2ice.cn/admin/login/google_oauth2_provider",
redirect_uri="https://fastapi-admin-pro.long2ice.cn/admin/oauth2/google_oauth2_provider",
),
]
)
```
If you want custom oauth2 provider, just inherit `fastapi_admin.providers.login.OAuth2Provider` and implement its
methods.
methods. And the `redirect_uri` format is `{server_url}/{admin_path}/oauth2/{provider_name}`.

View File

@@ -50,7 +50,8 @@ class AdminResource(Model):
]
```
You can pass `str` or `Field` to `fields`, if is `str`, it will try to auto mapping display and input widget, such as `displays.Boolean` for `BooleanField`, `inputs.Date` for `DateField`.
You can pass `str` or `Field` to `fields`, if is `str`, it will try to auto mapping display and input widget, such
as `displays.Boolean` for `BooleanField`, `inputs.Date` for `DateField`.
All kind of widgets you can find in [Display](/reference/widget/display/) and [Input](/reference/widget/input/).
@@ -58,9 +59,11 @@ All kind of widgets you can find in [Display](/reference/widget/display/) and [I
The `Action` define the action display in every end of row, and bulk action for every model.
By default there are two actions, Which are delete action and edit action, and one bulk action, which allow delete rows in bulk.
By default there are two actions, Which are delete action and edit action, and one bulk action, which allow delete rows
in bulk.
To use that, you should override the `get_actions` and `get_bulk_actions`. The following example hide all default actions with return empty list.
To use that, you should override the `get_actions` and `get_bulk_actions`. The following example hide all default
actions with return empty list.
```python
@app.register
@@ -74,7 +77,8 @@ class AdminResource(Model):
## Model
`Model` is the core resource, which make TortoiseORM model as a menu and display a data table with create, update, and delete.
`Model` is the core resource, which make TortoiseORM model as a menu and display a data table with create, update, and
delete.
```python
@app.register
@@ -101,8 +105,9 @@ class AdminResource(Model):
- `model`: TortoiseORM model.
- `page_pre_title`: Show page pre title in content.
- `page_title`: Show page title in content.
- `filters`: Define filters for the model, which will display filter inputs in table above, all kinds of filters you can find in [Filter](/reference/widget/filter/).
- `can_delete`: Whether show a `create` button there.
- `filters`: Define filters for the model, which will display filter inputs in table above, all kinds of filters you can
find in [Filter](/reference/widget/filter/).
- `can_create`: Whether show a `create` button there.
### row_attributes
@@ -119,17 +124,33 @@ class ConfigResource(Model):
The example above will add the css `class = "bg-green text-white"` for the row which `status = enums.Status.on`.
### column_attributes
You can add extra attributes to each column by use `column_attributes`.
```python
@app.register
class LogResource(Model):
async def column_attributes(self, request: Request, field: Field) -> dict:
if field.name == "content":
return {"class": "w-50"}
return await super().column_attributes(request, field)
```
The example above will add the css `class = "w-50"` for the column which `content`.
### cell_attributes
Same as `row_attributes` but for the cell, you can add extra attributes to cell depends on the row object and column field.
Same as `row_attributes` but for the cell, you can add extra attributes to cell depends on the row object and column
field.
```python
@app.register
class AdminResource(Model):
async def cell_attributes(self, request: Request, obj: dict, field: Field) -> dict:
if field.name == "id":
return {"class": "bg-danger text-white"}
return await super().cell_attributes(request, obj, field)
if field.name == "id":
return {"class": "bg-danger text-white"}
return await super().cell_attributes(request, obj, field)
```
## Dropdown

View File

@@ -4,15 +4,9 @@ from aioredis import Redis
from fastapi import FastAPI
from pydantic import HttpUrl
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.status import HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND, HTTP_500_INTERNAL_SERVER_ERROR
from tortoise import Model
from fastapi_admin import i18n
from fastapi_admin.exceptions import (
forbidden_error_exception,
not_found_error_exception,
server_error_exception,
)
from . import middlewares, template
from .providers import Provider

View File

@@ -75,6 +75,9 @@ class Model(Resource):
async def row_attributes(self, request: Request, obj: dict) -> dict:
return {}
async def column_attributes(self, request: Request, field: Field) -> dict:
return {}
async def cell_attributes(self, request: Request, obj: dict, field: Field) -> dict:
return {}

View File

@@ -1,8 +1,6 @@
from fastapi import APIRouter
from .password import router as password_router
from .resources import router as resources_router
router = APIRouter()
router.include_router(resources_router)
router.include_router(password_router, prefix="/password")

View File

@@ -1,47 +0,0 @@
from fastapi import APIRouter, Depends, Form
from starlette.requests import Request
from fastapi_admin.depends import get_current_admin, get_resources
from fastapi_admin.i18n import _
from fastapi_admin.models import AbstractAdmin
from fastapi_admin.template import templates
router = APIRouter()
@router.get("")
async def update_password_view(
request: Request,
resources=Depends(get_resources),
):
return templates.TemplateResponse(
"password.html",
context={
"request": request,
"resources": resources,
},
)
@router.post("")
async def update_password(
request: Request,
old_password: str = Form(...),
new_password: str = Form(...),
re_new_password: str = Form(...),
admin: AbstractAdmin = Depends(get_current_admin),
resources=Depends(get_resources),
):
login_provider = request.app.login_provider
error = None
if not login_provider.check_password(admin, old_password):
error = _("old_password_error")
elif new_password != re_new_password:
error = _("new_password_different")
if error:
return templates.TemplateResponse(
"password.html",
context={"request": request, "resources": resources, "error": error},
)
await login_provider.update_password(admin, new_password)
return await login_provider.logout(request)

View File

@@ -38,7 +38,7 @@ async def list_view(
page_size = model_resource.page_size
qs = qs.offset((page_num - 1) * page_size)
values = await qs.values(*fields_name)
rendered_values, row_attributes, cell_attributes = await render_values(
rendered_values, row_attributes, column_attributes, cell_attributes = await render_values(
request, model_resource, fields, values
)
context = {
@@ -48,6 +48,7 @@ async def list_view(
"fields": fields,
"values": values,
"row_attributes": row_attributes,
"column_attributes": column_attributes,
"cell_attributes": cell_attributes,
"rendered_values": rendered_values,
"filters": filters,

View File

@@ -1,7 +1,7 @@
import os
import typing
from datetime import date
from typing import Any, List, Tuple
from typing import Any, List
from urllib.parse import urlencode
from jinja2 import contextfilter
@@ -51,7 +51,7 @@ async def render_values(
fields: List["Field"],
values: List[typing.Dict[str, Any]],
display: bool = True,
) -> typing.Tuple[List[List[Any]], List[dict], List[List[dict]]]:
) -> typing.Tuple[List[List[Any]], List[dict], List[dict], List[List[dict]]]:
"""
render values with template render
:param fields:
@@ -64,6 +64,9 @@ async def render_values(
ret = []
cell_attributes: List[List[dict]] = []
row_attributes: List[dict] = []
column_attributes: List[dict] = []
for field in fields:
column_attributes.append(await model.column_attributes(request, field))
for value in values:
row_attributes.append(await model.row_attributes(request, value))
item = []
@@ -76,4 +79,4 @@ async def render_values(
item.append(await fields[i].input.render(request, value[k]))
ret.append(item)
cell_attributes.append(cell_item)
return ret, row_attributes, cell_attributes
return ret, row_attributes, column_attributes, cell_attributes

View File

@@ -18,7 +18,7 @@ packages = [
]
readme = "README.md"
repository = "https://github.com/fastapi-admin/fastapi-admin.git"
version = "1.0.0"
version = "1.0.1"
[tool.poetry.dependencies]
Babel = "*"

View File

@@ -1,2 +1,5 @@
[flake8]
ignore = E501,W503
ignore = E501,W503
[mypy]
pretty = True
ignore_missing_imports = True