Ответ 1
Вы можете использовать
form.data['field_name']
Таким образом вы получите исходное значение, присвоенное полю.
Когда у меня есть действительная форма Django, я могу получить доступ к данным с помощью form.cleaned_data. Но как я могу получить данные, введенные пользователем, когда форма недействительна, т.е. Form.is_valid является ложным.
Я пытаюсь получить доступ к формам в наборе форм, поэтому form.data, похоже, просто путает меня.
Вы можете использовать
form.data['field_name']
Таким образом вы получите исходное значение, присвоенное полю.
См. http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation
Во-вторых, как только мы решили, что комбинированные данные в двух полях мы считаются недействительными, мы должны не забудьте удалить их из cleaned_data.
Фактически, Django в настоящее время полностью уничтожить очищенные_данные если есть какие-либо ошибки в форма. Однако это поведение может изменения в будущем, так что это не плохая идея очистить после себя в на первом месте.
Исходные данные всегда доступны в request.POST
.
В комментарии говорится, что дело в том, чтобы сделать что-то похожее на более сложную проверку на уровне поля.
Каждому полю присваиваются неутвержденные данные и либо возвращает действительные данные, либо вызывает исключение.
В каждом поле может быть сделана любая проверка на исходное содержимое.
Я боролся с подобной проблемой и наткнулся на отличную дискуссию здесь: https://code.djangoproject.com/ticket/10427
Это не совсем хорошо документировано, но для живой формы вы можете просмотреть значение поля - как видно из виджетов/пользователей - со следующим:
form_name['field_name'].value()
Вы можете использовать этот шаблон:
class MyForm(forms.Form):
...
def clean(self):
self.saved_data=self.cleaned_data
return self.cleaned_data
В вашем коде:
if form.is_valid():
form.save()
return django.http.HttpResponseRedirect(...)
if form.is_bound:
form.saved_data['....'] # cleaned_data does not exist any more, but saved_data does.
Использование form.data не является хорошим решением. Причины:
У меня много методов. Все, что вы можете выбрать.
Я предполагаю, что форма выглядит следующим образом:
class SignupForm(forms.Form):
email = forms.CharField(label='email')
password = forms.CharField(label='password',
widget=forms.PasswordInput)
1-1. Получите от request
def signup(req):
if req.method == 'POST':
email = req.POST.get('email', '')
password = req.POST.get('password', '')
2-1. Получите raw value
, назначенный этому полю, и верните значение атрибута data
поля
def signup(req):
if req.method == 'POST':
...
sf = SignupForm(req.POST)
email = sf["email"].data
password = sf["password"].data
...
2-2. Получите исходное значение, присвоенное полю, и верните значение атрибута value
поля
def signup(req):
if req.method == 'POST':
...
sf = SignupForm(req.POST)
email = sf["email"].value()
password = sf["password"].value()
...
2-3. Получите dictionary
, присвоенный полям
def signup(req):
if req.method == 'POST':
...
sf = SignupForm(req.POST)
# print sf.data
# <QueryDict: {u'csrfmiddlewaretoken': [u'U0M9skekfcZiyk0DhlLVV1HssoLD6SGv'], u'password': [u''], u'email': [u'hello']}>
email = sf.data.get("email", '')
password = sf.data.get("password", '')
...
У меня возникла аналогичная проблема с использованием набора форм. В моем примере я хотел, чтобы пользователь выбирал первый вариант перед вторым выбором, но если первый выбор ударил еще одну ошибку, также была отображена ошибка "выбрать первый выбор до второй".
Чтобы захватить 1-ые нечистые данные поля, я использовал это в чистом методе поля формы:
dirty_rc1 = self.data[self.prefix + '-reg_choice_1']
Затем я мог проверить наличие данных в этом поле:
if not dirty_rc1:
raise ValidationError('Make a first choice before second')
Надеюсь, это поможет!
Вы получаете доступ к данным либо из метода clean() поля, либо из метода clean() формы. clean() - это функция, которая определяет, действительна ли форма или нет. Он вызывается, когда вызывается is_valid(). В форме clean() у вас есть список cleaned_data
, когда вы можете запускать собственный код, чтобы убедиться, что все его проверили. В виджете у вас также есть clean(), но он использует одну переданную переменную. Чтобы получить доступ к методу field clean(), вам придется подклассифицировать его. например:.
class BlankIntField(forms.IntegerField):
def clean(self, value):
if not value:
value = 0
return int(value)
Если вы хотите, чтобы IntField, который не задыхается от пустого значения, например, вы должны использовать вышеуказанное.
clean() в виде вида подобных работ:
def clean(self):
if self.cleaned_data.get('total',-1) <= 0.0:
raise forms.ValidationError("'Total must be positive")
return self.cleaned_data
Также вы можете иметь функцию clean_FIELD() для каждого поля, чтобы вы могли проверять каждое поле отдельно (после вызова поля clean())