Я хочу добавить поле «expiry_date» в DjangoModelFactory, чтобы оно соответствовало связанной модели.
Вот моя реализация:
модели.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]
)
фабрики.ру
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». Тем не менее, я получаю переведенное сообщение об ошибке формы, в котором говорится, что я должен указать правильную дату и время. Это сообщение об ошибке не исходит от пользовательского валидатора, который я добавил для этого поля.
вот определение формы, для полноты:
формы.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
.
Похоже, что объект datetime должен использовать локализованный формат, но не может этого сделать.
Когда я запускаю сервер, поле даты и времени использует локализованный формат.
Так что это не проблема конфигурации на уровне формы.
Любое понимание ценится и спасибо за ваше время.
Обновлено:
вывод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']
Подробнее здесь: документы
Тогда я не понимаю, почему у меня правильный локализованный формат при запуске сервера. Я не указал какой-либо формат, и Django использовал для меня локализованный формат. Только в контексте интегрированных тестов формат не настроен должным образом. Обновлено: я получаю TypeError с ключевым словом «input_formats».
Наконец-то я решил использовать другой подход и просто передать целое число, представляющее смещение в днях.
Спасибо @Ramy Mohamed за его понимание.
Я пытался отправить объект datetime как есть. Поскольку виджет отображается как текстовый ввод, сервер получит строку, а не объект даты и времени после запроса 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)
Можете ли вы распечатать содержимое
offer
, прежде чем отправить его в форму?