我想在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_TZ
和USE_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)