Просмотр исходного кода

Add Wagtail 7.2 ordering support for countries and ingredients

- Add sort_order field to Country model with db_index
- Add Orderable mixin to BreadIngredient model
- Update model Meta ordering to prioritize sort_order
- Add sort_order_field to CountryModelViewSet and BreadIngredientSnippetViewSet
- Enable drag-and-drop reordering in Wagtail admin (7.2+)
- Maintain backward compatibility with Wagtail 7.1
Mohit-Lakra 3 месяцев назад
Родитель
Сommit
dad793f5ac

+ 60 - 30
bakerydemo/base/fixtures/bakerydemo.json

@@ -281,175 +281,200 @@
     "model": "breads.country",
     "pk": 1,
     "fields": {
-      "title": "Egypt"
+      "title": "Egypt",
+      "sort_order": 4
     }
   },
   {
     "model": "breads.country",
     "pk": 2,
     "fields": {
-      "title": "Slovenia"
+      "title": "Slovenia",
+      "sort_order": 19
     }
   },
   {
     "model": "breads.country",
     "pk": 3,
     "fields": {
-      "title": "United States (New England)"
+      "title": "United States (New England)",
+      "sort_order": 25
     }
   },
   {
     "model": "breads.country",
     "pk": 4,
     "fields": {
-      "title": "Japan"
+      "title": "Japan",
+      "sort_order": 12
     }
   },
   {
     "model": "breads.country",
     "pk": 5,
     "fields": {
-      "title": "India (Kerala)\nSri Lanka"
+      "title": "India (Kerala)\nSri Lanka",
+      "sort_order": 7
     }
   },
   {
     "model": "breads.country",
     "pk": 6,
     "fields": {
-      "title": "South America (Northern)"
+      "title": "South America (Northern)",
+      "sort_order": 20
     }
   },
   {
     "model": "breads.country",
     "pk": 7,
     "fields": {
-      "title": "China (Northwestern Yunnan, Naxi people)"
+      "title": "China (Northwestern Yunnan, Naxi people)",
+      "sort_order": 3
     }
   },
   {
     "model": "breads.country",
     "pk": 8,
     "fields": {
-      "title": "Polish/Ashkenazi Jewish"
+      "title": "Polish/Ashkenazi Jewish",
+      "sort_order": 16
     }
   },
   {
     "model": "breads.country",
     "pk": 9,
     "fields": {
-      "title": "France"
+      "title": "France",
+      "sort_order": 5
     }
   },
   {
     "model": "breads.country",
     "pk": 10,
     "fields": {
-      "title": "Tibet (Central)"
+      "title": "Tibet (Central)",
+      "sort_order": 21
     }
   },
   {
     "model": "breads.country",
     "pk": 11,
     "fields": {
-      "title": "Jamaica"
+      "title": "Jamaica",
+      "sort_order": 11
     }
   },
   {
     "model": "breads.country",
     "pk": 12,
     "fields": {
-      "title": "Scandinavia"
+      "title": "Scandinavia",
+      "sort_order": 18
     }
   },
   {
     "model": "breads.country",
     "pk": 13,
     "fields": {
-      "title": "United Kingdom (Scotland)"
+      "title": "United Kingdom (Scotland)",
+      "sort_order": 23
     }
   },
   {
     "model": "breads.country",
     "pk": 14,
     "fields": {
-      "title": "United Kingdom (Wales)"
+      "title": "United Kingdom (Wales)",
+      "sort_order": 24
     }
   },
   {
     "model": "breads.country",
     "pk": 15,
     "fields": {
-      "title": "Iran\nAfghanistan (northwestern)"
+      "title": "Iran\nAfghanistan (northwestern)",
+      "sort_order": 8
     }
   },
   {
     "model": "breads.country",
     "pk": 16,
     "fields": {
-      "title": "Ireland"
+      "title": "Ireland",
+      "sort_order": 9
     }
   },
   {
     "model": "breads.country",
     "pk": 17,
     "fields": {
-      "title": "Italy"
+      "title": "Italy",
+      "sort_order": 10
     }
   },
   {
     "model": "breads.country",
     "pk": 18,
     "fields": {
-      "title": "Libya"
+      "title": "Libya",
+      "sort_order": 13
     }
   },
   {
     "model": "breads.country",
     "pk": 19,
     "fields": {
-      "title": "Turkey"
+      "title": "Turkey",
+      "sort_order": 22
     }
   },
   {
     "model": "breads.country",
     "pk": 20,
     "fields": {
-      "title": "North America"
+      "title": "North America",
+      "sort_order": 14
     }
   },
   {
     "model": "breads.country",
     "pk": 21,
     "fields": {
-      "title": "India\nPakistan"
+      "title": "India\nPakistan",
+      "sort_order": 6
     }
   },
   {
     "model": "breads.country",
     "pk": 22,
     "fields": {
-      "title": "Poland"
+      "title": "Poland",
+      "sort_order": 15
     }
   },
   {
     "model": "breads.country",
     "pk": 23,
     "fields": {
-      "title": "China"
+      "title": "China",
+      "sort_order": 2
     }
   },
   {
     "model": "breads.country",
     "pk": 24,
     "fields": {
-      "title": "Afghanistan"
+      "title": "Afghanistan",
+      "sort_order": 1
     }
   },
   {
     "model": "breads.country",
     "pk": 25,
     "fields": {
-      "title": "Portugal (Madeira)"
+      "title": "Portugal (Madeira)",
+      "sort_order": 17
     }
   },
   {
@@ -465,7 +490,8 @@
       "go_live_at": null,
       "expire_at": null,
       "expired": false,
-      "name": "Yeast"
+      "name": "Yeast",
+      "sort_order": 5
     }
   },
   {
@@ -481,7 +507,8 @@
       "go_live_at": null,
       "expire_at": null,
       "expired": false,
-      "name": "Flour"
+      "name": "Flour",
+      "sort_order": 2
     }
   },
   {
@@ -497,7 +524,8 @@
       "go_live_at": null,
       "expire_at": null,
       "expired": false,
-      "name": "Water"
+      "name": "Water",
+      "sort_order": 4
     }
   },
   {
@@ -513,7 +541,8 @@
       "go_live_at": null,
       "expire_at": null,
       "expired": false,
-      "name": "Cinnamon"
+      "name": "Cinnamon",
+      "sort_order": 1
     }
   },
   {
@@ -529,7 +558,8 @@
       "go_live_at": null,
       "expire_at": null,
       "expired": false,
-      "name": "Salt"
+      "name": "Salt",
+      "sort_order": 3
     }
   },
   {

+ 39 - 0
bakerydemo/breads/migrations/0010_alter_breadingredient_options_alter_country_options_and_more.py

@@ -0,0 +1,39 @@
+# Generated by Django 5.2.7 on 2025-10-27 08:11
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("breads", "0009_alter_breadpage_body"),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name="breadingredient",
+            options={
+                "ordering": ["sort_order", "name"],
+                "verbose_name": "bread ingredient",
+                "verbose_name_plural": "bread ingredients",
+            },
+        ),
+        migrations.AlterModelOptions(
+            name="country",
+            options={
+                "ordering": ["sort_order", "title"],
+                "verbose_name": "country of origin",
+                "verbose_name_plural": "countries of origin",
+            },
+        ),
+        migrations.AddField(
+            model_name="breadingredient",
+            name="sort_order",
+            field=models.IntegerField(blank=True, editable=False, null=True),
+        ),
+        migrations.AddField(
+            model_name="country",
+            name="sort_order",
+            field=models.IntegerField(blank=True, db_index=True, null=True),
+        ),
+    ]

