首页 > 解决方案 > Django - POST is_valid() false,没有错误,也没有写入数据库

问题描述

我有一个简单的 html 表单,我可以在其中添加一些数据并将其提交以添加到数据库中。

这是表格:

 <!-- MAIN CONTENT-->

    <div class="main-content">
        <div class="section__content section__content--w1830">
            <div class="container-fluid">

                <h1>Artikel</h1>
                <br>
                <br>

                <div class="card">
                    <div class="card-header">Artikel hinzufügen</div>
                    <div class="card-body">
                        <form action="" method="post">
                            {% csrf_token %}
                            <div class="form-group">
                                <div class="row form-group">
                                    <div class="col-4">
                                        <label for="type" class="control-label mb-1">Typ</label>
                                        <select name="type" id="type" class="form-control"
                                                value=" {{ forms.artikel_typ }} ">
                                            <option value="0">Bitte auswählen</option>
                                            <option value="1">Raum</option>
                                            <option value="2">Artikel</option>
                                            <option value="3">Gerät</option>
                                            <option value="4">Marketing</option>
                                            <option value="5">Labor</option>
                                        </select>
                                    </div>
                                    <div class="col-8">
                                        <label for="bezeichnung" class="control-label mb-1"> Bezeichnung</label>
                                        <input id="bezeichnung" name="bezeichnung" type="text" class="form-control"
                                               data-val="true"
                                               data-val-required="Bitte tragen Sie eine Bezeichnung ein!"
                                               aria-required="true" aria-invalid="false"
                                               placeholder="Bitte tragen Sie eine Bezeichnung ein." value ="{{ forms.bezeichnung }}">
                                    </div>
                                </div>
                            </div>
                            <div class="card-body card-block">
                                <div class="row form-group">
                                    <div class="col-4">
                                        <label for="menge" class="control-label mb-1">Menge</label>
                                        <input id="menge"  type="number"
                                               class="form-control" data-val="ture"
                                               data-val-required="Bitte tragen Sie die Menge ein!"
                                               aria-required="true" aria-invalid="false"
                                               placeholder="Bitte geben Sie die Menge an." value=" {{ forms.menge }} ">
                                    </div>
                                    <div class="col-4">
                                        <label for="einheit" class="control-label mb-1">Einheit</label>
                                        <select name="einheit" value="{{ forms.einheit }}" id="einheit"
                                                class="form-control"
                                                data-val-required="Bitte tragen Sie die Einheit ein!"
                                                aria-required="true" aria-invalid="false">
                                            <option value="0">Bitte auswählen</option>
                                            <option value="Euro">Euro</option>
                                            <option value="Prozent">Prozent</option>
                                            <option value="Minuten">Minuten</option>
                                            <option value="Stück">Stück</option>
                                            <option value="pauschal">pauschal</option>
                                        </select>
                                    </div>
                                    <div class="col-4">
                                        <label for="preis">Preis</label>
                                        <input id="preis" value="{{ forms.preis }}" step="0.01" type="number"
                                               class="form-control"
                                               data-val="ture"
                                               data-val-required="Bitte tragen Sie den Preis ein!"
                                               aria-required="true" aria-invalid="false"
                                               placeholder="Bitte tragen Sie den Preis ein!">
                                    </div>

                                </div>
                            </div>


                            <div class="card-footer">
                                
                                <button type="submit" class="btn btn-primary btn-sm" value="post" action="articles">
                                    <i class="fa fa-dot-circle-o"></i> Artikel hinzufügen
                                </button>
                            </div>

                    </div>
                    </form>

                </div>

                <div class="container-fluid">
                    <div class="row">
                        <div class="col-lg-9">
                            <div class="table-responsive table--no-card m-b-30">
                                <table class="table table-bordered table-striped">
                                    <thead>
                                    <tr>
                                        <th>id</th>
                                        <th>artikel_typ</th>
                                        <th>bezeichnung</th>
                                        <th>menge</th>
                                        <th>preis</th>
                                        <th>einheit</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    {% for d in data %}
                                        <tr>
                                            <td>{{ d.id }}</td>
                                            {% if  d.artikel_typ == 1 %}
                                                <td> Raum</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 2 %}
                                                <td> Artikel</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 3 %}
                                                <td> Gerät</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 4 %}
                                                <td> Marketing</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 5 %}
                                                <td> Labor</td>
                                            {% endif %}
                                            <td>{{ d.bezeichnung }}</td>
                                            <td>{{ d.menge }}</td>
                                            <td>{{ d.preis }}</td>
                                            <td>{{ d.einheit }}</td>
                                        </tr>
                                    {% endfor %}
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- END PAGE CONTAINER-->

这是使用的代码的 views.py 部分:

def articles(request):

data = Artikel.objects.all()
aform = ArtikelForm( data=request.POST or None)

