Django Inclusion Tag不会发布到数据库

时间:2015-06-28 17:33:06

标签: python django inclusion

我正在尝试构建一个表单,以便将名称和电子邮件地址保存到我的数据库中。但是,它不能保存...... 我使用了包含标记,因为我想在不同的模板中使用相同的表单。 这是我的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()}

在我填写并提交表单后,我在数据库中看不到任何内容。我错过了什么吗? 谢谢!

3 个答案:

答案 0 :(得分:0)

Post是一种由视图处理的服务器请求方法。

包含标记与页面一起呈现(即在服务器响应期间)。因此,如果您没有故意将POST作为上下文变量发送到页面,那么页面上下文无法获得request.POST - 但它不会是request.POST - 只是some_variable)。它看起来有点奇怪..

答案 1 :(得分:0)

您必须在视图函数中处理表单处理。

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 })

我从来没有在包含标签中看到任何表单处理,我怀疑这会有效。上面的视图功能可能会指向正确的方向。

答案 2 :(得分:0)

  

我使用了包含标记,因为我想在其中使用相同的表单   不同的模板。

您可以简单地重复使用表单 - 或者在这种情况下您的表单非常简单,您可以使用IntSupplier并进一步减少代码。

您的观点仅包含以下内容:

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(r'^another-form/$', OfferForm.as_view(), name='another-form')

最后,__unicode__方法应该返回一个unicode对象;所以在你的模型中:

def __unicode__(self):
    return u"{} {}".format(self.first_name, self.last_name)

您尝试这样做的方式不起作用,因为模板标记代码将在呈现模板之前执行;因此,当用户看到表单时,您的标记代码已经完成。没有办法再次“触发”它;这就是为什么你需要一个传统的视图方法来接受输入到表单中的数据。