Django:CSRF 验证失败

0 投票
4 回答
1375 浏览
提问于 2025-04-17 00:21

我不知道该怎么解决这个问题 :/。

这是 views.py 的内容:

# coding: utf-8
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views.generic.simple import direct_to_template
from django.core.mail import send_mail
from django.template import Context, loader
from django.conf import settings
from sklep.models import Produkt
from sklep.forms import ZamowienieForm
from django.core.context_processors import csrf

def koszyk(request):
    koszyk = request.session.get('koszyk', [])
    produkty = list(Produkt.objects.filter(pk__in=koszyk))

    if request.method == 'POST':
        formularz = ZamowienieForm(request.POST)

        if formularz.is_valid():
            dane = formularz.cleaned_data
            tresc = loader.get_template('sklep/zamowienie.txt').render(Context({'produkty': produkty, 'dane': dane}))

            send_mail('Potwierdzenie zakupu', tresc, settings.EMAIL_SKLEPU, [dane['email']])
            send_mail(u'Zamówienie', tresc, dane['email'], [settings.EMAIL_SKLEPU])

            del request.session['koszyk']

            return HttpResponseRedirect(reverse('sklep_koszyk'))
    else:
        formularz = ZamowienieForm()

    if koszyk:
        kontekst = {'koszyk': produkty, 'formularz': formularz}
    else:
        kontekst = {'koszyk': []}

    return direct_to_template(request, 'sklep/koszyk.html', extra_context = kontekst)

def koszyk_dodaj(request, id_produktu):
    koszyk = request.session.get('koszyk', [])
    if int(id_produktu) not in koszyk:
        koszyk.append(int(id_produktu))
    request.session['koszyk'] = koszyk
    return HttpResponseRedirect(reverse('sklep_koszyk'))

这是 forms.py 的内容:

# coding: utf-8
from django import forms
from django.contrib.localflavor.pl.forms import PLPostalCodeField

class ZamowienieForm(forms.Form):
    email = forms.EmailField()
    imie_nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=60)
    adres = forms.CharField(max_length=100)
    kod_pocztowy = PLPostalCodeField()
    miasto = forms.CharField(max_length=60)
    uwagi = forms.CharField(widget=forms.Textarea, required=False)

4 个回答

0

另外,补充一下murgatroid99说的内容,当你调用那个页面的时候,需要包含csrf(request)。我通常会用locals().update(csrf(request))来更新一下,然后用locals()作为全局字典参数去调用那个页面。

0

Django在处理POST请求时,需要一个CSRF令牌来防止跨站请求伪造(CSRF)。这意味着你需要在你的表单模板中加入{% csrf_token %}。如果你知道自己在做什么,比如在进行API调用时,你也可以使用@csrf_exempt这个装饰器来跳过这个要求。

想了解更多相关信息,可以查看Django关于CSRF保护的文档

2

问题可能出在你的模板文件 sklep/koszyk.html 里。在这个 HTML 页面中的表单里,你需要加上 {% csrf_token %} 这一行代码。想了解更多关于这个功能的信息,可以查看 文档

撰写回答