使用 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 时表单未提交到数据库的主要内容,如果未能解决你的问题,请参考以下文章

处理 http post 时使用哪些 http 状态代码?

php表单未将日期发送到数据库SQL

如果提交表单时未选中复选框,如何将布尔值更新为 0

在 HTMX 中,如何为选择表单元素中的每个选项请求特定的 URL?

当我尝试提交表单以存储某些值和上传图像的路径到数据库时,我收到[对象引用未设置...]的错误[复制]

Sails.js 表单帖子未提交任何数据