Модульное тестирование встроенных форм Django - PullRequest
9 голосов
/ 01 марта 2012

При попытке программно опубликовать новый объект ForeignKey через встроенный набор форм, я получаю сообщение об ошибке: ValueError: invalid literal for int() with base 10: ''.

Вот код моего теста (раздутый ради краткости здесь):

def test_merits_can_be_added(self):
    self.c = Client()
    self.c.login(username=self.user.username, password='dummy')
    self.post_data = {
      'name':u'Unhappy SE',
      'concept':u'Sad clown',
      'merit-TOTAL_FORMS':u'1',
      'merit-MAX_NUM_FORMS':u'',
      'merit-INITIAL_FORMS':u'1',
      'merit-0-id':u'',
      'merit-0-level':u'2',
      'merit-0-character':u'1',
      'merit-0-trait':u'11',
      'merit-0-specializations':u'Sometimes'
    }
    sheet = GeistCharacterSheet.objects.create(name='Happy SE', user=self.user)
    response = self.c.post(sheet.get_absolute_url(), self.post_data, follow=True)
    self.assertEqual(GeistCharacterSheet.objects.get(pk=1).chosentrait_set.all().filter(trait__name='Common Sense')[0].level, 2)
    self.assertEqual(GeistCharacterSheet.objects.get(pk=1).chosentrait_set.all().filter(trait__name='Common Sense')[0].specializations, u'Sometimes')

Код вида (опять же, для краткости обрезан):

def character_sheet(request, sheet_id=None):
  charsheet = GeistCharacterSheet.objects.get(pk=sheet_id, user=request.user)
  if request.method == 'POST':
    sheet_form = GeistCharacterSheetForm(request.POST, instance=charsheet)          
    merit_formset = setup_merit_form(charsheet, post=request.POST)

    if sheet_form.is_valid() and merit_formset.is_valid():
      sheet_form.save()
      merit_formset.save()
      return redirect('/character-manager/list/')

def setup_merit_form(charsheet, post=None):
  MeritFormSet = inlineformset_factory(GeistCharacterSheet, ChosenTrait, form=ChosenMeritForm, extra=1)
  if post:
    return MeritFormSet(post, instance=charsheet, queryset=ChosenTrait.objects.filter(trait__trait_type__name='Merit'), prefix='merit')
  else:
    return MeritFormSet(instance=charsheet, queryset=ChosenTrait.objects.filter(trait__trait_type__name='Merit'), prefix='merit')

Вот обратная связь с выполнением теста:

Traceback (most recent call last):
  File "C:\charon_sheet\..\charon_sheet\character_manager\tests.py", line 119, in test_skills_can_be_changed
    response = self.c.post(sheet.get_absolute_url(), self.post_data, follow=True)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\test\client.py", line 449, in post
    response = super(Client, self).post(path, data=data, content_type=content_type, **extra)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\test\client.py", line 259, in post
    return self.request(**r)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\core\handlers\base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "C:\charon_sheet\..\charon_sheet\character_manager\views.py", line 29, in character_sheet
    merit_formset = setup_merit_form(charsheet, post=request.POST)
  File "C:\charon_sheet\..\charon_sheet\character_manager\views.py", line 69, in setup_merit_form
    return MeritFormSet(post, instance=charsheet, queryset=ChosenTrait.objects.filter(trait__trait_type__name='Merit'), prefix='merit')
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\forms\models.py", line 682, in __init__
    queryset=qs)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\forms\models.py", line 415, in __init__
    super(BaseModelFormSet, self).__init__(**defaults)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\forms\formsets.py", line 47, in __init__
    self._construct_forms()
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\forms\formsets.py", line 108, in _construct_forms
    self.forms.append(self._construct_form(i))
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\forms\models.py", line 691, in _construct_form
    form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\forms\models.py", line 437, in _construct_form
    connection=connections[self.get_queryset().db])
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\db\models\fields\subclassing.py", line 53, in inner
    return func(*args, **kwargs)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\db\models\fields\subclassing.py", line 53, in inner
    return func(*args, **kwargs)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\db\models\fields\__init__.py", line 306, in get_db_prep_lookup
    value = self.get_prep_lookup(lookup_type, value)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\db\models\fields\__init__.py", line 292, in get_prep_lookup
    return self.get_prep_value(value)
  File "C:\Program Files\BitNami DjangoStack\apps\django\django\db\models\fields\__init__.py", line 479, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: ''

Я могу публиковать модели, формы, больше представления, что бы кто-нибудь ни подумал, было бы полезно.

Проблема связана с постом 'merit-0-id':u''.Я пробовал с юникодом и без него, используя 0 или -1, используя False, используя 'new' (я знаю, полный джокер).

Моя главная путаница заключается в том, что форма работает, когдаЯ запускаю сервер.Я проверял POST-переменные при отправке формы, и это поле id может быть пустым, а элемент добавляется просто отлично.

Почему форма блокируется, когда она отправляется через тестовый запуск?

Ответы [ 2 ]

8 голосов
/ 01 марта 2012

Начальные формы во встроенном наборе форм должны быть привязаны к существующим моделям в БД. Ваша установка не создает связанный экземпляр ChosenTrait (который вы должны использовать для merit-0-id). Если вы тестируете создание всех новых моделей, то 'merit-INITIAL_FORMS' должно быть 0.

0 голосов
/ 01 марта 2012

Пустое поле отличается от поля с пустой строкой.

Если поле пустое, браузер вообще не включает его в строку запроса.Тем не менее, вы смоделировали POST с этим полем, содержащим пустую строку, которая путает вещи.Удалите этот ключ полностью из диктата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...