Django-如何将表单输入保存到数据库中的对象模型?

时间:2016-11-23 16:01:56

标签: python django forms

我有一个Django项目,用于管理许多项目,以及与项目相关的所有信息。

在其中一个标题为“概念”的网页上,有一个表单,它在一个文本框中输入不包括增值税的成本输入值,在另一个文本框中显示包含增值税的成本,并且有一个{{1} }字段允许用户选择已支付存款的日期(如果有的话)。

如果用户填写表单中的三个字段(用户输入的成本,成本,成本),我在获取表单以保存用户输入的当前日期时遇到了一些麻烦inc vat-基于const exc vat和& date自动生成,然后刷新页面,两个成本字段保留其值,但'date'字段恢复为空白。

当我检查'date'字段的页面元素时,我可以看到它在以下HTML结构中:

datepicker

修改

虽然这是我在浏览器中检查页面时HTML的结构,但我项目中HTML文件的实际代码是:

<body>
    ...
    <div class="wrapper">
        <div class="content">
            <form method="POST" .... data-view-url=".../concept_save_ajax/">
                <div class="col-12-box">
                    <div>
                        <table class="right fixed m-t-md">
                            <tbody>
                                <tr>
                                    ...
                                    <td class="p-r-md">Deposit exc VAT</td>
                                    <td class="p-r-md">
                                        <input class="currency" id="id_amount_exc_vat" name="amount_exc_vat" type="number" value="280">
                                    <td class="p-r-md>
                                        <input class="datepicker hasDatepicker" data-original-value id="id_date_received" name="date_received" type="text"> == $0
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </form>
        </div>
    </div>
</body>

结束修改

鉴于表单方法已指定为{% block content %} <form method="POST" enctype="multipart/form-data" data-vat-status="{{project.vat_status}}" data-view-url="{% url 'projects:concept_save_ajax_2' project.id %}" class="autosave_form formset full-width" action="{% url 'projects:upload_budget_pdfs' project.id %}"> ... </form> <form method="POST" enctype="multipart/form-data" data-vat-status="{{project.vat_status}}" data-view-url="{% url 'projects:concept_save_ajax' project.id %}" class="autosave_form full-width"> {% csrf_token %} <div class="col-12 box"> <div> <table class="right fixed m-t-md"> <tr> {% for hidden in deposit_form.hidden_fields %} {{hidden}} {% endfor %} {% for field in deposit_form.visible_fields %} <td class="p-r-md">{{field.label}}</td><td class="p-r-md">{{field}}</td> {% endfor %} <td><a class="email_trigger button" data-view-url="{% url 'comms:open_email_template' project.id %}?template=7">Raise invoice</a></td> </tr> </table> </div> </div> <div class="col-6 box"> ... </div> <div class="col-6 box"> ... </div> </form> {% endblock content %} ,我希望使用POST视图中指示的concept_save_ajax视图保存输入到表单中的信息。< / p>

此视图在<form>中定义:

views.py

