单元测试 django 内联表单集

     2023-02-24     42

关键词:

【中文标题】单元测试 django 内联表单集【英文标题】:Unit testing django inline formsets 【发布时间】:2012-03-20 04:20:24 【问题描述】:

在尝试通过内联表单集以编程方式发布新的 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'' 帖子项。我尝试过使用和不使用 unicode,使用 0 或 -1,使用 False,使用 'new'(我知道这是一个完整的狂野镜头)。

我的主要困惑在于表单在我运行服务器时有效。我在提交表单时检查了 POST 变量,该 id 字段可以为空,并且项目添加就好了。

为什么表单在通过测试运行程序提交时会停止?

【问题讨论】:

【参考方案1】:

内联表单集中的初始表单需要绑定到数据库中的现有模型。您的设置不会创建相关的ChosenTrait 实例(这是您应该用于merit-0-id 的pk)。如果您正在测试创建所有新模型,那么 'merit-INITIAL_FORMS' 应该是 0

【讨论】:

【参考方案2】:

空字段与带有空字符串的字段不同。

如果某个字段为空,则浏览器根本不会将其包含在查询字符串中。但是,您已经模拟了一个包含空字符串的字段的 POST,这使事情变得混乱。从字典中完全删除该键。

【讨论】:

是的,我想知道这一点。不幸的是,如果我删除它,我会收到 MultiValueDictKeyError,因为它正在查找字典中的“merit-0-id”字段。

带有内联表单集的 Django 表单验证

】带有内联表单集的Django表单验证【英文标题】:Djangoformvalidationwithinlineformsets【发布时间】:2011-09-1714:40:57【问题描述】:我在一个HTML页面上有一个主表单和三个内联forset,目的是为客户创建Estimates。“主”表单的主键用作所... 查看详情

Django - 更改内联表单集 textInput 大小属性

】Django-更改内联表单集textInput大小属性【英文标题】:Django-ChanginginlineformsettextInputsizeattribute【发布时间】:2012-11-1617:41:29【问题描述】:我有一个只有三个字段的内联表单集:classEstimate_Product_Details(models.Model):proposalID=models.Fore... 查看详情

如何在 Django 的表单中拥有嵌套的内联表单集?

】如何在Django的表单中拥有嵌套的内联表单集?【英文标题】:HowtohaveanestedinlineformsetwithinaforminDjango?【发布时间】:2011-07-2723:47:00【问题描述】:我希望这个问题还没有被问到,但我想知道是否有可能为对象提供一个基于类的... 查看详情

django 内联表单集的单选按钮

】django内联表单集的单选按钮【英文标题】:Radiobuttonfordjangoinlineformset【发布时间】:2014-11-0401:58:21【问题描述】:我需要的是下面给定表单集中每个表单的单选按钮。classAppvideoDemoForm(forms.ModelForm):classMeta:model=AppvideoDemodef__init__... 查看详情

Django 内联表单集将始终创建新对象而不是更新它们

】Django内联表单集将始终创建新对象而不是更新它们【英文标题】:Djangoinlineformsetwillalwayscreatenewobjectinsteadofupdatethem【发布时间】:2020-09-1702:11:24【问题描述】:我有两个模型First和Second,FK从Second到First。我为2类创建了一个表... 查看详情

Django内联表单集:内联外键与父实例主键不匹配

】Django内联表单集:内联外键与父实例主键不匹配【英文标题】:Djangoinlineformset:Theinlineforeignkeydidnotmatchtheparentinstanceprimarykey【发布时间】:2014-11-1508:13:07【问题描述】:似乎有很多关于这个主题的问题,但我找不到任何可以为... 查看详情

用户同时编辑时,Django 内联表单集抛出 IndexError

】用户同时编辑时,Django内联表单集抛出IndexError【英文标题】:DjangoinlineformsetthrowsIndexErrorwhenusersareconcurrentlyediting【发布时间】:2011-07-1005:17:15【问题描述】:更新:我现在认为这是Django中的一个现有错误,报告为Ticket14642这让... 查看详情

