2012-03-01 9 views
9

Al intentar publicar un nuevo objeto ForeignKey mediante programación a través de un formset en línea, recibo un error: ValueError: invalid literal for int() with base 10: ''.Pruebas unitarias de conjuntos de formularios en línea django

Aquí está el código de mi prueba (distendido en aras de la brevedad aquí):

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') 

El código de la vista (de nuevo, recortado por razones de brevedad):

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') 

Aquí está el rastreo de la ejecución de la prueba:

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: '' 

puedo publicar modelos, formas, más de la vista, todo lo que alguien piensa que b e útil.

El problema es con el elemento de publicación 'merit-0-id':u''. Lo he intentado con y sin unicode, usando 0 o -1, usando False, usando 'new' (un tiro completo, lo sé).

Mi mayor confusión viene en que el formulario funciona cuando estoy ejecutando el servidor. He examinado las variables POST cuando envío el formulario, y ese campo de identificación puede estar vacío y el elemento se agrega muy bien.

¿Por qué la forma se detiene cuando se envía a través de un corredor de prueba?

Respuesta

8

Los formularios iniciales en un formset en línea deben vincularse a los modelos existentes en el DB. Su configuración no crea la instancia relacionada ChosenTrait (que es el pk que debería usar para merit-0-id). Si está probando la creación de todos los modelos nuevos, entonces 'merit-INITIAL_FORMS' debe ser 0.

+0

¡Eso fue todo! ¡Gracias! –

0

Un campo vacío no es lo mismo que uno con una cadena vacía.

Si un campo está vacío, el navegador no lo incluye en la cadena de consulta. Sin embargo, has simulado un POST con ese campo que contiene una cadena vacía, lo que confunde las cosas. Quita esa llave por completo del dict.

+0

Sí, me pregunté sobre eso. Desafortunadamente, si lo elimino, obtengo un MultiValueDictKeyError porque está buscando el campo 'merit-0-id' en el dict. –

Cuestiones relacionadas