我试图实现的功能是,当表单在创建视图中提交时,我希望在它下面显示创建的对象,而不刷新页面。我知道实现这一点的方法是通过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 = ()
所以它是一个空的形式,只是为了创建对象。
键创建表单的hx-post
端点应该是key_create_view
,而不是键显示视图。实际上,在表单页面上{{ key_url }}
是空的。此外,由于您只想显示最后生成的密钥,因此交换方法应该是默认的innerHTML
,因此HTMX将用新的#key
div中的内容替换。
<form action="" method="POST">
{% csrf_token %}
<div class="text-center">
<button hx-post="{% url 'create_key' %}" hx-target="#key" type="submit">Create new key</button>
</div>
</form>
<!-- HTMX will swap the returned key here -->
<div id="key"></div>
编辑:
重复键错误是由添加动态默认值的错误方法引起的。如果您实际调用函数(get_random_string(10)
),它将被执行一次,并且每个键将接收相同的随机字符串。您需要将该函数作为引用传递,因此每次Django创建新模型时,它都会调用该函数,创建一个新的随机字符串。由于get_random_string
需要一个参数,因此我们需要创建一个小型包装器函数。
def get_default_random_string():
return get_random_string(length=10)
class Key(models.Model):
key = models.CharField(max_length=10, null=False, default=get_default_random_string, unique=True)
amount = models.IntegerField(default=1)
created = models.DateTimeField(auto_now_add=True)