У меня есть форма django с полем, направленным на чужой ключ. Изначально пусто, я имею в виду без какой-либо опции. Javascript добавит параметры, основанные на другом поле формы.
Это работает, но я хочу протестировать его, не используя Selenium (и так, без использования javascript).
После многочисленных попыток Я пишу этот код, и, очевидно, он работает, но я не знаю почему, и я не уверен, что он действительно работает.
def test_form_validation(self):
maschio = Gender.objects.create(name_en='Male', name_it='Maschio')
nome = NameType.objects.create(name_en='Name', name_it='Nome')
romani = NameLanguage.objects.create(
name_en='Romans', name_it='Romani')
romani.syntax.add(nome)
form = NameForm({'nametype': nome.id, 'gender': maschio.id,
'name': 'Remo', 'namelanguage': romani.id})
# print('1', form)
form.fields['nametype'].initial = nome.id
print('2', form)
form.save()
self.assertEqual(Name.objects.all().count(), 1)
my_name = Name.objects.first()
self.assertEqual(my_name.name, 'remo')
self.assertEqual(my_name.nametype, nome)
self.assertEqual(my_name.gender, maschio)
self.assertEqual(my_name.namelanguage, romani)
print('end of test')
# print('1', form)
закомментирован, потому что с этим тестом будет даношибка в строке form.save()
(ValueError: The Name could not be created because the data didn't validate.
). Без этой строки тестовый проход (!?!).
Я ожидаю ошибки при вызове моей формы с ограничениями, потому что nametype
не имеет выбора. nome.id не является одним из допустимых вариантов. И в действительности, как я уже сказал, будет выдано сообщение об ошибке, если я попрошу распечатать форму.
<tr><th><label for="id_nametype">Tipo:</label></th><td><select name="nametype" style="width:170px" disabled id="id_nametype">
<option value="0">0</option>
</select></td></tr>
Итак, это нормально? а почему работает? что происходит?
Спасибо
Редактировать
Мой form.py
:
class NameForm(forms.ModelForm):
"""
form to add names to the database
input: nothing
output: the form
"""
class Meta:
model = Name
fields = ['namelanguage', 'nametype', 'gender', 'name']
widgets = {
'gender': forms.RadioSelect(),
}
def clean_name(self):
data = self.cleaned_data['name'].lower()
if data[0] not in "abcdefghijklmnopqrstuvwxyz":
data = "#" + data
return data
def __init__(self, *args, **kwargs):
try:
last_language = kwargs.get('initial')['namelanguage']
last_nametype = kwargs.get('initial')['nametype']
choices = get_nametype_choices(last_language)
gender_variable = get_gender_variable(last_nametype)
except (TypeError, KeyError):
print('except nameform')
choices = [(0, 0)]
gender_variable = True
super(NameForm, self).__init__(*args, **kwargs)
self.fields['name'].widget.attrs.update({'autofocus': ''})
self.fields['nametype'].widget.attrs.update({'style': 'width:170px'})
self.fields['nametype'].choices = choices
if choices[0][0] == 0:
self.fields['nametype'].disabled = True
if not gender_variable:
print('gender non variable')
self.fields['gender'].disabled = True
self.fields['gender'].required = False
try:
self.fields['gender'].initial = Gender.objects.get(
name_it='neutro').id
except ObjectDoesNotExist:
self.fields['gender'].initial = None
else:
self.fields['gender'].disabled = False
self.fields['gender'].required = True
def get_nametype_choices(last_language):
"""
function called by NameForm__init__ to create the list of choices
for nametype according to the language
input: language
output: a list of tuple with the appropriate nametype for the language
"""
# print('get_nametype_choices')
lista_file = []
try:
language = NameLanguage.objects.get(id=last_language)
choices = language.syntax.all()
for choice in choices:
lista_file.append((choice.id, choice))
except ObjectDoesNotExist:
print('except get_nametype_choices')
lista_file.append((0, 'Scegli il linguaggio'))
return lista_file
get_nametype_choices
не вызывается тестом, потому что last_language = kwargs.get('initial')['namelanguage']
в NameForm.__init__
дает исключение.