DjangoModelFactory 中的日期时间字段破坏了集成测试 (2.1)

Datetime field in a DjangoModelFactory breaks integrated tests (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
    )

此测试应该只有 return 两条错误消息,均来自 'price' 和 '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']

更多详情请点击此处:docs

我最终决定使用不同的方法并简单地传递一个代表天数偏移量的整数。
感谢@Ramy Mohamed 的见解。
我试图按原样 POST 日期时间对象。由于小部件呈现为文本输入,服务器将在 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)