使用 HTMX 时表单未提交到数据库
Posted
技术标签:
【中文标题】使用 HTMX 时表单未提交到数据库【英文标题】:Form not submitting to the DataBase when using HTMX 【发布时间】:2022-01-09 11:21:03 【问题描述】:我有以下模型,你可以看到它们是相互关联的
class Leads(models.Model):
project_id = models.BigAutoField(primary_key=True, serialize=False)
created_at = models.DateTimeField(auto_now_add=True)
expected_revenue = MoneyField(decimal_places=2,max_digits=14, default_currency='USD')
expected_licenses = models.IntegerField()
country = CountryField(blank_label='(select_country)')
status = models.CharField(choices=[('Open', 'Open'), ('Closed', 'Closed'), ('Canceled', 'Canceled'),
('Idle', 'Idle')
], max_length=10)
estimated_closing_date = models.DateField()
services = models.CharField(choices=[('Illumination Studies', 'Illumination Studies'),
('Training', 'Training'),('Survey Design Consultancy', 'Survey Design Consultancy'),
('Software License', 'Software License'),
('Software Development','Software Development')], max_length=40)
agent = models.ForeignKey(Profile, default='agent',on_delete=models.CASCADE)
company = models.ForeignKey(Company,on_delete=models.CASCADE)
point_of_contact = models.ForeignKey(Client, default='agent',on_delete=models.CASCADE)
updated_at = models.DateTimeField(auto_now=True)
application = models.CharField(choices=[('O&G','O&G'),('Renewables','Renewables'),('Mining','Mining'),
('Other','Other'),('CSS','CSS')],
default='O&G',max_length=20)
sub_category = models.CharField(choices=[('Wind','Wind'),('Geo-Thermal','Geo-Thermal'),('Solar','Solar'),
('Tidal','Tidal')], max_length=20, blank=True)
@property
def age_in_days(self):
today = date.today()
result = self.estimated_closing_date - today
return result.days
def __str__(self):
return f'self.project_id'
class LeadEntry(models.Model):
revenue = MoneyField(decimal_places=2,max_digits=14, default_currency='USD',blank=True)
date = models.DateField()
lead_id = models.ForeignKey(Leads,on_delete=models.CASCADE)
id = models.BigAutoField(primary_key=True, serialize=False)
probability = models.DecimalField(max_digits=2, decimal_places=2, default=0, blank=True)
@property
def est_revenue(self):
result = self.revenue * probabiity
return result
基本上,潜在客户条目与潜在客户相关,我使用 HTMX 实质上是使用表单将数据添加到 LeadEntry 数据库。
表格
class LeadEntryForm(forms.ModelForm):
class Meta:
model = LeadEntry
fields = ('lead_id','date','revenue','probability')
widgets = 'date': DateInput()
我有 2 个视图,一个将简单地传递一个带有按钮的 html,供用户向数据库添加条目,另一个视图具有实际表单
观看次数
@login_required
def add_to_forecast(request):
id = request.GET.get('project_id')
request.session['lead_id'] = id
return render(request, 'account/lead_forecast.html')
@login_required
def forecast_form(request):
if request.method=='POST':
form = LeadEntryForm(data=request.POST or None)
if form.is_valid():
form.save(commit=False)
messages.success(request,"Successful Submission")
return redirect('add_to_forecast')
lead_id = request.session['lead_id']
data = 'lead_id':lead_id
context =
"form":LeadEntryForm(initial=data)
return render(request, 'account/lead_entry_forecast.html', context)
最后,有 2 个 HTML 页面,第一个与 add_to_forecast 关联并呈现一个简单的页面,这是 HTMX 发生的地方,它会从下一个 HTML 页面添加表单
% extends "base.html" %
% load crispy_forms_tags %
% load static %
% block title %Client Information % endblock %
% block content %
<h1> Add Lead to Sales Forecast </h1>
<p>Click the Button below to add a Payment Date</p>
<button type="button" hx-get="% url 'lead_entry_forecast' %" hx-target="#leadform" hx-swap="beforeend" >
Add Lead </button>
<div id="leadform">
<br>
</div>
% endblock %
用户想添加多少次就添加多少次的表单
% load crispy_forms_tags %
% load static %
% block content %
<div class="container-fluid">
<form method="post" enctype="multipart/form-data" action=".">
% csrf_token %
<div class="row justify-content-center">
<div class="col-sm-1">
form.lead_id|as_crispy_field
</div>
<div class="col-sm-2">
form.date|as_crispy_field
</div>
<div class="col-sm-2">
form.revenue|as_crispy_field
</div>
<div class="col-sm-1">
form.probability|as_crispy_field
</div>
<div class="col-sm">
<input type="submit" value="Submit" >
</div>
</div>
</form>
</div>
<hr>
% endblock %
我的问题是提交表单后,一切似乎都在工作,显然,目前您只能提交一个潜在客户,因为我仍然需要添加更多逻辑,但目前表单没有发送数据到数据库,经过一些调试,我无法通过POST,似乎只是没有提交任何东西。
我们将不胜感激任何帮助
更新 - 2021 年 12 月 4 日
我尝试使用表单提交数据,它确实有效,所以提交POST.request的表单没有任何问题,如果我直接进入URL,它可以正常工作,所以表单提交正确并且数据库已更新。
我仍然不明白为什么当表单由 htmx 呈现时不起作用,所以它与此有关。
【问题讨论】:
【参考方案1】:当你设计一个HTMX页面时,你必须小心post请求,所以我在错误的视图中处理表单,请看下面的视图:
@login_required
def add_to_forecast(request):
form = LeadEntryForm(data=request.POST or None)
if request.method == 'POST':
if form.is_valid():
form.save()
return HttpResponse("Success")
else:
return render(request, 'account/lead_entry_forecast.html', "form": form)
id = request.GET.get('project_id')
request.session['lead_id'] = id
return render(request, 'account/lead_forecast.html')
@login_required
def forecast_form(request):
lead_id = request.session['lead_id']
data = 'lead_id':lead_id
context =
"form":LeadEntryForm(initial=data)
return render(request, 'account/lead_entry_forecast.html', context)
现在它可以正常工作了
【讨论】:
以上是关于使用 HTMX 时表单未提交到数据库的主要内容,如果未能解决你的问题,请参考以下文章
在 HTMX 中,如何为选择表单元素中的每个选项请求特定的 URL?