python 更改电子邮件时禁止 Django 403
python Django 403 forbidden when changing email
我想使用标准 Django 方法更改用户电子邮件,但在更改电子邮件之前,来自表单和数据库的密码必须匹配。我收到 403 错误 CSRF token missing or incorrect.
这是我的 form
:
class ChangeMailForm(forms.Form):
password = forms.CharField(label = (u'Podaj hasło'), widget=forms.PasswordInput(render_value=False))
email = forms.EmailField(label = (u'Podaj nowy adres email'))
def clean_email(self):
mail = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError("Taki email jest w bazie")
return mail
我的view
:
def ChangeEmail(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/')
if request.method == 'POST':
form = ChangeMailForm(request.POST)
if form.is_valid():
usr = request.user
u = User.objects.filter(username=usr)
if not User.objects.filter(username=usr).check_password(form.cleaned_data['password']):
return HttpResponseRedirect('/')
mail = form.cleaned_data['email']
u.new_email(mail)
u.save()
else:
return render_to_response('changeemail.html', {'form':form},context_instance=RequestContext(request))
else:
form = ChangeMailForm()
return render_to_response('changeemail.html', {'form':form}, context_instance=RequestContext(request))
和我的一部分 template
:
<form action="" method="post">
{% csrf_token %}
{% if form.errors %}<p id="correct">Popraw następujące pola:</p>{% endif %}
<table id="change">
<tr>
<td {% if form.password.errors %} class="error" {% endif %}>Podaj hasło:</td>
<td>{{ form.password }}</td>
</tr>
<tr>
<td {% if form.email.errors %} class="error" {% endif %}>Podaj nowy adres:</td>
<td>{{ form.email }}</td>
</tr>
</table>
<div id="sub">
<input type="submit" value="Wykonaj" alt="login" id="submit" />
任何帮助将不胜感激。
编辑:在放置@csrf_exempt装饰器
后添加回溯
Request Method: POST
Request URL: http://127.0.0.1:8000/changeemail/
Django Version: 1.7.1
Python Version: 2.7.8
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'dailyresults',
'trainingresults',
'athlete',
'easy_pdf')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "D:\Programy\Python27\lib\site-packages\django-1.7.1-py2.7.egg\django\core\handlers\base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\Programy\Python27\lib\site-packages\django-1.7.1-py2.7.egg\django\views\decorators\csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "D:\Inz\trening\athlete\views.py" in ChangeEmail
93. if not User .objects.filter(username=usr).check_password(form.cleaned_data['password']):
异常类型:/changeemail/ 的 AttributeError
异常值:'QuerySet' 对象没有属性 'check_password'
您需要更改此行:
u = User.objects.filter(username=usr)
if not User.objects.filter(username=usr).check_password(...):
对此:
u = User.objects.filter(username=usr).first()
if u and u.check_password(...):
...
为什么它会在第一种方法中抛出错误,因为 u
是 list 中的查询集,它本身没有 check_password
方法。但是您可以使用 queryset().first()
或切片 u[0]
访问 User 对象 并获得 User 对象(当然您需要验证是否存在,否则将是 []).
并且请确保 csrf_token
确实存在于您的请求中,您可以使用 logging 并检查:
import logging
...
#your view
logging.info('request MEAT for csrf: %s', request.META.get('CSRF_COOKIE'))
看看它是否存在。
您也可以尝试清除浏览器缓存,或使用其他浏览器(新会话或私人会话)进行测试,看看是否仍然出现错误。
已更新
当需要更新email字段时,使用普通模型save方法即可:
# above code... and being verified ...
u.email = form.cleaned_data['email']
u.save()
就是这样。
我想使用标准 Django 方法更改用户电子邮件,但在更改电子邮件之前,来自表单和数据库的密码必须匹配。我收到 403 错误 CSRF token missing or incorrect.
这是我的 form
:
class ChangeMailForm(forms.Form):
password = forms.CharField(label = (u'Podaj hasło'), widget=forms.PasswordInput(render_value=False))
email = forms.EmailField(label = (u'Podaj nowy adres email'))
def clean_email(self):
mail = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError("Taki email jest w bazie")
return mail
我的view
:
def ChangeEmail(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/')
if request.method == 'POST':
form = ChangeMailForm(request.POST)
if form.is_valid():
usr = request.user
u = User.objects.filter(username=usr)
if not User.objects.filter(username=usr).check_password(form.cleaned_data['password']):
return HttpResponseRedirect('/')
mail = form.cleaned_data['email']
u.new_email(mail)
u.save()
else:
return render_to_response('changeemail.html', {'form':form},context_instance=RequestContext(request))
else:
form = ChangeMailForm()
return render_to_response('changeemail.html', {'form':form}, context_instance=RequestContext(request))
和我的一部分 template
:
<form action="" method="post">
{% csrf_token %}
{% if form.errors %}<p id="correct">Popraw następujące pola:</p>{% endif %}
<table id="change">
<tr>
<td {% if form.password.errors %} class="error" {% endif %}>Podaj hasło:</td>
<td>{{ form.password }}</td>
</tr>
<tr>
<td {% if form.email.errors %} class="error" {% endif %}>Podaj nowy adres:</td>
<td>{{ form.email }}</td>
</tr>
</table>
<div id="sub">
<input type="submit" value="Wykonaj" alt="login" id="submit" />
任何帮助将不胜感激。
编辑:在放置@csrf_exempt装饰器
后添加回溯Request Method: POST
Request URL: http://127.0.0.1:8000/changeemail/
Django Version: 1.7.1
Python Version: 2.7.8
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'dailyresults',
'trainingresults',
'athlete',
'easy_pdf')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "D:\Programy\Python27\lib\site-packages\django-1.7.1-py2.7.egg\django\core\handlers\base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\Programy\Python27\lib\site-packages\django-1.7.1-py2.7.egg\django\views\decorators\csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "D:\Inz\trening\athlete\views.py" in ChangeEmail
93. if not User .objects.filter(username=usr).check_password(form.cleaned_data['password']):
异常类型:/changeemail/ 的 AttributeError 异常值:'QuerySet' 对象没有属性 'check_password'
您需要更改此行:
u = User.objects.filter(username=usr)
if not User.objects.filter(username=usr).check_password(...):
对此:
u = User.objects.filter(username=usr).first()
if u and u.check_password(...):
...
为什么它会在第一种方法中抛出错误,因为 u
是 list 中的查询集,它本身没有 check_password
方法。但是您可以使用 queryset().first()
或切片 u[0]
访问 User 对象 并获得 User 对象(当然您需要验证是否存在,否则将是 []).
并且请确保 csrf_token
确实存在于您的请求中,您可以使用 logging 并检查:
import logging
...
#your view
logging.info('request MEAT for csrf: %s', request.META.get('CSRF_COOKIE'))
看看它是否存在。
您也可以尝试清除浏览器缓存,或使用其他浏览器(新会话或私人会话)进行测试,看看是否仍然出现错误。
已更新
当需要更新email字段时,使用普通模型save方法即可:
# above code... and being verified ...
u.email = form.cleaned_data['email']
u.save()
就是这样。