I want to add an "expiry_date" field to a DjangoModelFactory, to match its related model.
Here is my implementation :
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
)
This test should only return two error messages, both from failed validation constraints on the 'price' and 'item_count' fields. Yet I get a translated form error message saying that I should provide a valid date and time. This error message does not originate from the custom validator I have added for this field.
here is the form's definition, for the sake of completeness :
forms.py
class OfferForm(forms.ModelForm):
[...]
class Meta:
model = Offer
fields = (
[...]
'expiry_date'
widgets = {
[...]
'expiry_date': forms.DateTimeInput(
attrs={'class': 'form-control', }
)
}
I have USE_TZ
and USE_L10N
enabled.
It looks like the datetime object should use a localized format but fails to do so.
When I run the server, the datetime field uses the localized format.
So this isn't a configuration issue at the form level.
Any insight is appreciated and thank you for your time.
EDIT:
output of 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>)}
In django, widgets
are responsible for rendering the view. so you might expect that rendering a non-formatted DateTimeInput
cause this unexpected behavior.
Try doing this:
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'
)
}
Also add your desired format to your model field supported formats
input_formats = ['list-of-desired-formats']
For more details here: docs