Action
An action is a server function which is called from the client using the call function.
The call function makes a POST request with a payload to the server. The action function takes the HttpRequest object as an argument and can peform any operation, then should return a Targets list. Picomet uses that Targets list to partially render the specific target elements on the server. Then the partialls are sent as the response to be updated on the client.
Call
Provided by picomet/comet.js
call(
action: string,
payload: {[key: string]: string | number | boolean | Blob} | FormData,
keys?: [string, number][][]
): Promise<void>
Parameter |
Description |
|---|---|
action: string |
Action location |
payload: {
[key: string]: string | number | boolean | Blob
} | FormData
|
Payload sent to the action as post body
|
keys?: [string, number][][] |
Optional loop keys array for loop item partial rendering |
Usage
First of all, lets create a Blog and a Like model:
# apps/core/models.py
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=150)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Like(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.blog.title
Migrate the models:
python manage.py makemigrations
python manage.py migrate
Now enter into the django shell and create a blog:
python manage.py shell
from core.models import Blog
Blog.objects.create(title="First blog", content="This is the content")
Define a like action:
# apps/core/actions.py
from core.models import Blog, Like
def like_blog(request):
blog = Blog.objects.get(id=request.POST["blog"])
Like.objects.create(blog=blog)
return ["&likes"]
Create a Template and call the action from the client:
<!-- apps/core/comets/Blogs.html -->
<div s-for="blog" s-in="blogs" s-of="blogs.filter(id=key)" s-key="blog.id">
<div s-keys>
<h2>{$ blog.title $}</h2>
<p>{$ blog.content $}</p>
<span s-group="likes">likes ({$ blog.like_set.count() $})</span>
<button
x-on:click="call('core.like_blog', {blog: $X(`blog.id`)}, keys)"
s-csrf
>
like
</button>
</div>
</div>
Create the view:
# apps/core/views.py
from picomet.decorators import template
from picomet.views import render
from core.models import Blog
@template("Blogs")
def blogs(request):
context = {"blogs": Blog.objects.all()}
return render(request, context)
Configure url:
# apps/core/urls.py
from django.urls import path
from core import views
app_name = "core"
urlpatterns = [
path("blogs", views.blogs, name="blogs"),
]
Redirect
class picomet.shortcuts.ActionRedirect
Parameter |
Description |
|---|---|
redirect_to: str |
Path to redirect |
update: bool = True |
Whether to update the page after redirection |
Return a redirection from an action
# apps/core/actions.py
from picomet.shortcuts import ActionRedirect
def my_action(request):
if not request.POST.get("var"):
raise ActionRedirect("/")