Поле Datetime в DjangoModelFactory нарушает интегрированные тесты (2.1) - PullRequest
3 голосов
/ 08 апреля 2019

Я хочу добавить поле "expiry_date" в DjangoModelFactory, чтобы соответствовать его связанной модели.

Вот моя реализация:

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
    )

Этот тест должен возвращать только две ошибкисообщения от неудачных проверочных ограничений в полях '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_TZ и USE_L10N.

Похоже, что объект datetime должен использовать локализованный формат, но не может это сделать.

КогдаЯ запускаю сервер, поле 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>)}

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Я, наконец, решил использовать другой подход и просто передать целое число, представляющее смещение в днях.
Спасибо @Ramy Mohamed за его понимание.
Я пытался POST-объект datetime как есть,Поскольку виджет отображается как текстовый ввод, сервер получит строку, а не объект 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)
0 голосов
/ 08 апреля 2019

В 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']

Для более подробной информации здесь: Документы

...