我可以看到,如果满足条件def concept_save_ajax(request, project_id): """ Save concept forms """ if not request.is_ajax(): raise Http404('Ajax only') if request.method == 'POST': project = Project.objects.prefetch_related('budget_versions', 'budget_overview').get(pk=project_id) form_instances = [ # [DepositForm, project.deposit], [DepositInfoForm, project.deposit], [BudgetNotesForm, project.budget_overview], [EndDetailsForm, project.end], ] # Save the forms for form_instance in form_instances: form = form_instance[0](request.POST, instance=form_instance[0]) #1]) should be '0' for first element? if form.is_valid() and form.has_changed(): print form_instance[0], "is valid.", form_instance[0] updated_details = form.save() elif form.has_changed(): print form_instance[0], "is not valid", form.errors return JsonResponse({'error': form.errors}) # url = '/projects/{0}/?tab={1}'.format(project_id, tabs[3]) return JsonResponse({'success': 'Saved'}) else: raise Http404('Request is not a post') form.save(),此视图就会调用form.is_valid(),但出于某种原因,当我输入时,这似乎并没有实际保存“日期”字段的新值。

我试图在控制台中对此进行测试 - 但应该持有“日期”值的字段显示为空...在控制台中,我跑了:

form.has_changed()

但是,当我在控制台中运行 from projects import models from projects.models import Project allPrjcts = Project.objects.all() br = allPrjcts.filter(project_name="1 Brocks Road") from costing import models from costing.models import Deposit allDpsts = Deposit.objects.all() brocksRoad = br[0] # I know that this is the only project returned by the filter brDpst = allDpsts.get(project_id = 6311L) # I know that this is the ID for the 'brocksRoad' project 时,没有显示任何内容,表示我在网页上的“日期”字段中输入的值似乎没有保存...

为什么会这样?如何让'date'字段的值自动保存,以便在我重新加载页面时显示,与该表单上的'cost'字段相同?

如果我在控制台中运行brDpst.date_received,则会显示值:

  

十进制( '280.00')

这是我在文本框中输入的金额,所以显然表单正在保存...只是出于某种原因,'date'字段的值没有被保留...

修改

这是brDpst.amount_exc_vat当前的定义方式:

DepositInfoForm

我尝试将其更改为:

class DepositInfoForm(ValidatedForm):
    ...
    date_received = MoonDateField(required=False, label="Date deposit received", widget=forms.DateInput(format='%d/%m/%Y', attrs=({'class':'datepicker'})))

正如@neverwalkaloner所建议的那样,但如果我这样做,当我在表单上选择class DepositInfoForm(ValidatedForm): ... date_received = MoonDateField(required=False, label="Date deposit received", widget=forms.DateInput(format='%d/%m/%Y', attrs=({'class':'datepicker', 'type':'date'}))) 字段时,下拉列表中会显示两个日历...我想使用已经存在的日历选择日期,而不是我传递给date_received变量的'type':'date'参数添加的日期......

修改

我已经为我的date_received类添加了一些调试,并且在对采用数值的表单字段进行更改时似乎调用了它的DepositInfoForm(...)方法,但是{{1当对持有日期的表单字段进行更改时,没有被调用...我不明白为什么这是......?

save()类定义为:

save()

修改

当我尝试更改网页上表单中的日期时,虽然最初显示新日期,但如果我刷新页面,其值将更改回更改之前的值。当我更改表单中“日期”字段的值时,控制台将显示以下输出:

DepositInfoForm(...)

但我实际上并没有改变它在class DepositInfoForm(ValidatedForm): amount_exc_vat = forms.IntegerField(required=False, widget=forms.NumberInput(attrs={'class': 'currency',}),label="Deposit exc VAT") amount_inc_vat = forms.IntegerField(required=False, widget=forms.NumberInput(attrs={'class': 'currency', 'readonly':'readonly',}),label="Inc VAT") date_received = MoonDateField(required=False, label="Date deposit received", widget=forms.DateInput(format='%d/%m/%Y', attrs=({'class':'datepicker'}))) class Meta: model = Deposit fields = ('amount_exc_vat', 'amount_inc_vat', 'date_received')#,'received') def __init__(self, *args, **kwargs): print "__init__ method being called in DepositInfoForm" instance = kwargs.get('instance', {}) project = instance.project try: amount_exc_vat = int(round(instance.amount_exc_vat)) except TypeError: amount_exc_vat = None try: amount_inc_vat = int(round(project.deposit.amount_inc_vat)) except TypeError: amount_inc_vat = None try: date_received = instance.date_received except TypeError: date_received = None initial = kwargs.get('initial', {}) initial={ 'received': project.deposit_received, 'amount_exc_vat': amount_exc_vat, 'amount_inc_vat': amount_inc_vat, 'date_received': date_received, } kwargs['initial'] = initial super(DepositInfoForm, self).__init__(*args, **kwargs) self.fields['date_received'].widget.attrs.update({'data-original-value': self.initial['date_received'] or ''}) def save(self, commit=True): print "Save method being called in DepositInfoForm" deposit = self.instance data = self.cleaned_data print "save method being called in DepositInfoForm (projects/forms.py line 1142)" if 'date_received' in self.changed_data: if not data['date_received'] == '': deposit.project.deposit_received = True; self.deposit_r = True deposit.project.upgrade_detailed_status(Project.ds75) else: deposit.project.deposit_received = False; deposit.project.save() if ('amount_exc_vat' in self.changed_data or 'date_received' in self.changed_data in self.changed_data) and data['amount_exc_vat'] and data['date_received']: send_message(message_template=2, project=self.instance.project) self.deposit_r = True if hasattr(self, 'deposit_r'): # Make the payment deposit_payment = Payment(project=deposit.project, is_booking_deposit=True, amount_exc_vat=data['amount_exc_vat'], date_paid=data['date_received']) return super(DepositInfoForm, self).save(commit=commit) 中抱怨的任何文件......导致此异常的原因是什么?

1 个答案:

答案 0 :(得分:0)

可能是因为date_received的type = text而不是type = date。 尝试更改表单:

class DepositInfoForm(forms.Form):
    date_received = forms.DateField(widget=forms.TextInput(attrs=
                            {
                                'class':'datepicker hasDatepicker',
                                'type':'date'  
                            })