对于 HTMX 和 Django 来说,我想要实现的是在页面上有一个 ModelForm,并带有一个按钮,允许用户直接在页面上“编辑”字段值。按“编辑”按钮后,页面应显示“取消”和“提交”按钮。它与 HTMX 网站上的这个示例基本相同:Edit Row
在索引页查看:
这是我到目前为止所拥有的(当用户按下“编辑条目”时),但它没有按预期工作:
有几个问题:
当按下“编辑”按钮时,ModelForm 会将所有内容加载到 HTML 表的第一列中。理想情况下,我希望模型的每个字段都位于表中的“正确”位置。
当按下“取消编辑”按钮时,会将 ModelForm 交换回 HTML 模板。我不想要这个,只是想让表行恢复到以前的状态。
提交按钮不会将数据发送回模型。
我不确定如何真正考虑这里的设计以使 HTML 表和 ModelForm 按预期工作(#1 和 #2)。
对于#3,问题似乎是 PUT request.method 作为空的 QuerySet 返回。
感谢您提供的任何帮助。一旦我开始工作,我将上传一个简短的视频到 YouTube,以帮助其他初学者,因为除了这个简单的实现的文档之外,我无法在网上找到任何示例。
基本 HTML 模板
<!DOCTYPE html>
<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>Document</title>
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
<!-- HTMX -->
<script src="https://unpkg.com/htmx.org@1.8.0" integrity="sha384-cZuAZ+ZbwkNRnrKi05G/fjBX+azI9DNOkNYysZ0I/X5ZFgsmMiBXgDZof30F5ofc" crossorigin="anonymous"></script>
</head>
{% block page_content %}
<body>
<table class="country_table">
<thead>
<tr>
<th> City Name </th>
<th> Country </th>
<th> Latitude </th>
<th> Longitude </th>
<th> </th>
</tr>
</thead>
<tbody hx-target="closest tr" hx-swap="outer HTML">
{% for city in city_model %}
<tr>
<td> {{city.city_name}}</td>
<td> {{city.city_country}}</td>
<td> {{city.city_latitude}}</td>
<td> {{city.city_longitude}}</td>
<td> <button class="btn btn-danger"
hx-get="{% url 'edit_city_record' city.city_name %}"
hx-trigger="click"> Edit Entry </button> </td>
</tr>
{%endfor%}
</tbody>
</table>
</body>
{% endblock page_content %}
</html>
<script>
document.body.addEventListener('htmx:configRequest', (event) => {
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}'; })
</script>
Run Code Online (Sandbox Code Playgroud)
edit_city_record.html 模板
{% extends 'base_html.html' %}
{% block page_content %}
<tr>
<td> {{city_form.city_name}} </td>
<td> {{city_form.city_country}} </td>
<td> {{city_form.city_latitude}} </td>
<td> {{city_form.city_longitude}} </td>
<td> <button class="btn btn-danger"
hx-get="{% url 'get_city_record' city_object.city_name %}"
hx-trigger="click"> Cancel Edit </button> </td>
<td>
<button class="btn btn-danger"
type="submit"
hx-put="{% url 'edit_city_record' city_object.city_name %}"
hx-trigger="click"> Save Edit </button>
</td>
</tr>
{% endblock page_content %}
Run Code Online (Sandbox Code Playgroud)
get_city_record.py 模板
{% extends 'base_html.html' %}
{% block page_content %}
{{city_form}}
{% endblock page_content %}
Run Code Online (Sandbox Code Playgroud)
视图.py
from django.shortcuts import render
from main_app.models import cityModel
from main_app.forms import cityModelForm
def index(request):
city_model = cityModel.objects.all()
context = {'city_model': city_model}
return render(request, 'base_html.html', context)
def edit_city_record(request, city_name):
print(request.method)
city_object = cityModel.objects.get(city_name=city_name)
if request.method == 'PUT':
city_form = cityModelForm(request.POST, instance=city_object)
print(request.POST)
if city_form.is_valid():
city_form.save()
else:
city_form = cityModelForm(instance=city_object)
context = {'city_form': city_form, 'city_object': city_object}
return render(request, 'edit_city_record.html', context)
def get_city_record(request, city_name):
city_object = cityModel.objects.get(city_name=city_name)
city_form = cityModelForm(instance=city_object)
context = {'city_form': city_form}
return render(request, 'get_city_record.html', context)
Run Code Online (Sandbox Code Playgroud)