+ 9 - 2
bakerydemo/breads/models.py

@@ -6,7 +6,7 @@ from modelcluster.fields import ParentalManyToManyField
 from wagtail.admin.panels import FieldPanel, MultiFieldPanel
 from wagtail.api import APIField
 from wagtail.fields import StreamField
-from wagtail.models import DraftStateMixin, Page, RevisionMixin
+from wagtail.models import DraftStateMixin, Orderable, Page, RevisionMixin
 from wagtail.search import index
 
 from bakerydemo.base.blocks import BaseStreamBlock
@@ -24,6 +24,7 @@ class Country(models.Model):
     """
 
     title = models.CharField(max_length=100)
+    sort_order = models.IntegerField(null=True, blank=True, db_index=True)
 
     api_fields = [
         APIField("title"),
@@ -37,7 +38,7 @@ class Country(models.Model):
         verbose_name_plural = "countries of origin"
 
 
-class BreadIngredient(DraftStateMixin, RevisionMixin, models.Model):
+class BreadIngredient(Orderable, DraftStateMixin, RevisionMixin, models.Model):
     """
     A Django model to store a single ingredient.
     It is made accessible in the Wagtail admin interface through the BreadIngredientSnippetViewSet
@@ -71,6 +72,7 @@ class BreadIngredient(DraftStateMixin, RevisionMixin, models.Model):
     class Meta:
         verbose_name = "bread ingredient"
         verbose_name_plural = "bread ingredients"
+        ordering = ["sort_order", "name"]
 
 
 class BreadType(RevisionMixin, models.Model):
@@ -181,6 +183,11 @@ class BreadPage(Page):
         APIField("ingredients"),
     ]
 
+    @property
+    def ordered_ingredients(self):
+        """Return ingredients ordered by sort_order, then name."""
+        return self.ingredients.order_by("sort_order", "name")
+
 
 class BreadsIndexPage(Page):
     """

+ 3 - 2
bakerydemo/breads/wagtail_hooks.py

@@ -18,7 +18,7 @@ class BreadIngredientFilterSet(RevisionFilterSetMixin, WagtailFilterSet):
 
 class BreadIngredientSnippetViewSet(SnippetViewSet):
     model = BreadIngredient
-    ordering = ("name",)
+    ordering = ("name")
     search_fields = ("name",)
     filterset_class = BreadIngredientFilterSet
     inspect_view_enabled = True
@@ -39,10 +39,11 @@ class BreadTypeSnippetViewSet(SnippetViewSet):
 
 class CountryModelViewSet(ModelViewSet):
     model = Country
-    ordering = ("title",)
+    ordering = ("title")
     search_fields = ("title",)
     icon = "globe"
     inspect_view_enabled = True
+    sort_order_field = "sort_order"
 
     panels = [
         FieldPanel("title"),

+ 1 - 1
bakerydemo/templates/breads/bread_page.html

@@ -32,7 +32,7 @@
                                 <p class="bread-detail__meta-title">Type</p>
                                 <p class="bread-detail__meta-content">{{ page.bread_type }}</p>
                             {% endif %}
-                            {% with ingredients=page.ingredients.all %}
+                            {% with ingredients=page.ordered_ingredients %}
                                 {% if ingredients %}
                                     <h4>Ingredients</h4>
                                     <ul>