Django 包含标签不会 post 到数据库
Django Inclusion Tag doesn't post to database
我正在尝试构建一个表单以将姓名和电子邮件地址保存到我的数据库中。然而,它并没有保存...
我使用了包含标签,因为我想在不同的模板中使用相同的表单。
这是我的 models.py:
class Contact(models.Model):
FRAU = 'FR'
HERR= 'HR'
GENDER_CHOICES = (
(FRAU, 'Frau'),
(HERR, 'Herr'),
)
gender = models.CharField(max_length=2, choices=GENDER_CHOICES, default=FRAU)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=200)
email = models.EmailField()
def __unicode__(self):
return "%s %s" %(self.first_name, self.last_name)
这是我的 forms.py:
class FragenContactForm(ModelForm):
class Meta:
model = Contact
fields = ['gender', 'first_name', 'last_name', 'email']
这是我的自定义标签模块:
from django import template
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from fragen.forms import FragenContactForm
register = template.Library()
@register.inclusion_tag('fragen/askforoffer.html', takes_context=True)
def askforoffer(context):
form = FragenContactForm(context['request'].POST or None)
if context['request'].method=='POST':
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('fragen/thanks.html'))
else:
messages.error(context['request'], "Error")
return {'form': FragenContactForm()}
填写并提交表格后,我在数据库中看不到任何内容。我错过了什么吗?
谢谢!
Post
是一种由视图处理的服务器请求方法。
包含标记与页面一起呈现(即在服务器响应期间)。因此页面上下文无法获得 request.POST
- 原因是,如果你不故意将 POST 作为上下文变量发送到页面(但它不会是 request.POST - 只是 some_variable).看起来有点奇怪..
您必须在视图函数中处理表单。
from django.shortcuts import redirect, render
from fragen.forms import FragenContactForm
def askforoffer(request):
form = FragenContactForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('specify_thank_url_here')
return render(request, 'fragen/askforoffer.html',
{ 'form': form })
我从未在包含标记中看到过任何表单处理,我怀疑这是否可行。以上视图功能可能会为您指明正确的方向。
I've used an Inclusion Tag because I want to use the same form in
different templates.
您可以简单地重用表单 - 或者由于您的表单在本例中非常简单,您可以使用 CreateView
generic class based view 并进一步减少代码。
您的视图将仅包含以下内容:
class OfferForm(CreateView):
template_name = 'fragen/askforoffer.html'
model = Contact
fields = ['gender', 'first_name', 'last_name', 'email']
success_url = 'fragen/thanks.html'
Django 会自动创建 ModelForm
,并为您处理错误重定向和保存字段。
在您的 fragen/askforoffer.html
模板中,您只需要:
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create" />
</form>
最后,在你的 urls.py
:
url(r'^submit-offer/$', OfferForm.as_view(), name='offer-form')
要在多个地方显示相同的表单,只需将其映射到一个 URL:
url(r'^another-form/$', OfferForm.as_view(), name='another-form')
最后,__unicode__
方法应该return一个unicode对象;所以在你的模型中:
def __unicode__(self):
return u"{} {}".format(self.first_name, self.last_name)
您尝试执行此操作的方式将不起作用,因为模板标记代码将在呈现模板之前执行;所以当用户看到表单时,您的标记代码已经完成。没办法再"trigger"了;这就是为什么您需要一个传统的视图方法来接受输入到表单中的数据。
我正在尝试构建一个表单以将姓名和电子邮件地址保存到我的数据库中。然而,它并没有保存... 我使用了包含标签,因为我想在不同的模板中使用相同的表单。 这是我的 models.py:
class Contact(models.Model):
FRAU = 'FR'
HERR= 'HR'
GENDER_CHOICES = (
(FRAU, 'Frau'),
(HERR, 'Herr'),
)
gender = models.CharField(max_length=2, choices=GENDER_CHOICES, default=FRAU)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=200)
email = models.EmailField()
def __unicode__(self):
return "%s %s" %(self.first_name, self.last_name)
这是我的 forms.py:
class FragenContactForm(ModelForm):
class Meta:
model = Contact
fields = ['gender', 'first_name', 'last_name', 'email']
这是我的自定义标签模块:
from django import template
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from fragen.forms import FragenContactForm
register = template.Library()
@register.inclusion_tag('fragen/askforoffer.html', takes_context=True)
def askforoffer(context):
form = FragenContactForm(context['request'].POST or None)
if context['request'].method=='POST':
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('fragen/thanks.html'))
else:
messages.error(context['request'], "Error")
return {'form': FragenContactForm()}
填写并提交表格后,我在数据库中看不到任何内容。我错过了什么吗? 谢谢!
Post
是一种由视图处理的服务器请求方法。
包含标记与页面一起呈现(即在服务器响应期间)。因此页面上下文无法获得 request.POST
- 原因是,如果你不故意将 POST 作为上下文变量发送到页面(但它不会是 request.POST - 只是 some_variable).看起来有点奇怪..
您必须在视图函数中处理表单。
from django.shortcuts import redirect, render
from fragen.forms import FragenContactForm
def askforoffer(request):
form = FragenContactForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('specify_thank_url_here')
return render(request, 'fragen/askforoffer.html',
{ 'form': form })
我从未在包含标记中看到过任何表单处理,我怀疑这是否可行。以上视图功能可能会为您指明正确的方向。
I've used an Inclusion Tag because I want to use the same form in different templates.
您可以简单地重用表单 - 或者由于您的表单在本例中非常简单,您可以使用 CreateView
generic class based view 并进一步减少代码。
您的视图将仅包含以下内容:
class OfferForm(CreateView):
template_name = 'fragen/askforoffer.html'
model = Contact
fields = ['gender', 'first_name', 'last_name', 'email']
success_url = 'fragen/thanks.html'
Django 会自动创建 ModelForm
,并为您处理错误重定向和保存字段。
在您的 fragen/askforoffer.html
模板中,您只需要:
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create" />
</form>
最后,在你的 urls.py
:
url(r'^submit-offer/$', OfferForm.as_view(), name='offer-form')
要在多个地方显示相同的表单,只需将其映射到一个 URL:
url(r'^another-form/$', OfferForm.as_view(), name='another-form')
最后,__unicode__
方法应该return一个unicode对象;所以在你的模型中:
def __unicode__(self):
return u"{} {}".format(self.first_name, self.last_name)
您尝试执行此操作的方式将不起作用,因为模板标记代码将在呈现模板之前执行;所以当用户看到表单时,您的标记代码已经完成。没办法再"trigger"了;这就是为什么您需要一个传统的视图方法来接受输入到表单中的数据。