Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Components

Overview

We supply some pre-designed that components can be used to help simplify development.


PyScript Component

This allows you to embedded any number of client-side PyScript components within traditional ReactPy components.

By default, the onlyavailable dependencies are the Python standard library,pyscript,pyodide,reactpy core.

The entire file path provided is loaded directly into the browser, and must have adefroot() component to act as the entry point.

Pitfall

Similar to JavaScript, your provided Python file is loaded directly into the client (web browser)as raw text to run using the PyScript interpreter. Be cautious about what you include in your Python file.

As a result being client-sided, Python packages within your local environment (such as those installed viapip install ...) arenot accessible within PyScript components.

 1 2 3 4 5 6 7 8 91011
fromreactpyimportcomponent,htmlfromreactpy_django.componentsimportpyscript_component@componentdefserver_side_component():returnhtml.div("This text is from my server-side component",pyscript_component("./example_project/my_app/components/root.py"),)
123456
fromreactpyimportcomponent,html@componentdefroot():returnhtml.div("This text is from my client-side component")
 1 2 3 4 5 6 7 8 91011121314
{%loadreactpy%}<!DOCTYPE html><html><head>    <title>ReactPy</title>{%pyscript_setup%}</head><body>{%component"example_project.my_app.components.server_side_component"%}</body></html>
See Interface

NameTypeDescriptionDefault
*file_pathsstrFile path to your client-side component. If multiple paths are provided, the contents are automatically merged.N/A
initialstr|VdomDict|ComponentTypeThe initial HTML that is displayed prior to the PyScript component loads. This can either be a string containing raw HTML, areactpy.html snippet, or a non-interactive component.""
rootstrThe name of the root component function."root"
You must callpyscript_setup in your Django template before using this tag!

This requires using of the{%pyscript_setup%} template tag to initialize PyScript on the client.

123456
{%loadreactpy%}<head>    <title>ReactPy</title>{%pyscript_setup%}</head>
How do I execute JavaScript within PyScript components?

PyScript components several options available to execute JavaScript, including...

Pyodide JS Module

The Pyodidejs module has access to everything within the browser's JavaScript environment. Therefore, any global JavaScript functions loaded within your HTML<head> can be called as well. However, you will need to be mindful of JavaScript load order if usingasync ordeferred loading!

 1 2 3 4 5 6 7 8 910
importjsfromreactpyimportcomponent,html@componentdefroot():defon_click(event):js.document.title="New window title"returnhtml.button({"onClick":on_click},"Click Me!")

PyScript Foreign Function Interface (FFI)

PyScript FFI has similar functionality to Pyodide'sjs module, but utilizes a different API.

There are two importable modules available that are available within the FFI interface:window anddocument.

 1 2 3 4 5 6 7 8 91011121314
frompyscriptimportdocument,windowfromreactpyimportcomponent,html@componentdefroot():defon_click(event):my_element=document.querySelector("#example")my_element.innerText=window.location.hostnamereturnhtml.div({"id":"example"},html.button({"onClick":on_click},"Click Me!"),)

PyScript JS Modules

Assuming you have a local bundle stored within your project's static files, you can import JavaScript modules in a fashion similar toimport{moment}from'static/moment.js'. You will first need to configure your{%pyscript_setup%} block to make themoment.js module available to PyScript. Then, this module can be accessed withinpyscript.js_modules.*.

 1 2 3 4 5 6 7 8 9101112
fromreactpyimportcomponent,html@componentdefroot():frompyscript.js_modulesimportmomentreturnhtml.div({"id":"moment"},"Using the JavaScript package 'moment' to calculate time: ",moment.default().format("YYYY-MM-DD HH:mm:ss"),)
 1 2 3 4 5 6 7 8 91011121314
{%loadreactpy%}<!DOCTYPE html><html><head>    <title>ReactPy</title>{%pyscript_setupextra_js='{"/static/moment.js":"moment"}'%}</head><body>{%component"example_project.my_app.components.root.py"%}</body></html>
Does my entire component need to be contained in one file?

Splitting a large file into multiple files is a common practice in software development.

However, PyScript components are run on the client browser. As such, they do not have access to your local development environment, and thus cannotimport any local Python files.

If your PyScript component file gets too large, you can declare multiple file paths instead. These files will automatically combined by ReactPy.

