স্টেপ ১: ভার্চুয়াল এনভায়রনমেন্ট তৈরি ও অ্যাক্টিভেট করুন (ঐচ্ছিক)
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windowsস্টেপ ২: Django ও প্রয়োজনীয় লাইব্রেরি ইন্সটল করুন
pip install django django-htmxস্টেপ ৩: প্রজেক্ট ও অ্যাপ তৈরি করুন
django-admin startproject htmx_dashboard
cd htmx_dashboard
python manage.py startapp productsস্টেপ ৪: টেইলউইন্ড সেটআপ করুন
বিকল্প ১: CDN ব্যবহার করুন (সরল উপায়)base.html-এ সরাসরি টেইলউইন্ড CDN যোগ করুন
স্টেপ ৫: settings.py কনফিগারেশন
# htmx_dashboard/settings.py
INSTALLED_APPS = [
...
'products',
'django_htmx', # নতুন অ্যাপ যোগ করুন
]
MIDDLEWARE = [
...
'django_htmx.middleware.HtmxMiddleware', # HTMX মিডলওয়্যার
]
TEMPLATES = [
{
...
'DIRS': [BASE_DIR / 'templates'], # টেমপ্লেট ডিরেক্টরি যোগ করুন
}
]প্রজেক্ট স্ট্রাকচার
htmx_dashboard/
├── htmx_dashboard/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── products/
│ ├── migrations/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
├── templates/
│ ├── base.html
│ └── products/
│ ├── product_form.html
│ ├── _product_form.html
│ ├── product_list.html
│ └── _product_list.html
├── venv/
├── manage.py
└── requirements.txt৩. urls.py (প্রজেক্ট লেভেল)
# htmx_dashboard/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('products/', include('products.urls')),
]স্টেপ ৯: মডেল ও ফর্ম তৈরি করুন
# products/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
description = models.TextField()
def __str__(self):
return self.name# products/forms.py
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ['name', 'price', 'description']
widgets = {
'description': forms.Textarea(attrs={'rows': 3}),
}৬. products/views.py
from django.views.generic import CreateView, ListView
from django.urls import reverse_lazy
from django.http import HttpResponseBadRequest
from django.shortcuts import render
from .models import Product
from .forms import ProductForm
class ProductCreateView(CreateView):
form_class = ProductForm
template_name = "products/product_form.html"
success_url = reverse_lazy("product_list")
def get_template_names(self):
if self.request.htmx:
return ["products/_product_form.html"]
return super().get_template_names()
def form_valid(self, form):
response = super().form_valid(form)
if self.request.htmx:
return render(self.request, "products/_product_list.html", {"products": Product.objects.all()})
return response
def form_invalid(self, form):
if self.request.htmx:
return HttpResponseBadRequest("Invalid form data")
return super().form_invalid(form)
class ProductListView(ListView):
model = Product
context_object_name = "products"
template_name = "products/product_list.html"
def get_template_names(self):
if self.request.htmx:
return ["products/_product_list.html"]
return super().get_template_names()products/urls.py
from django.urls import path
from .views import ProductCreateView, ProductListView
urlpatterns = [
path("create/", ProductCreateView.as_view(), name="product_create"),
path("list/", ProductListView.as_view(), name="product_list"),
]templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTMX Dashboard</title>
<script src="https://unpkg.com/htmx.org@1.9.6"></script>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100">
<div class="min-h-screen flex">
<!-- Sidebar -->
<aside class="w-64 bg-white shadow-lg fixed h-full">
<div class="p-4">
<h2 class="text-xl font-bold mb-4">Dashboard</h2>
<nav>
<ul class="space-y-2">
<li>
<a hx-get="{% url 'product_create' %}"
hx-target="#main-content"
hx-push-url="/products/create/"
class="block px-4 py-2 text-gray-700 hover:bg-gray-100 rounded">
Create Product
</a>
</li>
<li>
<a hx-get="{% url 'product_list' %}"
hx-target="#main-content"
hx-push-url="/products/list/"
class="block px-4 py-2 text-gray-700 hover:bg-gray-100 rounded">
Product List
</a>
</li>
</ul>
</nav>
</div>
</aside>
<!-- Main Content -->
<main class="flex-1 ml-64 p-8">
<!-- Topbar -->
<div class="bg-white shadow-sm rounded-lg p-4 mb-6">
<div class="flex justify-between items-center">
<h1 class="text-2xl font-bold">{% block title %}{% endblock %}</h1>
</div>
</div>
<!-- Dynamic Content -->
<div id="main-content" class="bg-white rounded-lg shadow p-6">
{% block content %}{% endblock %}
</div>
</main>
</div>
</body>
</html>templates/products/product_form.html
{% extends "base.html" %}
{% block title %}Create Product{% endblock %}
{% block content %}
{% include "products/_product_form.html" %}
{% endblock %}templates/products/_product_form.html
<div class="max-w-2xl mx-auto">
<h2 class="text-2xl font-bold mb-4">Create Product</h2>
<form method="POST" hx-post="{% url 'product_create' %}" hx-target="#main-content">
{% csrf_token %}
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700">Name</label>
{{ form.name }}
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Price</label>
{{ form.price }}
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Description</label>
{{ form.description }}
</div>
</div>
<button type="submit" class="mt-4 bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
Submit
</button>
</form>
</div>১১. templates/products/product_list.html
{% extends "base.html" %}
{% block title %}Product List{% endblock %}
{% block content %}
{% include "products/_product_list.html" %}
{% endblock %}templates/products/_product_list.html
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Name</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Price</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Description</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{% for product in products %}
<tr>
<td class="px-6 py-4 whitespace-nowrap">{{ product.name }}</td>
<td class="px-6 py-4 whitespace-nowrap">${{ product.price }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ product.description|truncatechars:50 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>মাইগ্রেশন ও রান সার্ভার
# ডাটাবেস মাইগ্রেট
python manage.py makemigrations
python manage.py migrate
# অ্যাডমিন ইউজার তৈরি (ঐচ্ছিক)
python manage.py createsuperuser
# সার্ভার রান
python manage.py runserverটেস্ট করার স্টেপ
http://localhost:8000/products/create/এ গিয়ে ফর্ম পূরণ করুন- সাবমিট করলে প্রোডাক্ট লিস্টে নতুন আইটেম যোগ হবে (HTMX এর মাধ্যমে)
- ব্রাউজার রিলোড করলে সম্পূর্ণ পেজ রেন্ডার হবে
- সাইডবারের লিংকগুলোতে ক্লিক করে HTMX ট্রানজিশন দেখুন
Key Features
- HTMX ইন্টিগ্রেশন:
- পার্শিয়াল টেমপ্লেট লোডিং
- URL সিনক্রোনাইজেশন (
hx-push-url) - AJAX ফর্ম সাবমিশন
- টেইলউইন্ড ডিজাইন:
- রেসপনসিভ ড্যাশবোর্ড
- মডার্ন UI কম্পোনেন্ট
- ক্লাস-বেজড ভিউ:
CreateViewএবংListViewএর এক্সটেন্ডেড ব্যবহার- ডাইনামিক টেমপ্লেট সিলেকশন