使用 HTMX 时表单不提交到数据库

Form not submitting to the DataBase when using HTMX

我有以下模型,如您所见,它们相互关联


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 呈现时不起作用,所以它与此有关。

当你设计一个 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)

现在可以正常工作了