Here is how we recommend splitting your component into multiple files while avoiding local imports but retaining type hints.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromreactpy_django.componentsimportpyscript_component@componentdefserver_side_component():returnhtml.div(pyscript_component("./example_project/my_app/components/root.py","./example_project/my_app/components/child.py",),)
12345678
fromreactpyimportcomponent,htmlfromexample.componentsimportchild_component@componentdefroot():returnhtml.div("This text is from the root component.",child_component())
123456
fromreactpyimportcomponent,html@componentdefchild_component():returnhtml.div("This is a child component from a different file.")
How do I display something while the component is loading?

You can configure theinitial keyword to display HTML while your PyScript component is loading.

The value forinitial is most commonly be areactpy.html snippet or a non-interactive@component.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromreactpy_django.componentsimportpyscript_component@componentdefserver_side_component():returnhtml.div(pyscript_component("./example_project/my_app/components/root.py",initial=html.div("Loading ..."),),)

However, you can also use a string containing raw HTML.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromreactpy_django.componentsimportpyscript_component@componentdefserver_side_component():returnhtml.div(pyscript_component("./example_project/my_app/components/root.py",initial="<div> Loading ... </div>",),)
Can I use a different name for my root component?

Yes, you can use theroot keyword to specify a different name for your root function.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromreactpy_django.componentsimportpyscript_component@componentdefserver_side_component():returnhtml.div(pyscript_component("./example_project/my_app/components/main.py",root="main",),)
123456
fromreactpyimportcomponent,html@componentdefmain():returnhtml.div("Hello, World!")

View To Component

Automatically convert a Django view into a component.

At this time, this works best with static views with no interactivity.

Compatible with sync or asyncFunction Based Views andClass Based Views.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_componenthello_world_component=view_to_component(views.hello_world)@componentdefmy_component():returnhtml.div(hello_world_component(),)
12345
fromdjango.httpimportHttpResponsedefhello_world(request):returnHttpResponse("Hello World!")
See Interface

NameTypeDescriptionDefault
viewCallable|View|strThe view to convert, or the view's dotted path as a string.N/A
transformsSequence[Callable[[VdomDict],Any]]A list of functions that transforms the newly generated VDOM. The functions will be called on each VDOM node.tuple
strict_parsingboolIfTrue, an exception will be generated if the HTML does not perfectly adhere to HTML5.True

TypeDescription
constructorA function that takesrequest,*args,key,**kwargs and returns a ReactPy component. Note that*args and**kwargs are directly provided to your view.
Existing limitations

There are currently several limitations of usingview_to_component that will beresolved in a future version.

  • Requires manual intervention to change HTTP methods to anything other thanGET.
  • ReactPy events cannot conveniently be attached to converted view HTML.
  • Has no option to automatically intercept click events from hyperlinks (such as<ahref='example/'></a>).
How do I use this for Class Based Views?

Class Based Views are accepted byview_to_component as an argument.

Callingas_view() is optional, but recommended.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_componenthello_world_component=view_to_component(views.HelloWorld.as_view())@componentdefmy_component():returnhtml.div(hello_world_component(),)
1234567
fromdjango.httpimportHttpResponsefromdjango.viewsimportViewclassHelloWorld(View):defget(self,request):returnHttpResponse("Hello World!")
How do I providerequest,args, andkwargs to a converted view?

This component acceptsrequest,*args, and**kwargs arguments, which are sent to your provided view.

 1 2 3 4 5 6 7 8 91011121314151617181920212223
