创建对象并使用HTMX在同一页面中显示
我试图实现的功能是,当表单在创建视图中提交时,我想在其下方显示创建对象,而无需页面刷新。我知道实现此目的的方法是通过HTMX。正在创建的对象是唯一且随机生成的键。但是它无法正常工作。现在,第一次单击按钮创建键并显示它的按钮,但是第二次尝试显示上一个键,并且因为它已经存在它不是唯一的,因此它没有显示。
这是我有两个视图,一个创建视图和详细视图的模型
class Key(models.Model):
key = models.CharField(max_length=10, null=False, default=get_random_string(length=10), unique=True)
amount = models.IntegerField(default=1)
created = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse("key", kwargs={"id": self.id })
,我希望使用CBV,但我无法透露自己的实现方式,因此我坚持基于功能的视图。 视图看起来像这样
@login_required
def key_create_view(request):
form = CreateKeyForm(request.POST or None)
context = {
"form": form,
}
if form.is_valid():
obj = form.save(commit=False)
obj.save()
key_url = reverse('key', kwargs={'id':obj.id})
if request.htmx:
context = {
"object": obj,
"key_url": key_url
}
return render(request, "base/components/key.html", context)
#return redirect(obj.get_absolute_url())
return render(request, "base/form.html", context)
@login_required
def key_detail_hx_view(request, id=None):
if not request.htmx:
raise Http404
try:
obj = Key.objects.get(id=id)
except:
obj = None
if obj is None:
return HttpResponse("Something went wrong")
context = {
"object": obj
}
return render(request, "base/components/key.html", context)
目前,在模板中,
<form action="" method="POST">
{% csrf_token %}
<div id="key" class="text-center">
<button hx-post="{{key_url}}" hx-target="#key" hx-swap="beforeend" type="submit">Create new key</button>
</div>
</form>
,我希望它每次按下按钮并替换上一个键时都会生成一个新键。有人知道我如何实施吗?
编辑 这些是我的URL,
path('createkey', key_create_view, name='create_key'),
path('createkey/<int:id>', key_detail_hx_view, name='key')
这是形式
class CreateKeyForm(forms.ModelForm):
class Meta:
model = Key
fields = ()
,因此它是一个空形式,只是为了创建对象。
The function I am trying to implement is that, when the form is submitted in the create view, I would like to display the created object beneath it without the page refreshing. I know the way to implement this is through HTMX. The object that is being created is a key which is unique and gets randomly generated. However it does not work properly. Right now, first time clicking the button it creates a key and displays it but the second time it tries to show the previous key and because it already exists it is not unique and therefore it shows nothing.
This is the model
class Key(models.Model):
key = models.CharField(max_length=10, null=False, default=get_random_string(length=10), unique=True)
amount = models.IntegerField(default=1)
created = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse("key", kwargs={"id": self.id })
I have two views, a create view and a detail view, I would have liked to used CBV but I can't get my head around how I would implement that, so I am sticking to function based views. Right now the views are looking like this
@login_required
def key_create_view(request):
form = CreateKeyForm(request.POST or None)
context = {
"form": form,
}
if form.is_valid():
obj = form.save(commit=False)
obj.save()
key_url = reverse('key', kwargs={'id':obj.id})
if request.htmx:
context = {
"object": obj,
"key_url": key_url
}
return render(request, "base/components/key.html", context)
#return redirect(obj.get_absolute_url())
return render(request, "base/form.html", context)
@login_required
def key_detail_hx_view(request, id=None):
if not request.htmx:
raise Http404
try:
obj = Key.objects.get(id=id)
except:
obj = None
if obj is None:
return HttpResponse("Something went wrong")
context = {
"object": obj
}
return render(request, "base/components/key.html", context)
In the template have I built it like this
<form action="" method="POST">
{% csrf_token %}
<div id="key" class="text-center">
<button hx-post="{{key_url}}" hx-target="#key" hx-swap="beforeend" type="submit">Create new key</button>
</div>
</form>
I would like it to generate a new key each time the button is pressed and replace the previous one. Does anybody know how I can implement that?
EDIT
These are my urls
path('createkey', key_create_view, name='create_key'),
path('createkey/<int:id>', key_detail_hx_view, name='key')
This is the form
class CreateKeyForm(forms.ModelForm):
class Meta:
model = Key
fields = ()
So it is an empty form, just to create the object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
键创建表单的
hx-post
端点应为key_create_view
而不是键显示视图。实际上,在表单页面上{{key_url}}
是空的。此外,由于您只想显示最后一个生成的密钥,因此交换方法应为默认innerhtml
,因此htmx将替换#key
div中的内容中的内容一。编辑:
重复的密钥错误是由错误的方法引起的,以添加动态默认值。如果您实际调用函数(
get_random_string(10)
),它将被执行一次,每个键将接收相同的随机字符串。您需要将函数作为参考传递,因此每次Django创建一个新模型时,都会称呼此功能,创建一个新的随机字符串。由于get_random_string
需要一个参数,因此我们需要创建一个小包装函数。The key creating form's
hx-post
endpoint should be thekey_create_view
not the key displaying view. Actually, on the form page{{ key_url }}
is empty. Furthermore, since you want to show only the last generated key, the swapping method should be the defaultinnerHTML
, so HTMX will replace the content inside the#key
div with the new one.Edit:
The duplicate key error is caused by the wrong approach to add a dynamic default value. If you actually call the function (
get_random_string(10)
) it will be executed once and each key will receive the same random string. You need to pass the function as a reference, so each time Django creates a new model, it will call this function, creating a new random string. Sinceget_random_string
needs a parameter, we need to create a small wrapper function.