我遇到了一个与表单相关的问题,其中来自POST的数据显然已被发回,但是Django正在将其剥离,以便它不会进入我的表单类。
以下是我的类post()中的一些代码片段,它们显示了从模板返回的数据,以及数据是如何通过表单类过滤的。
为什么会这样?
直接从POST中获取数据而不使用内置表单类过滤有什么危害?
print(request.POST)
产生这个:
<QueryDict: {'book': ['Zippity do dah,'], 'weather': ["It's raining!"], 'dividend': ['Zippity aye!'], 'earnings': ['Yo man, one step at a time.'], 'csrfmiddlewaretoken': ['3MWFOwebVeYfCum8JaGvITRB542b3jbp']}>
和
main_form = self.main_form_class(request.POST)
print('\n','main_form: ',main_form)
产生这个:
main_form: <tr><th><label for="id_weather">weather:</label></th><td><input id="id_weather" maxlength="256" name="weather" size="36" type="text" /></td></tr>
<tr><th><label for="id_book">book:</label></th><td><input id="id_book" maxlength="256" name="book" size="36" type="text" /></td></tr>
<tr><th><label for="id_dividend">dividend:</label></th><td><input id="id_dividend" maxlength="256" name="dividend" size="36" type="text" /></td></tr>
<tr><th><label for="id_earnings">earnings:</label></th><td><input id="id_earnings" maxlength="256" name="earnings" size="36" type="text" /></td></tr>
<tr><th><label for="id_csrfmiddlewaretoken">csrfmiddlewaretoken:</label></th><td><input id="id_csrfmiddlewaretoken" maxlength="256" name="csrfmiddlewaretoken" size="36" type="text" /></td></tr>
您可以看到main_form中没有包含“值”。
main_form.is_valid() is never True
main_form.cleaned_data throws an error - if I pull it out in front of main_form.is_valid()
帮助!
好的 - 这里有一些代码:
我有一个子类,其表单不会从POST请求返回数据。超类也有一个表单,这个IS从同一个POST请求返回数据。也就是说超类正在请求用户输入,并且有几个子类扩展超类并请求其他数据。超类总是从表单的一部分返回数据,但子类不会。
子类在POST中返回数据,但数据不会返回到Django视图。这似乎是一个错误,(但也许它是一个特征)或另一个可能的情况是我错过了一些东西。但是,我找不到它。
解决方案可能是没有超级级别,只有一个非DRY程序。呸。
我在终端命令中添加了一些print()来查看返回的内容(或不回来)来验证这一点。
我还使用浏览器的开发人员工具看到POST确实在其中有必要的数据,应该返回到视图进行处理。但是,此数据不会使其返回到视图。
子类视图代码如下所示:
class MainView(SidebarBaseView):
main_form_class = MainViewForm
template_name = 'myapp/my_view.html'
def get(self, request, *args, **kwargs):
context = super(MainView, self).get(request, *args, **kwargs)
context.update(self.get_context_data(*args, **kwargs))
main_form_initial = {}
for detail in context['my_data']: # my_data comes from get_context_data()
field_name = detail.datatype.name
main_form_initial[field_name] = detail.note
main_form = self.main_form_class(initial=main_form_initial)
context['main_form'] = main_form
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
context = super(MainView, self).post(request, *args, **kwargs)
context.update(self.get_context_data(*args, **kwargs))
main_form = self.main_form_class(request.POST)
print('\n','main_form',main_form,'\n') #to terminal
if main_form.is_valid():
main_form_data = main_form.cleaned_data
print('\n', 'cleaned data', main_form_data, '\n') #to terminal
for detail in context['my_data']:
field_name = detail.datatype.name
detail.note = main_form_data[field_name]
detail.save()
main_form_initial = {}
for detail in context['my_data']:
field_name = detail.datatype.name
main_form_initial[field_name] = detail.note
main_form = self.main_form_class(initial=main_form_initial)
context['main_form'] = main_form
return render(request, self.template_name, context)
def get_context_data(self, *args, **kwargs):
context = super(CompanyStatsView, self).get_context_data(**kwargs)
...
return context
我的表单生成动态字段,因为我最终需要向其发送可变数量的字段:
class MyMainViewForm(forms.Form):
fields = {}
field_names = ['weather','book','dividend','earnings']
def __init__(self, field_names, *args, **kwargs):
super(MyMainViewForm, self).__init__(*args, **kwargs)
for name in field_names:
self.fields[name] = forms.CharField(label=name, max_length=256, required=False, widget=forms.TextInput(attrs={'size':'36'}))
我的模板如下所示:
{% extends 'my_sidebar.html' %}
{% block content_right %}
<div class="container-fluid">
<h2>Table</h2>
<div class="col-sm-4">
<div class="table-responsive">
<table class="table">
<tbody>
{% for detail in my_data %}
<tr height="50">
<td>{{ detail.datatype.full_name }}:</td>
<td class="text-right">{{ detail }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="col-sm-4">
<div class="table-responsive">
<table class="table">
<tbody>
<form action="." method="post"> {% csrf_token %}
{% for note in main_form %}
<tr height="50">
<td>{{ note }}</td>
</tr>
{% endfor %}
<p><input type="submit" value="Save"></p>
</form>
</tbody>
</table>
</div>
</div>
<div class="col-sm-4">
</div>
</div>
{% endblock %}
有什么想法吗?
urls.py的相关部分是:
from django.conf.urls import url
from . import views
app_name = 'my_app'
urlpatterns = [
url(r'^(?P<slug>[A-Z]+)/data/$', views.MainView.as_view(), name='main-view',),
...
]