【问题标题】:Python Django Forms to Add to Database要添加到数据库的 Python Django 表单
【发布时间】:2013-03-19 14:43:59
【问题描述】:

我正在尝试使用此表单添加到数据库中的表中。我目前收到错误“CSRF 验证失败。请求中止。”但我收到了其他错误,对此代码进行了不同的调整。如何让这段代码工作,编写这样的表单的最佳做法是什么?

models.py

from django.db import models
from django.contrib.auth.models import User

class Portfolio(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name

forms.py

from django import forms

class CreatePortfolio(forms.Form):
    name = forms.CharField(max_length=30)
    description = forms.CharField(max_length=100)

views.py

from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from portfolio.models import Portfolio
from portfolio.forms import CreatePortfolio

def portfolio(request):
    if request.method == 'POST':
        portfolio_form = CreatePortfolio(request.POST)
        if form.is_valid():
            csrf_token = django.middleware.csrf.get_token(request)
            port_name = form.cleaned_data['name']
            port_description = form.cleaned_data['description']
            port_user = request.user
            new_portfolio = Portfolio(name=port_name, description=port_description, user=port_user)
            new_portfolio.save()
            return render_to_response('portfolio.html', {'csrf_token': csrf_token})
    else:
        portfolio_form = CreatePortfolio()
    return render_to_response('portfolio.html', {'portfolio_form': portfolio_form})

portfolio.html

<form method="post" action="">
    {% csrf_token %}
    <div class="field">
        <label for="id_name">Name:</label>
            {{ portfolio_form.name}}
    </div>
    <div class="field">
        <label for="id_description">Description:</label>
        {{ portfolio_form.description }}
    </div>
    <input type="submit" value="Create">
</form>

【问题讨论】:

    标签: python django django-models django-forms django-views


    【解决方案1】:

    您不必显式发送 csrf_token。 Django 会为您处理好它。

    每次提交表单时,都会验证令牌,并为后续请求生成新令牌。在这里,您强制它使用相同的令牌,因此出现错误。

    您的视图应如下所示:

    def portfolio(request):
        if request.method == 'POST':
            portfolio_form = CreatePortfolio(request.POST)
            if form.is_valid():
                port_name = form.cleaned_data['name']
                port_description = form.cleaned_data['description']
                port_user = request.user
                new_portfolio = Portfolio(name=port_name, description=port_description, user=port_user)
                new_portfolio.save()
                return render_to_response('portfolio.html', {}, context_instance=RequestContext(request))
        else:
            portfolio_form = CreatePortfolio()
        return render_to_response('portfolio.html', {'portfolio_form': portfolio_form}, context_instance=RequestContext(request))
    

    【讨论】:

      【解决方案2】:

      问题是您没有在 render_to_response 中将 csrf 令牌添加到您的上下文中。

      使用 RequestContext 来呈现您的视图(在其上下文中自动包含 csrf),如下所示:

      from django.template import RequestContext
      
      def portfolio(request):
          # ... view code here
         return render_to_response("portfolio.html", {'portfolio_form': portfolio_form}, context_instance=RequestContext(request))
      

      或者像这样手动更新csrf:

      from django.core.context_processors import csrf
      from django.shortcuts import render_to_response
      
      def portfolio(request):
          # ... view code here
      
          c = {'portfolio_form': portfolio_form}
          c.update(csrf(request))
          return render_to_response("portfolio.html", c)
      

      查看更多参考资料

      https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-26
        • 2018-01-22
        • 1970-01-01
        • 2015-05-21
        相关资源
        最近更新 更多