From 3a3df85a0cc56bd73704886c9689b3cafb14ade3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hasan=20Sezer=20Ta=C5=9Fan?= <13135006+hasansezertasan@users.noreply.github.com> Date: Fri, 29 Dec 2023 05:41:25 +0300 Subject: [PATCH] Removed dobule spaces, fixed some broken admonition syntax, added single spaces before and after headings. (#446) * Removed dobule empty lines, fixed some broken admonition syntax. * Remove unnecessary argument for func.count --------- Co-authored-by: Jocelin Hounon --- docs/advanced/base-model-view/index.md | 3 ++- docs/advanced/custom-field/index.md | 12 +++++++--- docs/index.es.md | 1 + docs/index.md | 1 + docs/tutorial/authentication/index.md | 2 ++ docs/tutorial/configurations/admin/index.md | 1 - .../configurations/modelview/index.md | 23 ++++++++++++------- docs/tutorial/files/index.md | 3 ++- docs/tutorial/getting-started/index.md | 1 - docs/tutorial/validations/index.md | 17 ++++++++------ starlette_admin/actions.py | 4 ++++ starlette_admin/contrib/sqla/view.py | 2 +- starlette_admin/fields.py | 14 +++++++---- starlette_admin/views.py | 11 ++++++--- 14 files changed, 65 insertions(+), 30 deletions(-) diff --git a/docs/advanced/base-model-view/index.md b/docs/advanced/base-model-view/index.md index 73f5a1d8..742aff86 100644 --- a/docs/advanced/base-model-view/index.md +++ b/docs/advanced/base-model-view/index.md @@ -53,6 +53,7 @@ class PostView(BaseModelView): ``` !!! important + `identity` is used to identify the model associated to this view and should be unique. ## Primary key @@ -97,6 +98,7 @@ Finally, you need to implement these CRUD methods: * [delete()][starlette_admin.BaseModelView.delete] ## Full example + ```python from dataclasses import dataclass from typing import Any, Dict, Iterable, List, Optional, Union @@ -221,5 +223,4 @@ class PostView(BaseModelView): del db[int(pk)] cnt += 1 return cnt - ``` diff --git a/docs/advanced/custom-field/index.md b/docs/advanced/custom-field/index.md index c88d1c41..397d0086 100644 --- a/docs/advanced/custom-field/index.md +++ b/docs/advanced/custom-field/index.md @@ -4,6 +4,7 @@ according to your need. !!! important + Before creating a new field, try first to extend the existing ones. They are flexible enough to fit most use cases. The first step is to define a new class, which derives from [BaseField][starlette_admin.fields.BaseField] or any others fields to customize it @@ -28,7 +29,9 @@ read [Datatables documentation](https://datatables.net/reference/option/columns. the admin class !!! Example + This is simple example with SQLAlchemy backend + ```python from starlette_admin.contrib.sqla import Admin as BaseAdmin @@ -47,7 +50,9 @@ the admin class }, }); ``` + !!! note + `fieldOptions` is your field as javascript object. Your field attributes is serialized into javascript object by using dataclass `asdict` function. @@ -74,6 +79,7 @@ These jinja2 variables are available: * `action`: `EDIT` or `CREATE` !!! Example + ```html title="forms/custom.html"
@@ -85,6 +91,7 @@ These jinja2 variables are available:
{{error}}
{%endif%} ``` + ```python from starlette_admin import BaseField from dataclasses import dataclass @@ -104,11 +111,12 @@ These jinja2 variables are available: * `field`: Your field instance * `data`: value to display - !!! Example + ```html title="displays/custom.html" Hello {{data}} ``` + ```python from starlette_admin import BaseField from dataclasses import dataclass @@ -128,7 +136,6 @@ For data processing you will need to override two functions: * `serialize_field_value`: Will be call when serializing value to send through the API. This is the same data you will get in your *render* function - ```python from dataclasses import dataclass from typing import Any, Dict @@ -155,6 +162,5 @@ class CustomField(BaseField): ``` - !!! important Override `dict` function to get control of the options which is available in javascript. diff --git a/docs/index.es.md b/docs/index.es.md index 219d78e6..ca9ce8bd 100644 --- a/docs/index.es.md +++ b/docs/index.es.md @@ -96,6 +96,7 @@ admin.add_view(ModelView(Post)) # Montar admin a tu app admin.mount_to(app) ``` + Acceda a su interfaz de administrador en su navegador en [http://localhost:8000/admin](http://localhost:8000/admin) ## Terceros diff --git a/docs/index.md b/docs/index.md index ed85a736..37ce7c17 100644 --- a/docs/index.md +++ b/docs/index.md @@ -100,6 +100,7 @@ admin.add_view(ModelView(Post)) # Mount admin to your app admin.mount_to(app) ``` + Access your admin interface in your browser at [http://localhost:8000/admin](http://localhost:8000/admin) ## Third party diff --git a/docs/tutorial/authentication/index.md b/docs/tutorial/authentication/index.md index 1c50bb30..1e0060e1 100644 --- a/docs/tutorial/authentication/index.md +++ b/docs/tutorial/authentication/index.md @@ -236,7 +236,9 @@ 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] diff --git a/docs/tutorial/configurations/admin/index.md b/docs/tutorial/configurations/admin/index.md index 10726c70..4eafea45 100644 --- a/docs/tutorial/configurations/admin/index.md +++ b/docs/tutorial/configurations/admin/index.md @@ -19,7 +19,6 @@ admin = Admin( ) ``` - ## Parameters * `title`: Admin title. diff --git a/docs/tutorial/configurations/modelview/index.md b/docs/tutorial/configurations/modelview/index.md index 1ecbe15a..23300b2b 100644 --- a/docs/tutorial/configurations/modelview/index.md +++ b/docs/tutorial/configurations/modelview/index.md @@ -9,7 +9,7 @@ Here are some of the most commonly used options: You can use the `fields` property of the ModelView class to customize which fields are included in the admin view. -```Python hl_lines="21" +```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 @@ -50,12 +50,13 @@ view. These options include: * `exclude_fields_from_create`: List of fields to exclude from the creation page. * `exclude_fields_from_edit`: List of fields to exclude from the editing page.\ -```Python +```python class PostView(ModelView): exclude_fields_from_list = [Post.content, Post.tags] ``` !!! note + For more advanced use cases, you can override the [ModelView.get_fields_list()][starlette_admin.views.BaseModelView.get_fields_list] function. @@ -68,7 +69,8 @@ Several options are available to specify which fields can be sorted or searched. * `fields_default_sort` for initial order (sort) to apply to the table !!! Usage - ```Python + + ```python class PostView(ModelView): sortable_fields = [Post.id, "title"] searchable_fields = [Post.id, Post.title, "tags"] @@ -86,7 +88,8 @@ You can specify the export options for each ModelView using the following attrib exports are `['csv', 'excel', 'pdf', 'print']`. By default, only `pdf` is disabled. !!! Example - ```Python + + ```python from starlette_admin import ExportType class PostView(ModelView): @@ -103,9 +106,9 @@ The pagination options in the list page can be configured. The available options * `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 + + ```python class PostView(ModelView): page_size = 5 page_size_options = [5, 10, 25, 50, -1] @@ -120,7 +123,8 @@ The template files are built using Jinja2 and can be completely overridden in th * `edit_template`: Edit view template. Default is `edit.html`. !!! Example - ```Python + + ```python class PostView(ModelView): detail_template = "post_detail.html" ``` @@ -136,6 +140,7 @@ in your `ModelView` by overridden following options: * `save_state`: Enable/Disable [state saving](https://datatables.net/examples/basic_init/state_save.html) !!! Example + ```python class PostView(ModelView): column_visibility = False @@ -155,6 +160,7 @@ interface. By default, only the value of the object's primary key attribute is d `__admin_repr__`, you can return a string that better represents the object in the admin interface. !!! Example + For example, the following implementation for a `User` model will display the user's full name instead of their primary key in the admin interface: @@ -170,7 +176,6 @@ interface. By default, only the value of the object's primary key attribute is d ![Custom Object representation](../../../images/tutorial/configurations/modelview/object_text_representation.png){ width="200" } - ### `__admin_select2_repr__` This method is similar to `__admin_repr__`, but it returns an HTML string that is used to display the object in @@ -178,9 +183,11 @@ a `select2` widget. By default, all the object's attributes allowed for detail p fields. !!! note + The returned value should be valid HTML. !!! danger + Escape your database value to avoid Cross-Site Scripting (XSS) attack. You can use Jinja2 Template render with `autoescape=True`. For more information, visit [OWASP website](https://owasp.org/www-community/attacks/xss/) diff --git a/docs/tutorial/files/index.md b/docs/tutorial/files/index.md index 65e8b2e7..4b0372c8 100644 --- a/docs/tutorial/files/index.md +++ b/docs/tutorial/files/index.md @@ -29,9 +29,10 @@ class BookView(ModelView): admin.add_view(BookView(Book)) ``` + !!! note - You can also use `multiple=True` to save multiple files. + You can also use `multiple=True` to save multiple files. ## MongoEngine diff --git a/docs/tutorial/getting-started/index.md b/docs/tutorial/getting-started/index.md index 7caff715..63f58ad0 100644 --- a/docs/tutorial/getting-started/index.md +++ b/docs/tutorial/getting-started/index.md @@ -139,7 +139,6 @@ class HomeView(CustomView): 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 diff --git a/docs/tutorial/validations/index.md b/docs/tutorial/validations/index.md index 7284e12b..1d99c898 100644 --- a/docs/tutorial/validations/index.md +++ b/docs/tutorial/validations/index.md @@ -16,7 +16,7 @@ capabilities using Python's type hints. To automatically validate submitted data with Pydantic, you only need to define a Pydantic model and use `starlette_admin.contrib.sqla.ext.pydantic.ModelView` -!!!Example +!!! Example ```python from starlette_admin.contrib.sqla.ext.pydantic import ModelView @@ -53,7 +53,8 @@ use `starlette_admin.contrib.sqla.ext.pydantic.ModelView` You can also create your own validation functions to enforce specific data requirements. -!!!Example +!!! Example + ```python from starlette_admin.contrib.sqla import ModelView from starlette_admin.exceptions import FormValidationError @@ -83,8 +84,8 @@ You can also create your own validation functions to enforce specific data requi ![SQLAlchemy Form Validations](../../images/validations/sqla.png) ??? info - Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/sqla) + Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/sqla) ## SQLModel @@ -92,6 +93,7 @@ With SQLModel, validating your data is made easy. Once you've defined your model automatically validated. !!! Example + ```python from sqlmodel import SQLModel, Field from pydantic import validator @@ -113,9 +115,8 @@ automatically validated. ![SQLModel Form Validations](../../images/validations/sqlmodel.png) ??? info - Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/sqlmodel) - + Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/sqlmodel) ## Odmantic @@ -123,6 +124,7 @@ Validation of submitted data is handled seamlessly by Odmantic. Any data that yo validated automatically. !!! Example + ```python from typing import List, Optional @@ -147,16 +149,16 @@ validated automatically. ![SQLModel Form Validations](../../images/validations/odmantic.png) - ??? info - Full example available [here](https://github.com/jowilf/starlette-admin/tree/main/examples/odmantic) + 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 @@ -175,4 +177,5 @@ The submitted data will be automatically validated according to your model defin ![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/actions.py b/starlette_admin/actions.py index cd54fc2d..e0e1dabe 100644 --- a/starlette_admin/actions.py +++ b/starlette_admin/actions.py @@ -31,6 +31,7 @@ def action( !!! usage + ```python class ArticleView(ModelView): actions = ['make_published', 'redirect'] @@ -129,6 +130,7 @@ def row_action( !!! usage + ```python @row_action( name="make_published", @@ -182,6 +184,7 @@ def link_row_action( Decorator to add custom row link actions to a ModelView for URL redirection. !!! note + This decorator is designed to create row actions that redirect to a URL, making it ideal for cases where a row action should simply navigate users to a website or internal page. @@ -195,6 +198,7 @@ def link_row_action( !!! usage + ```python @link_row_action( name="go_to_example", diff --git a/starlette_admin/contrib/sqla/view.py b/starlette_admin/contrib/sqla/view.py index 93f17c8f..2d0ae323 100644 --- a/starlette_admin/contrib/sqla/view.py +++ b/starlette_admin/contrib/sqla/view.py @@ -222,7 +222,7 @@ def get_count_query(self): return super().get_count_query().where(Post.published == true()) ``` """ - return select(func.count("*")).select_from(self.model) + return select(func.count()).select_from(self.model) def get_search_query(self, request: Request, term: str) -> Any: """ diff --git a/starlette_admin/fields.py b/starlette_admin/fields.py index 17b01a94..847abdd8 100644 --- a/starlette_admin/fields.py +++ b/starlette_admin/fields.py @@ -108,6 +108,7 @@ async def parse_obj(self, request: Request, obj: Any) -> Any: However, this function can be overridden to provide custom logic for computing the value of a field. ??? Example + ```py # Suppose we have a `User` model with `id`, `first_name`, and `last_name` fields. # We define a custom field called `MyCustomField` to compute the full name of the user: @@ -145,6 +146,7 @@ async def serialize_value( """Formats a value for sending to the frontend based on the current request action. !!! important + Make sure this value is JSON Serializable for RequestAction.LIST and RequestAction.API Args: @@ -469,7 +471,7 @@ class EnumField(StringField): It takes a python `enum.Enum` class or a list of *(value, label)* pairs. It can also be a list of only values, in which case the value is used as the label. Example: - ```Python + ```python class Status(str, enum.Enum): NEW = "new" ONGOING = "ongoing" @@ -482,7 +484,7 @@ class MyModelView(ModelView): fields = [EnumField("status", enum=Status)] ``` - ```Python + ```python class MyModel: language: str @@ -958,6 +960,7 @@ class RelationField(BaseField): between your models. !!! important + It is important to add both models in your admin interface. Parameters: @@ -965,6 +968,7 @@ class RelationField(BaseField): ??? Example + ```py class Author: id: Optional[int] @@ -1054,7 +1058,8 @@ class HasMany(RelationField): class CollectionField(BaseField): """ This field represents a collection of others fields. Can be used to represent embedded mongodb document. - !!!usage + !!! usage + ```python CollectionField("config", fields=[StringField("key"), IntegerField("value", help_text="multiple of 5")]), ``` @@ -1134,7 +1139,8 @@ class ListField(BaseField): Encapsulate an ordered list of multiple instances of the same field type, keeping data as a list. - !!!usage + !!! usage + ```python class MyModel: id: Optional[int] diff --git a/starlette_admin/views.py b/starlette_admin/views.py index 97502158..df12e8dc 100644 --- a/starlette_admin/views.py +++ b/starlette_admin/views.py @@ -67,7 +67,7 @@ class DropDown(BaseView): Group views inside a dropdown Example: - ```Python + ```python admin.add_view( DropDown( "Resources", @@ -108,7 +108,7 @@ class Link(BaseView): Add arbitrary hyperlinks to the menu Example: - ```Python + ```python admin.add_view(Link(label="Home Page", icon="fa fa-link", url="/")) ``` """ @@ -139,7 +139,7 @@ class CustomView(BaseView): add_to_menu: Display to menu or not Example: - ```Python + ```python admin.add_view(CustomView(label="Home", icon="fa fa-home", path="/home", template_path="home.html")) ``` """ @@ -686,6 +686,7 @@ async def serialize_field_value( Format output value for each field. !!! important + The returned value should be json serializable Parameters: @@ -802,9 +803,11 @@ async def select2_result(self, obj: Any, request: Request) -> str: HTML-formatted string. !!! note + The returned value should be valid HTML. !!! danger + Escape your database value to avoid Cross-Site Scripting (XSS) attack. You can use Jinja2 Template render with `autoescape=True`. For more information [click here](https://owasp.org/www-community/attacks/xss/) @@ -857,9 +860,11 @@ async def select2_selection(self, obj: Any, request: Request) -> str: By default, it simply calls `select2_result()`. !!! note + The returned value should be valid HTML. !!! danger + Escape your database value to avoid Cross-Site Scripting (XSS) attack. You can use Jinja2 Template render with `autoescape=True`. For more information [click here](https://owasp.org/www-community/attacks/xss/)