Django Crispy 表单 - 更新视图的内联表单集“ManagementForm 数据”错误

】DjangoCrispy表单-更新视图的内联表单集“ManagementForm数据”错误【英文标题】:DjangoCrispyforms-inlineFormsets\'ManagementFormdata\'errorwithupdateview【发布时间】:2019-04-2202:53:17【问题描述】:晚上好,我在使用脆的表格inlineformset时遇到了... 查看详情

Django - 带有内联表单集的 UpdateView 试图保存重复记录?

】Django-带有内联表单集的UpdateView试图保存重复记录?【英文标题】:Django-UpdateViewwithinlineformsetstryingtosaveduplicaterecords?【发布时间】:2015-12-1102:07:16【问题描述】:我有一个Expense模型和一个ExpenseLineItem模型。就像典型的费用/发... 查看详情

将查询集传递给 django 内联表单中的外键字段

】将查询集传递给django内联表单中的外键字段【英文标题】:Passingquerysettoforeignkeyfieldindjangoinlineform【发布时间】:2013-11-2023:26:49【问题描述】:我遇到了一个小问题,我认为这很常见。这是描述的非常笼统的问题:classOwnable(mod... 查看详情

Django内联表单集通过另一个模型在多对多关系中过滤

】Django内联表单集通过另一个模型在多对多关系中过滤【英文标题】:Djangoinlineformsetfiltersinmanytomanyrelationshipthroughanothermodel【发布时间】:2013-04-2706:36:13【问题描述】:我有两个模型SchoolClass和Student,它们通过Enrollment模型具有... 查看详情

动态添加行到内联表单集未反映在 django 中 views.py 的发布请求中

】动态添加行到内联表单集未反映在django中views.py的发布请求中【英文标题】:dynamicallyaddedrowtoinlineformsetnotreflectedinthepostrequestinviews.pyindjango【发布时间】:2016-01-1413:45:43【问题描述】:我正在尝试使用帖子中提到的步骤将动态... 查看详情

Django 中的内联表单验证

】Django中的内联表单验证【英文标题】:InlineFormValidationinDjango【发布时间】:2010-10-2700:53:15【问题描述】:我想在管理员更改表单中强制设置整个内联表单集。因此,在我当前的情况下,当我在发票表单(在管理员中)上点击... 查看详情

Django:如何更改内联表单集中的字段小部件

】Django:如何更改内联表单集中的字段小部件【英文标题】:Django:HowtochangeafieldwidgetinaInlineFormset【发布时间】:2012-08-1618:58:30【问题描述】:我是Django新手,我认为我在文档中遗漏了这一点。问题是在inline-formset中我没有声明一... 查看详情

在模板中访问内联表单集的父级?

...时间】:2018-11-2413:44:45【问题描述】:我想知道如何访问Django中设置的内联表单的父级。这是我目前正在做的事情:views.pydefupload(request):[CodeOmmitted]formSet=inlineformset_factory(Tombstone,Tank 查看详情

最初在 django 内联表单集中设置不同的外键值

】最初在django内联表单集中设置不同的外键值【英文标题】:Setdifferentforeignkeyvalueindjangoinlineformsetinitially【发布时间】:2020-06-2510:18:11【问题描述】:我正在尝试使用django制作结果管理系统。为了存储主题标记,我使用的是django... 查看详情

Django:正确显示表单集错误

】Django:正确显示表单集错误【英文标题】:Django:Displayingformseterrorscorrectly【发布时间】:2011-01-1112:03:32【问题描述】:我有一个模型的内联表单集,它有一个unique_together约束。因此,当我输入不满足此约束的数据时,它会显示... 查看详情

Django:将字段添加到模型表单集

】Django:将字段添加到模型表单集【英文标题】:Django:Addfieldtomodelformset【发布时间】:2011-06-1107:04:01【问题描述】:我可以向模型表单集添加字段吗?如果您使用普通表单集但不能使用模型表单集,您似乎可以添加字段(至少... 查看详情