Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Create simple reusable template components in Django.

License

NotificationsYou must be signed in to change notification settings

django-components/django-components

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

django-components

PyPI - VersionPyPI - Python VersionPyPI - LicensePyPI - DownloadsGitHub Actions Workflow StatusasvDiscord

django-components is a modular and extensible UI framework for Django.

It combines Django's templating system with the modularity seenin modern frontend frameworks like Vue or React.

Withdjango-components you can support Django projects small and large without leaving the Django ecosystem.

Sponsors

Quickstart

A component in django-components can be as simple as a Django template and Python code to declare the component:

{# components/calendar/calendar.html #}<divclass="calendar">  Today's date is <span>{{ date }}</span></div>
# components/calendar/calendar.pyfromdjango_componentsimportComponent,register@register("calendar")classCalendar(Component):template_file="calendar.html"

Or a combination of Django template, Python, CSS, and #"auto" data-snippet-clipboard-copy-content="{# components/calendar/calendar.html #}<div class="calendar"> Today's date is <span>{{ date }}</span></div>">

{# components/calendar/calendar.html #}<divclass="calendar">  Today's date is <span>{{ date }}</span></div>
/* components/calendar/calendar.css */.calendar {width:200px;background: pink;}
/* components/calendar/calendar.js */document.querySelector(".calendar").onclick=()=>{alert("Clicked calendar!");};
# components/calendar/calendar.pyfromdjango_componentsimportComponent,register@register("calendar")classCalendar(Component):template_file="calendar.html"js_file="calendar.js"css_file="calendar.css"defget_template_data(self,args,kwargs,slots,context):return {"date":kwargs["date"]}

Use the component like this:

{%component"calendar"date="2024-11-06"%}{%endcomponent%}

And this is what gets rendered:

<divclass="calendar-component">  Today's date is<span>2024-11-06</span></div>

Read on to learn about all the exciting details and configuration possibilities!

(If you instead prefer to jump right into the code,check out the example project)

Features

Modern and modular UI

  • Create self-contained, reusable UI elements.
  • Each component can include its own HTML, CSS, and JS, or additional third-party JS and CSS.
  • HTML, CSS, and JS can be defined on the component class, or loaded from files.
fromdjango_componentsimportComponent@register("calendar")classCalendar(Component):template="""        <div>            Today's date is            <span>{{ date }}</span>        </div>    """css="""        .calendar {            width: 200px;            background: pink;        }    """js="""        document.querySelector(".calendar")            .addEventListener("click", () => {                alert("Clicked calendar!");            });    """# Additional JS and CSSclassMedia:js= ["https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js"]css= ["bootstrap/dist/css/bootstrap.min.css"]# Variables available in the templatedefget_template_data(self,args,kwargs,slots,context):return {"date":kwargs["date"]        }

Composition with slots

{%component"Layout"bookmarks=bookmarksbreadcrumbs=breadcrumbs%}{%fill"header"%}        <divclass="flex justify-between gap-x-12">            <divclass="prose">                <h3>{{ project.name }}</h3>            </div>            <divclass="font-semibold text-gray-500">                {{ project.start_date }} - {{ project.end_date }}            </div>        </div>{%endfill%}{# Access data passed to `{% slot %}` with `data` #}{%fill"tabs"data="tabs_data"%}{%component"TabItem"header="Project Info"%}{%component"ProjectInfo"project=projectproject_tags=project_tagsattrs:class="py-5"attrs:width=tabs_data.width            /%}{%endcomponent%}{%endfill%}{%endcomponent%}

Extended template tags

django-components is designed for flexibility, making working with templates a breeze.

It extends Django's template tags syntax with:

{%component"table"    ...default_attrstitle="Friend list for {{ user.name }}"headers=["Name","Age","Email"]data=[        {"name":"John"|upper,"age": 30|add:1,"email":"john@example.com","hobbies": ["reading"],        },        {"name":"Jane"|upper,"age": 25|add:1,"email":"jane@example.com","hobbies": ["reading","coding"],        },    ],attrs:class="py-4 ma-2 border-2 border-gray-300 rounded-md"/%}

You too can define template tags with these features by using@template_tag()orBaseNode.

Read more onCustom template tags.

Full programmatic access

When you render a component, you can access everything about the component:

classTable(Component):js_file="table.js"css_file="table.css"template="""        <div>            <span>{{ variable }}</span>        </div>    """defget_template_data(self,args,kwargs,slots,context):# Access component's IDassertself.id=="djc1A2b3c"# Access component's inputs and slotsassertself.args== [123,"str"]assertself.kwargs== {"variable":"test","another":1}footer_slot=self.slots["footer"]some_var=self.context["some_var"]# Access the request object and Django's context processors, if availableassertself.request.GET== {"query":"something"}assertself.context_processors_data['user'].username=="admin"return {"variable":kwargs["variable"],        }# Access component's HTML / JS / CSSTable.templateTable.jsTable.css# Render the componentrendered=Table.render(kwargs={"variable":"test","another":1},args=(123,"str"),slots={"footer":"MY_FOOTER"},)

Granular HTML attributes

Use the{% html_attrs %} template tag to render HTML attributes.

It supports:

  • Defining attributes as whole dictionaries or keyword arguments
  • Merging attributes from multiple sources
  • Boolean attributes
  • Appending attributes
  • Removing attributes
  • Defining default attributes
<div{%html_attrsattrsdefaults:class="default-class"class="extra-class"%}>

{% html_attrs %} offers a Vue-like granular control forclassandstyleHTML attributes,where you can use a dictionary to manage each class name or style property separately.

{%html_attrsclass="foo bar"class={"baz":True,"foo":False,    }class="extra"%}
{%html_attrsstyle="text-align: center; background-color: blue;"style={"background-color":"green","color":None,"width":False,    }style="position: absolute; height: 12px;"%}

Read more aboutHTML attributes.

HTML fragment support

django-components makes integration with HTMX, AlpineJS or jQuery easy by allowing components to be rendered asHTML fragments:

  • Components's JS and CSS files are loaded automatically when the fragment is inserted into the DOM.

  • Components can beexposed as Django Views withget(),post(),put(),patch(),delete() methods

  • Automatically create an endpoint for a component withComponent.View.public

# components/calendar/calendar.py@register("calendar")classCalendar(Component):template_file="calendar.html"classView:# Define handlersdefget(self,request,*args,**kwargs):page=request.GET.get("page",1)returnCalendar.render_to_response(request=request,kwargs={"page":page,                },            )defget_template_data(self,args,kwargs,slots,context):return {"page":kwargs["page"],        }# Get auto-generated URL for the componenturl=get_component_url(Calendar)# Or define explicit URL in urls.pypath("calendar/",Calendar.as_view())

Provide / Inject

django-components supports the provide / inject pattern, similarly to React'sContext Providers or Vue'sprovide / inject:

Read more aboutProvide / Inject.

<body>{%provide"theme"variant="light"%}{%component"header" /%}{%endprovide%}</body>
@register("header")class Header(Component):    template = "..."    def get_template_data(self, args, kwargs, slots, context):        theme = self.inject("theme").variant        return {            "theme": theme,        }

Input validation and static type hints

Avoid needless errors withtype hints and runtime input validation.

To opt-in to input validation, define types for component's args, kwargs, slots, and more:

fromtypingimportOptionalfromdjango.templateimportContextfromdjango_componentsimportComponent,Slot,SlotInputclassButton(Component):classArgs:size:inttext:strclassKwargs:variable:stranother:intmaybe_var:Optional[int]=None# May be omittedclassSlots:my_slot:Optional[SlotInput]=Noneanother_slot:SlotInputdefget_template_data(self,args:Args,kwargs:Kwargs,slots:Slots,context:Context):args.size# intkwargs.variable# strslots.my_slot# Slot[MySlotData]

To have type hints when callingButton.render() orButton.render_to_response(),wrap the inputs in their respectiveArgs,Kwargs, andSlots classes:

Button.render(# Error: First arg must be `int`, got `float`args=Button.Args(size=1.25,text="abc",    ),# Error: Key "another" is missingkwargs=Button.Kwargs(variable="text",    ),)

Extensions

Django-components functionality can be extended withExtensions.Extensions allow for powerful customization and integrations. They can:

  • Tap into lifecycle events, such as when a component is created, deleted, or registered
  • Add new attributes and methods to the components
  • Add custom CLI commands
  • Add custom URLs

Some of the extensions include:

Some of the planned extensions include:

  • AlpineJS integration
  • Storybook integration
  • Component-level benchmarking with asv

Caching

  • Components can be cached using Django's cache framework.
  • Caching rules can be configured on a per-component basis.
  • Components are cached based on their input. Or you can write custom caching logic.
fromdjango_componentsimportComponentclassMyComponent(Component):classCache:enabled=Truettl=60*60*24# 1 daydefhash(self,*args,**kwargs):returnhash(f"{json.dumps(args)}:{json.dumps(kwargs)}")

Simple testing

  • Write tests for components with@djc_test decorator.
  • The decorator manages global state, ensuring that tests don't leak.
  • If usingpytest, the decorator allows you to parametrize Django or Components settings.
  • The decorator also serves as a stand-in for Django's@override_settings.
fromdjango_components.testingimportdjc_testfromcomponents.my_tableimportMyTable@djc_testdeftest_my_table():rendered=MyTable.render(kwargs={"title":"My table",        },    )assertrendered=="<table>My table</table>"

Debugging features

  • Visual component inspection: Highlight components and slots directly in your browser.
  • Detailed tracing logs to supply AI-agents with context: The logs include component and slot names and IDs, and their position in the tree.
Component debugging visualization showing slot highlighting

Sharing components

  • Install and use third-party components from PyPI

  • Or publish your own "component registry"

  • Highly customizable - Choose how the components are called in the template (and more):

    {%component"calendar"date="2024-11-06"%}{%endcomponent%}{%calendardate="2024-11-06"%}{%endcalendar%}

Documentation

Read the full documentation here.

... or jump right into the code,check out the example project.

Performance

Our aim is to be at least as fast as Django templates.

As of0.130,django-components is ~4x slower than Django templates.

Render time
django68.9±0.6ms
django-components259±4ms

See thefull performance breakdown for more information.

Release notes

Read theRelease Notesto see the latest features and fixes.

Community examples

One of our goals withdjango-components is to make it easy to share components between projects. If you have a set of components that you think would be useful to others, please open a pull request to add them to the list below.

Contributing and development

Get involved or sponsor this project -See here

Running django-components locally for development -See here


[8]ページ先頭

©2009-2025 Movatter.jp