DjangoModelFactory 中的日期时间字段会中断集成测试 (2.1)



我想在DjangoModelFactory中添加一个"expiry_date"字段,以匹配其相关模型。

这是我的实现:

models.py

def set_default_expiry_date():
return timezone.now() + datetime.timedelta(days=7)
[...]
expiry_date = models.DateTimeField(
verbose_name=_('Expiry date'),
default=set_default_expiry_date,
validators=[validate_expiry_date]
)

factories.py

class OfferFactory(factory.django.DjangoModelFactory):
[...]
expiry_date = factory.LazyFunction(set_default_expiry_date)

test_views.py

def test_POST_error_messages(self):
offer = factory.build(dict, FACTORY_CLASS=OfferFactory)
offer['price'] = 9999
offer['item_count'] = -123
self.client.force_login(self.company_user)
response = self.client.post(self.url, offer)
self.assertEqual(2, len(response.context['form'].errors))
self.assertTrue(
'price' and 'item_count' in response.context['form'].errors
)

此测试应仅返回两条错误消息,均来自"价格"和"item_count"字段的失败验证约束。 但是,我收到一条翻译表单错误消息,指出我应该提供有效的日期和时间。此错误消息并非源自我为此字段添加的自定义验证程序。

为了完整起见,以下是表单的定义:

forms.py

class OfferForm(forms.ModelForm):
[...]
class Meta:
model = Offer
fields = (
[...]
'expiry_date'
widgets = {
[...]
'expiry_date': forms.DateTimeInput(
attrs={'class': 'form-control', }
)
}

我启用了USE_TZUSE_L10N

看起来日期时间对象应该使用本地化格式,但未能这样做。

当我运行服务器时,日期时间字段使用本地化格式。

因此,这不是表单级别的配置问题。

任何见解都值得赞赏,并感谢您的时间。

编辑:

print(offer)输出

{'title': 'Back grow artist.', 'description': '...', 'price': 9999, 'item_count': -123, 'discount': 18, 'created_by': <CustomUser: TestCompany5>, 'expiry_date': datetime.datetime(2019, 4, 15, 13, 9, 52, 202191, tzinfo=<UTC>)}

在 django 中,widgets负责渲染视图。 因此,您可能认为呈现非格式化DateTimeInput会导致此意外行为。

尝试这样做:

class OfferForm(forms.ModelForm):
[...]
class Meta:
model = Offer
fields = (
[...]
'expiry_date'
widgets = {
[...]
'expiry_date': forms.DateTimeInput(
attrs={'type': 'datetime-local', 
'class': 'form-control', },
format='your-desired-format'
)
}

还可以将所需的格式添加到模型字段支持的格式

input_formats = ['list-of-desired-formats']

有关更多详细信息,请参阅:文档

我最终决定使用不同的方法,简单地传递一个表示以天为单位的偏移量的整数。
感谢@Ramy穆罕默德的见解。
我试图按原样发布日期时间对象。由于小部件呈现为文本输入,因此服务器将在 POST 请求后接收字符串而不是日期时间对象。
不过,我不需要按照他的回答中所示配置格式,因为他谈论的是日期时间的显示方式,而不是反馈给服务器。

这是我所做的工作:
test_views.py

locale_format = formats.get_format('DATETIME_INPUT_FORMATS', lang=translation.get_language())[0]
offer['expiry_date'] = offer['expiry_date'].strftime(locale_format)

相关内容

  • 没有找到相关文章