diff --git a/demo/demo/settings.py b/demo/demo/settings.py
index a07f8561..7e2dd37e 100644
--- a/demo/demo/settings.py
+++ b/demo/demo/settings.py
@@ -38,6 +38,10 @@
"django.contrib.staticfiles",
"core",
"products",
+ "crispy_forms",
+ "crispy_tailwind",
+ "template_partials",
+ "django_htmx",
]
MIDDLEWARE = [
@@ -48,6 +52,7 @@
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
+ "django_htmx.middleware.HtmxMiddleware",
]
ROOT_URLCONF = "demo.urls"
@@ -124,5 +129,8 @@
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+CRISPY_ALLOWED_TEMPLATE_PACKS = "tailwind"
+CRISPY_TEMPLATE_PACK = "tailwind"
+
SUPERUSER_EMAIL = "project@gmail.com"
SUPERUSER_PASSWORD = "password"
diff --git a/demo/demo/urls.py b/demo/demo/urls.py
index d5b2cd9a..e7447b12 100644
--- a/demo/demo/urls.py
+++ b/demo/demo/urls.py
@@ -1,19 +1,3 @@
-"""
-URL configuration for demo project.
-
-The `urlpatterns` list routes URLs to views. For more information please see:
- https://docs.djangoproject.com/en/4.2/topics/http/urls/
-Examples:
-Function views
- 1. Add an import: from my_app import views
- 2. Add a URL to urlpatterns: path('', views.home, name='home')
-Class-based views
- 1. Add an import: from other_app.views import Home
- 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
-Including another URLconf
- 1. Import the include() function: from django.urls import include, path
- 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
-"""
from django.contrib import admin
from django.urls import include
from django.urls import path
@@ -23,5 +7,5 @@
urlpatterns = [
path("admin/", admin.site.urls),
path("", RedirectView.as_view(url=reverse_lazy("products:product_list"))),
- path("products/", include("products.urls")),
+ path("products/", include("products.urls", namespace="products")),
]
diff --git a/demo/products/forms.py b/demo/products/forms.py
index 57193198..0266ce3d 100644
--- a/demo/products/forms.py
+++ b/demo/products/forms.py
@@ -6,4 +6,4 @@
class ProductForm(ModelForm):
class Meta:
model = Product
- fields = ("id", "name", "description", "price", "slug", "sku")
+ fields = ("id", "name", "description", "price", "sku")
diff --git a/demo/products/migrations/0002_category.py b/demo/products/migrations/0002_category.py
new file mode 100644
index 00000000..d669f56a
--- /dev/null
+++ b/demo/products/migrations/0002_category.py
@@ -0,0 +1,28 @@
+# Generated by Django 5.0 on 2023-12-21 14:36
+from django.db import migrations
+from django.db import models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("products", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name="Category",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("name", models.CharField(max_length=100)),
+ ("slug", models.SlugField(max_length=100, unique=True)),
+ ],
+ ),
+ ]
diff --git a/demo/products/migrations/0003_remove_product_slug_alter_product_name.py b/demo/products/migrations/0003_remove_product_slug_alter_product_name.py
new file mode 100644
index 00000000..51d949af
--- /dev/null
+++ b/demo/products/migrations/0003_remove_product_slug_alter_product_name.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.2.8 on 2023-12-21 19:46
+from django.db import migrations
+from django.db import models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("products", "0002_category"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="product",
+ name="slug",
+ ),
+ migrations.AlterField(
+ model_name="product",
+ name="name",
+ field=models.CharField(max_length=100, unique=True),
+ ),
+ ]
diff --git a/demo/products/models.py b/demo/products/models.py
index 3962ddc0..f0cb827f 100644
--- a/demo/products/models.py
+++ b/demo/products/models.py
@@ -2,13 +2,15 @@
class Product(models.Model):
- name = models.CharField(max_length=100)
+ name = models.CharField(max_length=100, unique=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
- # image = models.ImageField(upload_to="products/", null=True, blank=True)
- slug = models.SlugField(max_length=100, unique=True)
sku = models.CharField(max_length=100, unique=True)
+ @property
+ def slug(self):
+ return self.name.lower().replace(" ", "-")
+
class Category(models.Model):
name = models.CharField(max_length=100)
diff --git a/demo/products/urls.py b/demo/products/urls.py
index baa4a089..685e4bb3 100644
--- a/demo/products/urls.py
+++ b/demo/products/urls.py
@@ -2,6 +2,7 @@
from . import views
+
app_name = "products"
urlpatterns = [
diff --git a/demo/products/views.py b/demo/products/views.py
index 38cd351b..b7905b6a 100644
--- a/demo/products/views.py
+++ b/demo/products/views.py
@@ -12,10 +12,11 @@
def product_list(request: HttpRequest):
products = Product.objects.all()
+ template_name = "products/product_list.html#table" if request.htmx else "products/product_list.html"
return TemplateResponse(
request,
- "products/product_list.html",
- context={"products": paginate_queryset(request, products)},
+ template_name,
+ context={"products": paginate_queryset(request, products, 2)},
)
diff --git a/demo/requirements.txt b/demo/requirements.txt
new file mode 100644
index 00000000..3d6a3418
--- /dev/null
+++ b/demo/requirements.txt
@@ -0,0 +1,5 @@
+django
+django-crispy-forms
+crispy-tailwind
+django-template-partials
+django-htmx
diff --git a/demo/templates/base.html b/demo/templates/base.html
index 5ac56dbc..65da9861 100644
--- a/demo/templates/base.html
+++ b/demo/templates/base.html
@@ -1,15 +1,18 @@
-
-
-
- My Website
-
-
-
-
- {% block content %}
- {% endblock %}
-
-
+
+
+
+ My Website
+
+
+
+
+
+
+ {% block content %}
+ {% endblock content %}
+
+
+
diff --git a/demo/templates/products/product_create.html b/demo/templates/products/product_create.html
index e69de29b..6da2e6ea 100644
--- a/demo/templates/products/product_create.html
+++ b/demo/templates/products/product_create.html
@@ -0,0 +1,15 @@
+{% extends "base.html" %}
+{% load crispy_forms_tags %}
+
+{% block content %}
+ Create Product
+
+
+{% endblock content %}
diff --git a/demo/templates/products/product_detail.html b/demo/templates/products/product_detail.html
index e69de29b..1db1238d 100644
--- a/demo/templates/products/product_detail.html
+++ b/demo/templates/products/product_detail.html
@@ -0,0 +1,38 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+
+
+
+
+ -
+ Name: {{ product.name }}
+
+ -
+ Description: {{ product.description }}
+
+ -
+ Price: {{ product.price }}
+
+ -
+ Slug: {{ product.slug }}
+
+ -
+ Sku: {{ product.sku }}
+
+
+
+
+ Edit
+
+
+
+{% endblock content %}
diff --git a/demo/templates/products/product_list.html b/demo/templates/products/product_list.html
index 021dd3ea..5c153166 100644
--- a/demo/templates/products/product_list.html
+++ b/demo/templates/products/product_list.html
@@ -1,30 +1,122 @@
{% extends 'base.html' %}
+{% load partials %}
+
{% block content %}
-
-
-
- Product Name |
- Price |
-
-
-
- {% for product in products %}
-
- {{ product.name }} |
- {{ product.price }} |
-
- {% endfor %}
-
-
-
-