Получать данные запроса в форме Django
Можно ли получить данные request.user в классе формы? Я хочу очистить адрес электронной почты, чтобы убедиться, что он уникален, но если это текущий адрес электронной почты пользователей, он должен пройти.
Это то, что у меня сейчас есть, который отлично подходит для создания новых пользователей, но если я хочу отредактировать пользователя, я столкнулся с проблемой не проверять их электронную почту, потому что это уже принято. Если бы я мог проверить, что это их электронная почта, используя request.user.email, тогда я смогу решить свою проблему, но я не уверен, как это сделать.
class editUserForm(forms.Form):
email_address = forms.EmailField(widget=forms.TextInput(attrs={'class':'required'}))
def clean_email_address(self):
this_email = self.cleaned_data['email_address']
test = UserProfiles.objects.filter(email = this_email)
if len(test)>0:
raise ValidationError("A user with that email already exists.")
else:
return this_email
Ответы
Ответ 1
Как указывали ars и Diarmuid, вы можете передать request.user
в свою форму и использовать ее при проверке электронной почты. Однако код Diarmuid ошибочен. Код должен действительно читать:
from django import forms
class UserForm(forms.Form):
email_address = forms.EmailField(widget = forms.TextInput(attrs = {'class':'required'}))
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(UserForm, self).__init__(*args, **kwargs)
def clean_email_address(self):
email = self.cleaned_data.get('email_address')
if self.user and self.user.email == email:
return email
if UserProfile.objects.filter(email=email).count():
raise forms.ValidationError(u'That email address already exists.')
return email
Затем, на ваш взгляд, вы можете использовать его так:
def someview(request):
if request.method == 'POST':
form = UserForm(request.POST, user=request.user)
if form.is_valid():
# Do something with the data
pass
else:
form = UserForm(user=request.user)
# Rest of your view follows
Обратите внимание, что вы должны передать request.POST в качестве аргумента ключевого слова, так как ваш конструктор ожидает "пользователь" в качестве первого позиционного аргумента.
Выполняя этот путь, вам нужно передать user
в качестве аргумента ключевого слова. Вы можете передать request.POST
в качестве позиционного аргумента или аргумент ключевого слова (через data=request.POST
).
Ответ 2
Здесь вы можете получить пользователя в своей форме при использовании общих представлений:
В представлении передайте request.user
в форму с помощью get_form_kwargs
:
class SampleView( View ):
def get_form_kwargs( self ):
kwargs = super( SampleView, self ).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
В форме вы получите user
с помощью функции __init__
:
class SampleForm( Form ):
def __init__( self, user, *args, **kwargs ):
super( SampleForm, self ).__init__( *args, **kwargs )
self.user = user
Ответ 3
Как вы знаете, с Django 1.4 и Generic на основе класса CreateView и UpdateView, self.instance заносится в каждую модельную форму, что позволяет сравнить электронную почту POSTed и текущую электронную почту пользователя.
Вот пример кода, используя mixin
class EmailUniqueMixin(object):
"""
Ensure each User email is unique
on the form level
"""
def clean_email(self):
email = self.cleaned_data['email']
existing_email = User.objects.filter(email=email).exclude(pk=self.instance.id)
if existing_email:
raise forms.ValidationError('That email address already exists')
else:
return email
Ответ 4
Не то, чтобы я знал. Один из способов справиться с этим заключается в том, что ваш класс формы __init__
принимает необязательный параметр электронной почты, который он может хранить как атрибут. Если он указан во время создания формы, он может использовать это во время проверки для интересующего вас сравнения.