if request.method == "POST":

    if aform.is_valid():
        artikel_type = aform.cleaned_data['artikel_typ']
        bezeichnung = aform.cleaned_data['bezeichnung']
        menge =  aform.cleaned_data['menge']
        preis =  aform.cleaned_data['preis']
        einheit =  aform.cleaned_data['einheit']
        artikel = Artikel(artikel_typ=artikel_type, bezeichnung=bezeichnung, menge=menge, preis=preis, einheit=einheit)
        artikel.save()

    return redirect("articles")


return render(request, "articles.html", {"data": data, "forms": aform})

这是我定义的forms.py:

from django import forms

类 ArtikelForm(forms.Form):

artikel_typ = forms.IntegerField()
bezeichnung = forms.CharField(max_length=100)
menge = forms.FloatField()
preis = forms.FloatField()
einheit = forms.CharField(max_length=100)

这是models.py中定义的模型:

class Artikel(models.Model):
    id = models.AutoField(unique=True, primary_key=True)
    artikel_typ = models.IntegerField(null=True)
    bezeichnung = models.TextField()
    menge = models.FloatField(blank=True, null=True)
    preis = models.FloatField(blank=True, null=True)
    einheit = models.TextField(blank=True, null=True)

所以我尝试了模型、表单和 python 控制台。我将数据添加到 dict,创建了 ArtikelForm 的实例并调用 is_valid(),它返回 true,clean_data 看起来不错。

但是,当提交表单时,is_valid() 返回下降,并且字段值返回 None 对于整数和浮点字段,检索 char 字段并显示我输入/选择的信息,HTTP 响应为 200 并被重定向。有没有人可以解决我如何解决这个问题?谢谢!

标签: pythondjangodatabasepost

解决方案


您在这里遇到了一些问题,我将尝试详细解释它们。每当您在 Django 中创建表单时,您都必须为其创建一个类,该类定义所有字段以及如何“构建”表单,您已在forms.py. 即使你正确地做到了,你可能想要考虑继承,forms.ModelForm因为它会使表单创建更容易。基本上 aModelForm会自动为您制作一个表格Model在这里查看 更多信息。

真正神奇的views.py地方是您处理请求并以适当的形式返回呈现的 html 的地方。您所做的是在您的模型中查询某些对象data = Artikel.objects.all(),然后创建表单aform = ArtikelForm( data=request.POST or None),然后检查该方法是否是POST请求以验证表单并执行其他操作。但是,在底部,当您返回时,您不会将表单传递给 html。你需要确保你传递了一个包含所有内容的字典,例如return render(request, 'articles.html', {'data': data, 'forms': aform})。这应该可以解决无法从模板访问表单的问题。但这意味着您将访问表单中的特定字段,如下所示:{{ forms.artikel_typ }}.

另外我想指出,在您views.py访问表单内的数据以保存到您通常想要获取“清理数据”的模型时。这是 Django 所做的,以确保所有字段都变成某种 python 标准,以便轻松使用它并将其保存到模型中。您访问它的方式是通过执行aform.cleaned_data['artikel_typ']. 也可以考虑使用酥脆的表格,这样您就不必手动制作表格。

编辑

在您的 html 模板中,您需要做的就是访问{{ forms.field_name }},它将放入该字段小部件的 html。无需手动创建表单,这就是您使用 Django 表单的原因。见下文:

 <!-- MAIN CONTENT-->

    <div class="main-content">
        <div class="section__content section__content--w1830">
            <div class="container-fluid">

                <h1>Artikel</h1>
                <br>
                <br>

                <div class="card">
                    <div class="card-header">Artikel hinzufügen</div>
                    <div class="card-body">
                        <form action="" method="post">
                            {% csrf_token %}
                            {{ forms.artikel_typ }}
                            {{ forms.bezeichnung }}
                            {{ forms.menge }}
                            {{ forms.preis }}
                            {{ forms.einheit }}
                    </form>
                </div>

                <div class="container-fluid">
                    <div class="row">
                        <div class="col-lg-9">
                            <div class="table-responsive table--no-card m-b-30">
                                <table class="table table-bordered table-striped">
                                    <thead>
                                    <tr>
                                        <th>id</th>
                                        <th>artikel_typ</th>
                                        <th>bezeichnung</th>
                                        <th>menge</th>
                                        <th>preis</th>
                                        <th>einheit</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    {% for d in data %}
                                        <tr>
                                            <td>{{ d.id }}</td>
                                            {% if  d.artikel_typ == 1 %}
                                                <td> Raum</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 2 %}
                                                <td> Artikel</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 3 %}
                                                <td> Gerät</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 4 %}
                                                <td> Marketing</td>
                                            {% endif %}
                                            {% if  d.artikel_typ  == 5 %}
                                                <td> Labor</td>
                                            {% endif %}
                                            <td>{{ d.bezeichnung }}</td>
                                            <td>{{ d.menge }}</td>
                                            <td>{{ d.preis }}</td>
                                            <td>{{ d.einheit }}</td>
                                        </tr>
                                    {% endfor %}
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- END PAGE CONTAINER-->

如果您想重新排列它们的去向并进行一些样式设置,这将单独访问每个字段,但您也可以简单地使用{{ forms }}它将呈现所有字段。


推荐阅读