How to create a Django form in 2mins using Alpine.js 🏔️

July 27, 2023

There will be 4 steps. Each takes under 30 seconds.

We'll assume that you've already setup your Django project and created an app (I'll be using one I named sim ). You don't need to know anything about

Alpine.js

. I'll walk you through.

My video follows the guide below. Let's get to it!

1. Create template

  • create a folder called templates in your sim app
  • add an html file, we'll call it example.html
  • add your form html to the template
<div>
<form>
<div>
<input name="email" type="email" />
<input name="codename" type="text" />
<input name="dress_color" type="color" />
<button>Submit</button>
</div>
<div>
<p>Successfully submitted form ✅</p>
</div>
<div>
<p>Error submitting your form ❌</p>
</div>
</form>
</div>

2. Add your Django view

  • Add your view, update your urls, and check that a template is rendered at the right url.
# views.py
from django.shortcuts import render
def example(request):
return render(request, 'templates/example.html', context={})
def sample_post(request):
data = request.POST
print(f'{data = }')
return JsonResponse({'status': 'success'})
# urls.py
from . import views
from django.urls import path
urlpatterns = [
path('example', views.example, name='example'),
path('sample-post/', views.sample_post, name='sample_post')
]

3. Add alpine js to template

  • Add Alpine js submit function
  • include the Django CSRF token
  • add your specific view url path
  • Add Alpine js syntax to control the form and manage the form's state
  • Add Alpine js loader script using a CDN (very fast and light)
<div>
<form @submit.prevent="submit" x-data="{ status: 'normal', errors: {} }">
<div x-show="status === 'normal'">
<input name="email" type="email" />
<input name="codename" type="text" />
<input name="dress_color" type="color" />
<button>Submit</button>
</div>
<div x-show="status === 'success'">
<p>Successfully submitted form ✅</p>
</div>
<div x-show="status === 'error'">
<p>Error submitting your form ❌</p>
</div>
</form>
</div>
<script>
function submit(event) {
event.preventDefault()
const formData = new FormData(event.target)
// Update the `endpointUrl` to your specific url below.
const endpointUrl = '/sample-post/'
fetch(endpointUrl, {
method: 'post',
body: formData,
headers: {
'X-CSRFToken': '{{ csrf_token }}',
},
})
.then((response) => {
this.status = response.ok ? 'success' : 'error'
return response.json()
})
.then((data) => {
this.errors = data.errors || {}
})
}
</script>
<script
defer=""
src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js"
></script>

4. Check that the view works as expected

  • Submit something.
  • Check in the Django run console that you see something like: data = {"email": ..., "codename": ..., "dress_color":...}

Bonus: Prevent form flickering due to alpine loading

  • Add x-cloak to the form. This will hide the form until it's finished loading (avoiding flicker).
  • Add x-cloak into the style tag (or add a similar line to any stylesheet that you are using)
<div>
<form
x-cloak
@submit.prevent="submit"
x-data="{ status: 'normal', errors: {} }"
>
<div x-show="status === 'normal'">
<input name="email" type="email" />
<input name="codename" type="text" />
<input name="dress_color" type="color" />
<button>Submit</button>
</div>
<div x-show="status === 'success'">
<p>Successfully submitted form ✅</p>
</div>
<div x-show="status === 'error'">
<p>Error submitting your form ❌</p>
</div>
</form>
</div>
<script>
function submit(event) {
event.preventDefault()
const formData = new FormData(event.target)
// Update the `endpointUrl` to your specific url below.
const endpointUrl = '/sample-post/'
fetch(endpointUrl, {
method: 'post',
body: formData,
headers: {
'X-CSRFToken': '{{ csrf_token }}',
},
})
.then((response) => {
this.status = response.ok ? 'success' : 'error'
return response.json()
})
.then((data) => {
this.errors = data.errors || {}
})
}
</script>
<script
defer=""
src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js"
></script>
<style>
[x-cloak] {
display: none !important;
}
</style>

Congratulations! Using Alpine.js is a neat, clean way to add simple JavaScript, including managing state, to your Django templates.

P.S Want to ship better features with AI?
Join my free weekly newsletter

No spam guaranteed Unsubscribe whenever