fromdjango.httpimportHttpRequestfromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_componenthello_world_component=view_to_component(views.hello_world)@componentdefmy_component():request=HttpRequest()request.method="GET"returnhtml.div(hello_world_component(request,# This request object is optional."value_1","value_2",kwarg1="abc",kwarg2="123",),)
12345
fromdjango.httpimportHttpResponsedefhello_world(request,arg1,arg2,kwarg1=None,kwarg2=None):returnHttpResponse(f"Hello World!{arg1}{arg2}{kwarg1}{kwarg2}")
How do I customize this component's behavior?

This component accepts arguments that can be used to customize its behavior.

Below are all the arguments that can be used.


By default, an exception will be generated if your view's HTML does not perfectly adhere to HTML5.

However, there are some circumstances where you may not have control over the original HTML, so you may be unable to fix it. Or you may be relying on non-standard HTML tags such as<my-tag> Hello World</my-tag>.

In these scenarios, you may want to rely on best-fit parsing by setting thestrict_parsing parameter toFalse. This useslibxml2 recovery algorithm, which is designed to be similar to how web browsers would attempt to parse non-standard or broken HTML.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_componenthello_world_component=view_to_component(views.hello_world)@componentdefmy_component():returnhtml.div(hello_world_component(),)
12345
fromdjango.httpimportHttpResponsedefhello_world(request):returnHttpResponse("Hello World!")

After your view has been turned intoVDOM (python dictionaries),view_to_component will call yourtransforms functions on every VDOM node.

This allows you to modify your view prior to rendering.

For example, if you are trying to modify the text of a node with a certainid, you can create a transform like such:

 1 2 3 4 5 6 7 8 91011121314151617181920
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_componentdefexample_transform(vdom):attributes=vdom.get("attributes")ifattributesandattributes.get("id")=="hello-world":vdom["children"][0]="Farewell World!"hello_world_component=view_to_component(views.hello_world,transforms=[example_transform])@componentdefmy_component():returnhtml.div(hello_world_component(),)
12345
fromdjango.httpimportHttpResponsedefhello_world(request):returnHttpResponse('<div id="hello-world"> Hello World! </div>')

View To Iframe

Automatically convert a Django view into aniframe element.

The contents of thisiframe is handled entirely by traditional Django view rendering. While this solution is compatible with more views thanview_to_component, it comes with different limitations.

Compatible with sync or asyncFunction Based Views andClass Based Views.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_iframehello_world_iframe=view_to_iframe(views.hello_world)@componentdefmy_component():returnhtml.div(hello_world_iframe(),)
12345
fromdjango.httpimportHttpResponsedefhello_world(request):returnHttpResponse("Hello World!")
 1 2 3 4 5 6 7 8 91011
fromdjango.appsimportAppConfigfromexampleimportviewsfromreactpy_django.utilsimportregister_iframeclassExampleAppConfig(AppConfig):name="example"defready(self):register_iframe(views.hello_world)
See Interface

NameTypeDescriptionDefault
viewCallable|View|strThe view function or class to convert.N/A
extra_propsMapping[str,Any]|NoneAdditional properties to add to theiframe element.None

TypeDescription
constructorA function that takes*args,key,**kwargs and returns a ReactPy component. Note that*args and**kwargs are directly provided to your view.
Existing limitations

There are currently several limitations of usingview_to_iframe which may beresolved in a future version.

  • No built-in method of signalling events back to the parent component.
  • All providedargs andkwargs must be serializable values, since they are encoded into the URL.
  • Theiframe will always loadafter the parent component.
  • CSS styling foriframe elements tends to be awkward.
How do I use this for Class Based Views?

Class Based Views are accepted byview_to_iframe as an argument.

Callingas_view() is optional, but recommended.

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_iframehello_world_iframe=view_to_iframe(views.HelloWorld.as_view())@componentdefmy_component():returnhtml.div(hello_world_iframe(),)
1234567
fromdjango.httpimportHttpResponsefromdjango.viewsimportViewclassHelloWorld(View):defget(self,request):returnHttpResponse("Hello World!")
 1 2 3 4 5 6 7 8 91011
fromdjango.appsimportAppConfigfromexampleimportviewsfromreactpy_django.utilsimportregister_iframeclassExampleAppConfig(AppConfig):name="example"defready(self):register_iframe(views.HelloWorld)
How do I provideargs andkwargs to a converted view?

This component accepts*args and**kwargs arguments, which are sent to your provided view.

All provided*args and*kwargs must be serializable values, since they are encoded into the URL.

 1 2 3 4 5 6 7 8 91011121314151617181920
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_iframehello_world_iframe=view_to_iframe(views.hello_world,)@componentdefmy_component():returnhtml.div(hello_world_iframe("value_1","value_2",kwarg1="abc",kwarg2="123",),)
12345
fromdjango.httpimportHttpResponsedefhello_world(request):returnHttpResponse("Hello World!")
 1 2 3 4 5 6 7 8 91011
fromdjango.appsimportAppConfigfromexampleimportviewsfromreactpy_django.utilsimportregister_iframeclassExampleAppConfig(AppConfig):name="example"defready(self):register_iframe(views.hello_world)
How do I customize this component's behavior?

This component accepts arguments that can be used to customize its behavior.

Below are all the arguments that can be used.


This component accepts aextra_props parameter, which is a dictionary of additional properties to add to theiframe element.

For example, if you want to add atitle attribute to theiframe element, you can do so like such:

 1 2 3 4 5 6 7 8 910111213
fromreactpyimportcomponent,htmlfromexampleimportviewsfromreactpy_django.componentsimportview_to_iframehello_world_iframe=view_to_iframe(views.hello_world,extra_props={"title":"Hello World!"})@componentdefmy_component():returnhtml.div(hello_world_iframe(),)
12345
fromdjango.httpimportHttpResponsedefhello_world(request):returnHttpResponse("Hello World!")
 1 2 3 4 5 6 7 8 91011
fromdjango.appsimportAppConfigfromexampleimportviewsfromreactpy_django.utilsimportregister_iframeclassExampleAppConfig(AppConfig):name="example"defready(self):register_iframe(views.hello_world)

Django Form

Automatically convert a Django form into a ReactPy component.

Compatible with bothstandard Django forms andModelForms.

 1 2 3 4 5 6 7 8 910
fromreactpyimportcomponent,htmlfromexample.formsimportMyFormfromreactpy_django.componentsimportdjango_form@componentdefbasic_form():children=[html.input({"type":"submit"})]returndjango_form(MyForm,bottom_children=children)
12345
fromdjangoimportformsclassMyForm(forms.Form):username=forms.CharField(label="Username")
See Interface

NameTypeDescriptionDefault
formtype[Form|ModelForm]The form to convert.N/A
on_successAsyncFormEvent|SyncFormEvent|NoneA callback function that is called when the form is successfully submitted.None
on_errorAsyncFormEvent|SyncFormEvent|NoneA callback function that is called when the form submission fails.None
on_receive_dataAsyncFormEvent|SyncFormEvent|NoneA callback function that is called before newly submitted form data is rendered.None
on_changeAsyncFormEvent|SyncFormEvent|NoneA callback function that is called when a form field is modified by the user.None
auto_saveboolIfTrue, the form will automatically callsave on successful submission of aModelForm. This has no effect on regularForm instances.True
extra_propsdict[str,Any]|NoneAdditional properties to add to the<form> element.None
extra_transformsSequence[Callable[[VdomDict],Any]]|NoneA list of functions that transforms the newly generated VDOM. The functions will be repeatedly called on each VDOM node.None
form_templatestr|NoneThe template to use for the form. IfNone, Django's default template is used.None
thread_sensitiveboolWhether to run event callback functions in thread sensitive mode. This mode only applies to sync functions, and is turned on by default due to Django ORM limitations.True
top_childrenSequence[Any]Additional elements to add to the top of the form.tuple
bottom_childrenSequence[Any]Additional elements to add to the bottom of the form.tuple
keyKey|NoneA key to uniquely identify this component which is unique amongst a component's immediate siblings.None

TypeDescription
ComponentA ReactPy component.
Existing limitations

The following fields are currently incompatible withdjango_form:FileField,ImageField,SplitDateTimeField, andMultiValueField.

Compatibility for these fields will beadded in a future version.

How do I style these forms with Bootstrap?

You can style these forms by using a form styling library. In the example below, it is assumed that you have already installeddjango-bootstrap5.

After installing a form styling library, you can then provide ReactPy a customform_template parameter. This parameter allows you to specify a custom HTML template to use to render this the form.

Note that you can also set a global default forform_template by usingsettings.py:REACTPY_DEFAULT_FORM_TEMPLATE.

123456789
fromreactpyimportcomponentfromexample.formsimportMyFormfromreactpy_django.componentsimportdjango_form@componentdefbasic_form():returndjango_form(MyForm,form_template="bootstrap_form.html")
12345
fromdjangoimportformsclassMyForm(forms.Form):username=forms.CharField(label="Username")
 1 2 3 4 5 6 7 8 91011
{%loaddjango_bootstrap5%}<!-- Note: CSS/JS is loaded here only for demonstration purposes.You should load this CSS/JS in your HTML <head> instead. -->{%bootstrap_css%}{%bootstrap_javascript%}<!-- The actual form that is rendered by ReactPy -->{%bootstrap_formform%}{%bootstrap_buttonbutton_type="submit"content="OK"%}{%bootstrap_buttonbutton_type="reset"content="Reset"%}
How do I handle form success/errors?

You can react to form state by providing a callback function to any of the following parameters:on_success,on_error,on_receive_data, andon_change.

These functions will be called when the form is submitted.

In the example below, we will use theon_success parameter to change the URL upon successful submission.

 1 2 3 4 5 6 7 8 9101112131415161718192021
fromreactpyimportcomponent,hooks,htmlfromreactpy_routerimportnavigatefromexample.formsimportMyFormfromreactpy_django.componentsimportdjango_formfromreactpy_django.typesimportFormEventData@componentdefbasic_form():submitted,set_submitted=hooks.use_state(False)defon_submit(event:FormEventData):"""This function will be called when the form is successfully submitted."""set_submitted(True)ifsubmitted:returnnavigate("/homepage")children=[html.input({"type":"submit"})]returndjango_form(MyForm,on_success=on_submit,bottom_children=children)
12345
fromdjangoimportformsclassMyForm(forms.Form):username=forms.CharField(label="Username")

Django CSS

Allows you to defer loading a CSS stylesheet until a component begins rendering. This stylesheet must be stored withinDjango's static files.

 1 2 3 4 5 6 7 8 91011
fromreactpyimportcomponent,htmlfromreactpy_django.componentsimportdjango_css@componentdefmy_component():returnhtml.div(django_css("css/buttons.css"),html.button("My Button!"),)
See Interface

NameTypeDescriptionDefault
static_pathstrThe path to the static file. This path is identical to what you would use on Django's{%static%} template tag.N/A
keyKey|NoneA key to uniquely identify this component which is unique amongst a component's immediate siblingsNone

TypeDescription
ComponentA ReactPy component.
Can I load static CSS usinghtml.link instead?

While you can load stylesheets withhtml.link, keep in mind that loading this waydoes not ensure load order. Thus, your stylesheet will be loaded after your component is displayed. This would likely cause unintended visual behavior, so use this at your own discretion.

Here's an example on what you should avoid doing for Django static files:

 1 2 3 4 5 6 7 8 910
fromdjango.templatetags.staticimportstaticfromreactpyimportcomponent,html@componentdefmy_component():returnhtml.div(html.link({"rel":"stylesheet","href":static("css/buttons.css")}),html.button("My Button!"),)
How do I load external CSS?

django_css can only be used with local static files.

For external CSS, you should usehtml.link.

123456789
fromreactpyimportcomponent,html@componentdefmy_component():returnhtml.div(html.link({"rel":"stylesheet","href":"https://example.com/external-styles.css"}),html.button("My Button!"),)
Why not load my CSS in<head>?

Traditionally, stylesheets are loaded in your<head> using Django's{%static%} template tag.

However, to help improve webpage load times you can use thisdjango_css component to defer loading your stylesheet until it is needed.


Django JS

Allows you to defer loading JavaScript until a component begins rendering. This JavaScript must be stored withinDjango's static files.

 1 2 3 4 5 6 7 8 91011
fromreactpyimportcomponent,htmlfromreactpy_django.componentsimportdjango_js@componentdefmy_component():returnhtml.div(html.button("My Button!"),django_js("js/scripts.js"),)
See Interface

NameTypeDescriptionDefault
static_pathstrThe path to the static file. This path is identical to what you would use on Django's{%static%} template tag.N/A
keyKey|NoneA key to uniquely identify this component which is unique amongst a component's immediate siblingsNone

TypeDescription
ComponentA ReactPy component.
Can I load static JavaScript usinghtml.script instead?

While you can load JavaScript withhtml.script, keep in mind that loading this waydoes not ensure load order. Thus, your JavaScript will likely be loaded at an arbitrary time after your component is displayed.

Here's an example on what you should avoid doing for Django static files:

 1 2 3 4 5 6 7 8 910
fromdjango.templatetags.staticimportstaticfromreactpyimportcomponent,html@componentdefmy_component():returnhtml.div(html.script({"src":static("js/scripts.js")}),html.button("My Button!"),)
How do I load external JS?

django_js can only be used with local static files.

For external JavaScript, you should usehtml.script.

123456789
fromreactpyimportcomponent,html@componentdefmy_component():returnhtml.div(html.script({"src":"https://example.com/external-scripts.js"}),html.button("My Button!"),)
Why not load my JS in<head>?

Traditionally, JavaScript is loaded in your<head> using Django's{%static%} template tag.

However, to help improve webpage load times you can use thisdjango_js component to defer loading your JavaScript until it is needed.


Last update:December 11, 2024
Authors:Mark Bakhit

[8]ページ先頭

©2009-2025 Movatter.jp