From e4bf91386064570d1e452681db60f4df1e744c0f Mon Sep 17 00:00:00 2001 From: Jocelin Hounon Date: Sat, 17 Dec 2022 12:09:56 +0100 Subject: [PATCH] Release 0.5.0 (#59) --- docs/changelog/index.es.md | 137 ---------- docs/changelog/index.md | 10 + docs/tutorial/authentication/index.es.md | 124 --------- docs/tutorial/authentication/index.md | 2 +- .../tutorial/configurations/admin/index.es.md | 33 --- .../configurations/modelview/index.es.md | 117 -------- docs/tutorial/getting-started/index.es.md | 258 ------------------ docs/tutorial/multiple-admin/index.es.md | 30 -- docs/tutorial/validations/index.es.md | 129 --------- starlette_admin/__init__.py | 2 +- 10 files changed, 12 insertions(+), 830 deletions(-) delete mode 100644 docs/changelog/index.es.md delete mode 100644 docs/tutorial/authentication/index.es.md delete mode 100644 docs/tutorial/configurations/admin/index.es.md delete mode 100644 docs/tutorial/configurations/modelview/index.es.md delete mode 100644 docs/tutorial/getting-started/index.es.md delete mode 100644 docs/tutorial/multiple-admin/index.es.md delete mode 100644 docs/tutorial/validations/index.es.md diff --git a/docs/changelog/index.es.md b/docs/changelog/index.es.md deleted file mode 100644 index 826f62f9..00000000 --- a/docs/changelog/index.es.md +++ /dev/null @@ -1,137 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres -to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [0.3.1] - 2022-11-22 - ---- - -### Fixed - -* Fix Regression on SQLModel backend: Duplicate instances when creating or updating a model with relationships in [#23](https://github.com/jowilf/starlette-admin/issues/23) - - -## [0.3.0] - 2022-11-21 - ---- - -### Breaking Changes - -* Changes in `ModelView` definition - -=== "Now" - ```python - class Post: - id: int - title: str - - admin.add_view(ModelView(Post, icon="fa fa-blog", label = "Blog Posts")) - ``` - -=== "Before" - ```python - class Post: - id: int - title: str - - - class PostView(ModelView, model=Post): - icon = "fa fa-blog" - label = "Blog Posts" - - admin.add_view(PostView) - ``` - -* Changes in `CustomView` definition - -=== "Now" - ```python - admin.add_view(CustomView(label="Home", icon="fa fa-home", path="/home", template_path="home.html")) - ``` -=== "Before" - ```python - class HomeView(CustomView): - label = "Home" - icon = "fa fa-home" - path = "/home" - template_path = "home.html" - - admin.add_view(HomeView) - ``` - -* Changes in `Link` definition -=== "Now" - ```python - admin.add_view(Link(label="Back to Home", icon="fa fa-home", url="/", target = "_blank")) - ``` - -=== "Before" - ```python - class BackToHome(Link): - label = "Back to Home" - icon = "fa fa-home" - url = "/" - target = "_blank" - ``` - -These changes are inspired from *Flask-admin* and are introduced to help reduce code size and keep it simple. - -### Added - -* Add `CollectionField` -* Add `ListField` -* Add support for [Odmantic](https://art049.github.io/odmantic/) -* Add support for datatables [responsive extensions](https://datatables.net/extensions/responsive/) -!!! usage - ```python - class MyModelView(ModelView): - responsive_table = True - ``` - -### Changed - -* Move `SQLModel` to it own contrib package -* MongoEngine `EmbeddedDocumentField` is now converted into `CollectionField` - -### Removed - -* Remove PDF from default `export_types` - -## [0.2.2] - 2022-09-20 - ---- - -### Fixed - -* Null support for EnumField in [#17](https://github.com/jowilf/starlette-admin/pull/17) - - -## [0.2.1] - 2022-09-19 - ---- - -### Fixed - -* Fix SearchBuilder not working with dates (SQLAlchemy) in [#15](https://github.com/jowilf/starlette-admin/pull/15) - - -## [0.2.0] - 2022-09-14 - ---- - -### Changed - -* Date & Time input now use Flatpickr in [#10](https://github.com/jowilf/starlette-admin/pull/10) - - -## [0.1.1] - 2022-09-09 - ---- - -### Added - -- Add `ColorField` in [#7](https://github.com/jowilf/starlette-admin/pull/7) -- AsyncEngine support for SQLAlchemy in [#8](https://github.com/jowilf/starlette-admin/pull/8) diff --git a/docs/changelog/index.md b/docs/changelog/index.md index b39210f7..4ccdb2d9 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.5.0] - 2022-12-17 + +### Added + +* Introduce [`AdminUser`][starlette_admin.auth.AuthProvider.get_admin_user] and add navbar to show the current [`AdminUser`][starlette_admin.auth.AuthProvider.get_admin_user] information (`username` and `photo`) by [@jowilf](https://github.com/jowilf) in [#49](https://github.com/jowilf/starlette-admin/pull/49) + +### Internals + +* Add auth example by [@jowilf](https://github.com/jowilf) in [#51](https://github.com/jowilf/starlette-admin/pull/51) + ## [0.4.0] - 2022-12-07 --- diff --git a/docs/tutorial/authentication/index.es.md b/docs/tutorial/authentication/index.es.md deleted file mode 100644 index 1338a9b1..00000000 --- a/docs/tutorial/authentication/index.es.md +++ /dev/null @@ -1,124 +0,0 @@ -# Authentication & Authorization - -By default, *Starlette Admin* does not enforce any authentication to your application, but provides an -optional [AuthProvider][starlette_admin.auth.AuthProvider] you can use. - -## Authentication - -To enable authentication in your admin interface, inherit the [AuthProvider][starlette_admin.auth.AuthProvider] class -and set `auth_provider` when declaring your admin app - -The class [AuthProvider][starlette_admin.auth.AuthProvider] has three methods you need to override: - -* [is_authenticated][starlette_admin.auth.AuthProvider.is_authenticated] : Will be called for validating each incoming - request. -* [login][starlette_admin.auth.AuthProvider.login]: Will be called in the login page to validate username/password. -* [logout][starlette_admin.auth.AuthProvider.logout]: Will be called for the logout - -```python -from starlette.requests import Request -from starlette.responses import Response -from starlette_admin import BaseAdmin as Admin -from starlette_admin.auth import AuthProvider -from starlette_admin.exceptions import FormValidationError, LoginFailed - -users = { - "admin": ["admin"], - "john": ["post:list", "post:detail"], - "terry": ["post:list", "post:create", "post:edit"], - "doe": [""], -} - - -class MyAuthProvider(AuthProvider): - async def login( - self, - username: str, - password: str, - remember_me: bool, - request: Request, - response: Response, - ) -> Response: - if len(username) < 3: - raise FormValidationError( - {"username": "Ensure username has at least 03 characters"} - ) - if username in users and password == "password": - response.set_cookie(key="session", value=username) - return response - raise LoginFailed("Invalid username or password") - - async def is_authenticated(self, request) -> bool: - if "session" in request.cookies: - user_roles = users.get(request.cookies.get("session"), None) - if user_roles is not None: - """Save user roles in request state, can be use later, - to restrict user actions in admin interface""" - request.state.user_roles = user_roles - return True - return False - - async def logout(self, request: Request, response: Response): - response.delete_cookie("session") - return response - - -admin = Admin(auth_provider=MyAuthProvider()) - -``` - -??? note - Refer to [demo app](https://github.com/jowilf/starlette-admin-demo) for full example with starlette SessionMiddleware - -## Authorization - -### For all views - -Each [view][starlette_admin.views.BaseView] implement [is_accessible][starlette_admin.views.BaseView.is_accessible] method which can be used to restrict access -to current user. - -```python -from starlette_admin import CustomView -from starlette.requests import Request - -class ReportView(CustomView): - - def is_accessible(self, request: Request) -> bool: - return "admin" in request.state.user_roles -``` -!!! important - When view is inaccessible, it does not appear in menu structure - -### For [ModelView][starlette_admin.views.BaseModelView] -In [ModelView][starlette_admin.views.BaseModelView], there is four additional methods you can override -to restrict access to current user. - -* `can_view_details`: Permission for viewing full details of Items -* `can_create`: Permission for creating new Items -* `can_edit`: Permission for editing Items -* `can_delete`: Permission for deleting Items - -```python -from starlette_admin.contrib.sqla import ModelView -from starlette.requests import Request - -class PostView(ModelView): - - def is_accessible(self, request: Request) -> bool: - return ( - "admin" in request.state.user_roles - or "post:list" in request.state.user_roles - ) - - def can_view_details(self, request: Request) -> bool: - return "post:detail" in request.state.user_roles - - def can_create(self, request: Request) -> bool: - return "post:create" in request.state.user_roles - - def can_edit(self, request: Request) -> bool: - return "post:edit" in request.state.user_roles - - def can_delete(self, request: Request) -> bool: - return "admin" in request.state.user_roles -``` diff --git a/docs/tutorial/authentication/index.md b/docs/tutorial/authentication/index.md index cc4d7ac3..4971d08c 100644 --- a/docs/tutorial/authentication/index.md +++ b/docs/tutorial/authentication/index.md @@ -155,4 +155,4 @@ class ArticleView(ModelView): ## Example -For a working example, have a look at [https://github.com/jowilf/starlette-admin/tree/main/examples/auth](https://github.com/jowilf/starlette-admin/tree/main/examples/auth) +For a working example, have a look at [`https://github.com/jowilf/starlette-admin/tree/main/examples/auth`](https://github.com/jowilf/starlette-admin/tree/main/examples/auth) diff --git a/docs/tutorial/configurations/admin/index.es.md b/docs/tutorial/configurations/admin/index.es.md deleted file mode 100644 index 0f3b2079..00000000 --- a/docs/tutorial/configurations/admin/index.es.md +++ /dev/null @@ -1,33 +0,0 @@ -# Admin Configurations - -Multiple options are available to customize your admin interface - -```python -admin = Admin( - title="SQLModel Admin", - base_url="/admin", - route_name="admin", - statics_dir="statics/admin", - templates_dir="templates/admin", - logo_url="`https`://preview.tabler.io/static/logo-white.svg", - login_logo_url="`https`://preview.tabler.io/static/logo.svg", - index_view=CustomView(label="Home", icon="fa fa-home", path="/home", template_path="home.html"), - auth_provider=MyAuthProvider(login_path="/sign-in", logout_path="/sign-out"), - middlewares=[], - debug=False, -) -``` - - -## Parameters - -* `title`: Admin title. -* `base_url`: Base URL for Admin interface. -* `route_name`: Mounted Admin name -* `logo_url`: URL of logo to be displayed instead of title. -* `login_logo_url`: If set, it will be used for login interface instead of logo_url. -* `statics_dir`: Templates dir for static files customisation -* `templates_dir`: Templates dir for customisation -* `index_view`: CustomView to use for index page. -* `auth_provider`: Authentication Provider -* `middlewares`: Starlette middlewares diff --git a/docs/tutorial/configurations/modelview/index.es.md b/docs/tutorial/configurations/modelview/index.es.md deleted file mode 100644 index 381ad297..00000000 --- a/docs/tutorial/configurations/modelview/index.es.md +++ /dev/null @@ -1,117 +0,0 @@ -# ModelView Configurations - -Multiple options are available to customize your ModelView. For a complete list, have a look at the API documentation for -[BaseModelView()][starlette_admin.views.BaseModelView]. Here are some of the most commonly used options: - -## Fields - -Use `fields` property to customize which fields to include in admin view. - -```Python hl_lines="21" -from sqlalchemy import JSON, Column, Integer, String, Text, create_engine -from sqlalchemy.ext.declarative import declarative_base -from starlette.applications import Starlette -from starlette_admin import TagsField -from starlette_admin.contrib.sqla import Admin, ModelView - -Base = declarative_base() -engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) - - -class Post(Base): - __tablename__ = "posts" - - id = Column(Integer, primary_key=True) - title = Column(String) - tags = Column(JSON) - content = Column(Text) - - -class PostView(ModelView): - fields = ["id", "title", Post.content, TagsField("tags", label="Tags")] - - -app = Starlette() - -admin = Admin(engine) -admin.add_view(PostView(Post, icon="fa fa-blog")) -admin.mount_to(app) -``` - -## Exclusions - -There are several options to help you exclude some fields from certain part of admin interface. - -The options are: - -* `exclude_fields_from_list`: List of fields to exclude in List page. -* `exclude_fields_from_detail`: List of fields to exclude in Detail page. -* `exclude_fields_from_create`: List of fields to exclude from creation page. -* `exclude_fields_from_edit`: List of fields to exclude from editing page. - -```Python -class PostView(ModelView): - exclude_fields_from_list = [Post.content, Post.tags] -``` - -## Searching & Sorting - -Two options are available to specify which fields can be sorted or searched. - -* `searchable_fields` for list of searchable fields -* `sortable_fields` for list of orderable fields - -!!! Usage - ```Python - class PostView(ModelView): - sortable_fields = [Post.id, "title"] - searchable_fields = [Post.id, Post.title, "tags"] - ``` - -## Exporting - -You can export your data from list page. The export options can be set per model and includes the following options: - -* `export_fields`: List of fields to include in exports. -* `export_types`: A list of available export filetypes. Available -exports are `['csv', 'excel', 'pdf', 'print']`. By default, All of them are activated by default. - -!!! Example - ```Python - from starlette_admin import ExportType - - class PostView(ModelView): - export_fields = [Post.id, Post.content, Post.tags] - export_types = [ExportType.CSV, ExportType.EXCEL] - ``` - -## Pagination - -The pagination options in the list page can be configured. The available options are: - -* `page_size`: Default number of items to display in List page pagination. - Default value is set to `10`. -* `page_size_options`: Pagination choices displayed in List page. Default value is set to `[10, 25, 50, 100]`. - Use `-1`to display All - - -!!! Example - ```Python - class PostView(ModelView): - page_size = 5 - page_size_options = [5, 10, 25, 50, -1] - ``` - -## Templates -The template files are built using Jinja2 and can be completely overridden in the configurations. The pages available are: - -* `list_template`: List view template. Default is `list.html`. -* `detail_template`: Details view template. Default is `detail.html`. -* `create_template`: Edit view template. Default is `create.html`. -* `edit_template`: Edit view template. Default is `edit.html`. - -!!! Example - ```Python - class PostView(ModelView): - detail_template = "post_detail.html" - ``` diff --git a/docs/tutorial/getting-started/index.es.md b/docs/tutorial/getting-started/index.es.md deleted file mode 100644 index 7caff715..00000000 --- a/docs/tutorial/getting-started/index.es.md +++ /dev/null @@ -1,258 +0,0 @@ -# Getting started - -## Initialization - -The first step is to initialize an empty admin interface for your app: - -=== "SQLAlchemy" - ```python - from sqlalchemy import create_engine - from starlette_admin.contrib.sqla import Admin - - engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) - - admin = Admin(engine) - ``` -=== "SQLModel" - ```python - from sqlalchemy import create_engine - from starlette_admin.contrib.sqlmodel import Admin - - engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) - - admin = Admin(engine) - ``` -=== "MongoEngine" - ```python - from starlette_admin.contrib.mongoengine import Admin - - admin = Admin() - ``` -=== "ODMantic" - ```python - from odmantic import AIOEngine - from starlette_admin.contrib.odmantic import Admin - - engine = AIOEngine() - - admin = Admin(engine) - ``` - -## Adding Views - -### ModelView - -Model views allow you to add a dedicated set of admin pages for managing any model. - -=== "SQLAlchemy" - ```python hl_lines="2 10-11" - from sqlalchemy import create_engine - from starlette_admin.contrib.sqla import Admin, ModelView - - from .models import User, Post - - engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) - - admin = Admin(engine) - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - ``` -=== "SQLModel" - ```python hl_lines="2 10-11" - from sqlalchemy import create_engine - from starlette_admin.contrib.sqlmodel import Admin, ModelView - - from .models import User, Post - - engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) - - admin = Admin(engine) - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - ``` -=== "MongoEngine" - ```python hl_lines="1 7-8" - from starlette_admin.contrib.mongoengine import Admin, ModelView - - from .models import Post, User - - admin = Admin() - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - ``` -=== "ODMantic" - ```python hl_lines="2 10-11" - from odmantic import AIOEngine - from starlette_admin.contrib.odmantic import Admin, ModelView - - from .models import Post, User - - engine = AIOEngine() - - admin = Admin(engine) - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - ``` -This gives you a set of fully featured CRUD views for your model: - -- A *list view*, with support for searching, sorting, filtering, and deleting records. -- A *create view* for adding new records. -- An *edit view* for updating existing records. -- A read-only *details view*. - -### CustomView - -With [CustomView][starlette_admin.views.CustomView] you can add your own views (not tied to any particular model). For example, -a custom home page that displays some analytics data. - -```python -from starlette_admin import CustomView - -admin.add_view(CustomView(label="Home", icon="fa fa-home", path="/home", template_path="home.html")) - -``` - -To have a full control of the rendering, override the `render` methods - -```python -from starlette.requests import Request -from starlette.responses import Response -from starlette.templating import Jinja2Templates -from starlette_admin import CustomView - - -class HomeView(CustomView): - async def render(self, request: Request, templates: Jinja2Templates) -> Response: - return templates.TemplateResponse( - "home.html", {"request": request, "latest_posts": ..., "top_users": ...} - ) - - -admin.add_view(HomeView(label="Home", icon="fa fa-home", path="/home")) -``` - - -### Link - -Use [Link][starlette_admin.views.Link] to add arbitrary hyperlinks to the menu - -```python -from starlette_admin.views import Link - -admin.add_view(Link(label="Home Page", icon="fa fa-link", url="/")) -``` - -### DropDown - -Use [DropDown][starlette_admin.views.DropDown] to group views together in menu structure - -```python -from starlette_admin import CustomView, DropDown -from starlette_admin.contrib.sqla import ModelView -from starlette_admin.views import Link - -from .models import User - -admin.add_view( - DropDown( - "Resources", - icon="fa fa-list", - views=[ - ModelView(User), - Link(label="Home Page", url="/"), - CustomView(label="Dashboard", path="/dashboard", template_path="dashboard.html"), - ], - ) -) - -``` - -## Mount admin to your app - -The last step is to mount the admin interfaces to your app - -=== "SQLAlchemy" - ```python hl_lines="2 9 16" - from sqlalchemy import create_engine - from starlette.applications import Starlette - from starlette_admin.contrib.sqla import Admin, ModelView - - from .models import Post, User - - engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) - - app = Starlette() # FastAPI() - - admin = Admin(engine) - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - admin.mount_to(app) - - ``` -=== "SQLModel" - ```python hl_lines="2 9 16" - from sqlalchemy import create_engine - from starlette.applications import Starlette - from starlette_admin.contrib.sqlmodel import Admin, ModelView - - from .models import Post, User - - engine = create_engine("sqlite:///test.db", connect_args={"check_same_thread": False}) - - app = Starlette() # FastAPI() - - admin = Admin(engine) - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - admin.mount_to(app) - - ``` -=== "MongoEngine" - ```python hl_lines="1 6 13" - from starlette.applications import Starlette - from starlette_admin.contrib.mongoengine import Admin, ModelView - - from .models import Post, User - - app = Starlette() # FastAPI() - - admin = Admin() - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - admin.mount_to(app) - ``` -=== "ODMantic" - ```python hl_lines="2 9 16" - from odmantic import AIOEngine - from starlette.applications import Starlette - from starlette_admin.contrib.odmantic import Admin, ModelView - - from .models import Post, User - - engine = AIOEngine() - - app = Starlette() # FastAPI() - - admin = Admin(engine) - - admin.add_view(ModelView(User)) - admin.add_view(ModelView(Post)) - - admin.mount_to(app) - ``` - -You can now access your admin interfaces in your browser at [http://localhost:8000/admin](http://localhost:8000/admin) diff --git a/docs/tutorial/multiple-admin/index.es.md b/docs/tutorial/multiple-admin/index.es.md deleted file mode 100644 index 41dbe43e..00000000 --- a/docs/tutorial/multiple-admin/index.es.md +++ /dev/null @@ -1,30 +0,0 @@ -# Multiple Admin - -You can add multiple admin to your app with different or same views. To manage this, simply use different `base_url` -and `route_name` - -```python -from starlette.applications import Starlette -from starlette_admin import BaseAdmin as Admin -from starlette_admin.contrib.sqla import ModelView - -app = Starlette() - -admin1 = Admin( - "Admin1", base_url="/admin1", route_name="admin1", templates_dir="templates/admin1" -) -admin1.add_view(ModelView(Report)) -admin1.add_view(ModelView(Post)) -admin1.mount_to(app) - -admin2 = Admin( - "Admin2", base_url="/admin2", route_name="admin2", templates_dir="templates/admin2" -) -admin2.add_view(ModelView(Post)) -admin2.add_view(ModelView(User)) -admin2.mount_to(app) - -assert app.url_path_for("admin1:index") == "/admin1/" -assert app.url_path_for("admin2:index") == "/admin2/" - -``` diff --git a/docs/tutorial/validations/index.es.md b/docs/tutorial/validations/index.es.md deleted file mode 100644 index 1f03cdbc..00000000 --- a/docs/tutorial/validations/index.es.md +++ /dev/null @@ -1,129 +0,0 @@ -# Forms Validations - -By design, *Starlette-admin* doesn't validate your data, the validation will depend on your database backend - -## SQLAlchemy - -When working with sqlalchemy, you need to write your own validation logic to validate the data submitted in forms. - -!!!Example - ```python - from starlette_admin.contrib.sqla import ModelView - from starlette_admin.exceptions import FormValidationError - - - class PostView(ModelView): - - async def validate(self, request: Request, data: Dict[str, Any]) -> None: - """Raise FormValidationError to display error in forms""" - errors: Dict[str, str] = dict() - _2day_from_today = date.today() + timedelta(days=2) - if data["title"] is None or len(data["title"]) < 3: - errors["title"] = "Ensure this value has at least 03 characters" - if data["text"] is None or len(data["text"]) < 10: - errors["text"] = "Ensure this value has at least 10 characters" - if data["date"] is None or data["date"] < _2day_from_today: - errors["date"] = "We need at least one day to verify your post" - if data["publisher"] is None: - errors["publisher"] = "Publisher is required" - if data["tags"] is None or len(data["tags"]) < 1: - errors["tags"] = "At least one tag is required" - if len(errors) > 0: - raise FormValidationError(errors) - return await super().validate(request, data) - ``` - - ![SQLAlchemy Form Validations](../../images/validations/sqla.png) - -??? info - Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/sqla) - - -## SQLModel - -For SQLModel, you just need to define your model and submitted data are automatically validated. - -!!! Example - ```python - from sqlmodel import SQLModel, Field - from pydantic import validator - - - class Post(SQLModel, table=True): - id: Optional[int] = Field(primary_key=True) - title: str = Field() - content: str = Field(min_length=10) - views: int = Field(multiple_of=4) - - @validator('title') - def title_must_contain_space(cls, v): - if ' ' not in v: - raise ValueError('title must contain a space') - return v.title() - ``` - - ![SQLModel Form Validations](../../images/validations/sqlmodel.png) - -??? info - Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/sqlmodel) - - - -## Odmantic - -The submitted data will be automatically validated according to your model definition. - -!!! Example - ```python - from typing import List, Optional - - from odmantic import EmbeddedModel, Field, Model - from pydantic import EmailStr - - - class Address(EmbeddedModel): - street: str = Field(min_length=3) - city: str = Field(min_length=3) - state: Optional[str] - zipcode: Optional[str] - - - class Author(Model): - first_name: str = Field(min_length=3) - last_name: str = Field(min_length=3) - email: Optional[EmailStr] - addresses: List[Address] = Field(default_factory=list) - - ``` - - ![SQLModel Form Validations](../../images/validations/odmantic.png) - - -??? info - Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/odmantic) - - -## MongoEngine - -The submitted data will be automatically validated according to your model definition. - -!!! Example - ```python - import mongoengine as db - - class Comment(db.EmbeddedDocument): - name = db.StringField(min_length=3, max_length=20, required=True) - value = db.StringField(max_length=20) - - - class Post(db.Document): - name = db.StringField(max_length=20, required=True) - value = db.StringField(max_length=20) - inner = db.ListField(db.EmbeddedDocumentField(Comment)) - lols = db.ListField(db.StringField(max_length=20)) - ``` - - ![SQLModel Form Validations](../../images/validations/mongoengine.png) - -??? info - Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/mongoengine) diff --git a/starlette_admin/__init__.py b/starlette_admin/__init__.py index 4e654a14..7ffabdc9 100644 --- a/starlette_admin/__init__.py +++ b/starlette_admin/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.4.0" +__version__ = "0.5.0" from ._types import ExportType, RequestAction from .actions import action