HTMX 可排序仅工作一次,渲染使其禁用

问题描述 投票:0回答:2

我指的是 YouTube 上关于使用 Django 进行排序菜单的 BugBytes 频道。

(Django 和 HTMX #6(第 1 部分)- 构建可排序的拖放界面 )

https://www.youtube.com/watch?v=V-f_yYKUJo8

(Django 和 HTMX #6(第 2 部分)- 构建可排序的拖放界面 )

https://www.youtube.com/watch?v=5Fuwo4tVXmE

有些人遇到了同样的问题,但找到了解决问题的线索。

我没有任何暗示。

在 StackOverflow here 中发现了同样的问题。“Sortable JS 在 htmx 渲染部分时中断”

我认为答案似乎没有显示任何解决方案。

就我而言,按照 BugBytes 教程视频和 存储库,我制作了以下 Django 文件。

书籍.html

<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>List Books</title>
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>

  <script src="https://unpkg.com/[email protected]" integrity="sha384-EzBXYPt0/T6gxNp0nuPtLkmRpmDBbjg6WmCUZRLXBBwYYmwAUxzlSGej0ARHX0Bo" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"></script>
  
</head>
<body>


  <section id="book_list">
    {% include 'list_books.html' %}
  </section>




  <script>
    document.body.addEventListener('htmx:configRequest', (event) => {
        event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
    })
    htmx.onLoad(function(content) {
        var sortables = content.querySelectorAll(".sortable");
        for (var i = 0; i < sortables.length; i++) {
          var sortable = sortables[i];
          new Sortable(sortable, {
              animation: 150,
              ghostClass: 'blue-background-class'
          });
        }
    })

  </script>
</body>
</html>

list_books.html

    {% csrf_token %}
  <form class="sortable" hx-post="{% url 'book_app:sort' %}" hx-trigger="end" hx-target="#book_list" hx-swap="innerHTML">
    <div class="htmx-indicator">Updating...</div>
    
    {% for book in all_books %}
    <div>
        <input type='hidden' name='book_order' value='{{ book.pk }}'/>
      <p>#{{ book.order }} / {{ book.category.large_category }}/{{ book.category }}/{{ book.title }}</p>
    </div>
    {% endfor %}

  </form>

url.py

from django.urls import path
from . import views

app_name = 'book_app'

urlpatterns = [
    path('books/', views.books, name='books'),
]

htmx_urlpatterns = [
    path('sort/', views.sort, name='sort'),
]

urlpatterns += htmx_urlpatterns

views.py


def books(request):
    all_books = Books.objects.all().order_by('order')
    context = {
        'all_books': all_books,
    }
    return render(request, 'books.html', context)

def sort(request):
    books_order_list = request.POST.getlist('book_order')
    print(books_order_list)
    all_books = []
    for idx, book_pk in enumerate(books_order_list, start=1):
        book = Books.objects.get(pk=book_pk)
        book.order = idx
        book.save()
        all_books.append(book)
    context = {
        'all_books': all_books,
    }
    return render(request, 'list_books.html', context)

模型.py

from django.db import models

# Create your models here.

class LargeCategory(models.Model):
    name = models.CharField(max_length=25)

    def __str__(self):
        return self.name

class SmallCategory(models.Model):
    large_category = models.ForeignKey(LargeCategory, on_delete=models.CASCADE)
    name = models.CharField(max_length=25)

    def __str__(self):
        return self.name


class Books(models.Model):
    category = models.ForeignKey(SmallCategory, on_delete=models.CASCADE)
    title = models.CharField(max_length=25)
    order = models.PositiveSmallIntegerField(null=True, blank=True)

我在准备发布这个问题时注意到,如果我更改目标文件以在views.py文件中渲染sort()函数会怎样???

所以我改变了views.py文件中的sort()函数,就像下一个一样!!


def sort(request):
    books_order_list = request.POST.getlist('book_order')
    print(books_order_list)
    all_books = []
    for idx, book_pk in enumerate(books_order_list, start=1):
        book = Books.objects.get(pk=book_pk)
        book.order = idx
        book.save()
        all_books.append(book)
    context = {
        'all_books': all_books,
    }
    return render(request, 'books.html', context)

我将目标模板文件更改为“list_books.html”渲染为“books.html”。

最后它完全工作正常!!

BugBytes的教程视频中,views.py中sort()函数的目标模板文件经复核为“film-list.html”。

所以现在,它必须是“films.html”。

希望这对未来的学生有帮助。

因为关于 HTMX 及其可排序类的参考资源很少。

快乐编码!! :D!!

javascript jquery django ajax htmx
2个回答
0
投票

我猜你的方法会重新渲染整个页面?

BugBytes 视频下方有来自 @johndodd9972 的解决方案。 我只是把这个留给下一个将要遇到这个问题的人,因为我浪费了几个小时:

在base.html中,替换

var sortables = content.querySelectorAll(".sortable");

var sortables = document.querySelectorAll(".sortable");


0
投票

这里同样的错误,这种更改查询内容的方法对我不起作用

© www.soinside.com 2019 - 2024. All rights reserved.