While testing routes of my django prodject, i got Type error: expected sting or bites like object. How i can fix this error?

huangapple go评论88阅读模式
英文:

While testing routes of my django prodject, i got Type error: expected sting or bites like object. How i can fix this error?

问题

我的博客上发布的新闻页面对任何用户都可用。我使用pytest检查页面是否对匿名用户可访问。
URL由新闻的ID组成,我将其传递给地址参数(作为元组)。

在结果中,我得到了这个类型错误。test_pages_availability[news:detail-news] - TypeError: 期望字符串或类似字节的对象

我尝试过将args格式化为字符串,为元组格式的参数添加逗号,但没有帮助。

测试代码

  1. @pytest.mark.django_db
  2. @pytest.mark.parametrize(
  3. 'name, args',
  4. (
  5. ('news:detail', pytest.lazy_fixture('news')),
  6. ('news:home', None),
  7. ('users:login', None),
  8. ('users:logout', None),
  9. ('users:signup', None),
  10. )
  11. )
  12. def test_pages_availability(client, name, args):
  13. if args is not None:
  14. url = reverse(name, args=(news.id,))
  15. else:
  16. url = reverse(name)
  17. response = client.get(url)
  18. assert response.status_code == HTTPStatus.OK

夹具

  1. @pytest.fixture
  2. def news():
  3. news = News.objects.create(
  4. title='新闻',
  5. text='令人惊奇的事件',
  6. date=datetime.today,
  7. )
  8. return news

类NewsDetail(generic.DetailView)的代码

  1. class NewsDetail(generic.DetailView):
  2. model = News
  3. template_name = 'news/detail.html'
  4. def get_object(self, queryset=None):
  5. obj = get_object_or_404(
  6. self.model.objects.prefetch_related('comment_set__author'),
  7. pk=self.kwargs['pk']
  8. )
  9. return obj
  10. def get_context_data(self, **kwargs):
  11. context = super().get_context_data(**kwargs)
  12. if self.request.user.is_authenticated:
  13. context['form'] = CommentForm()
  14. return context

回溯:

  1. request = <FixtureRequest for <Function test_pages_availability[news:detail-news]>>
  2. def fill(request):
  3. item = request._pyfuncitem
  4. fixturenames = getattr(item, "fixturenames", None)
  5. if fixturenames is None:
  6. fixturenames = request.fixturenames
  7. if hasattr(item, 'callspec'):
  8. for param, val in sorted_by_dependency(item.callspec.params, fixturenames):
  9. if val is not None and is_lazy_fixture(val):

> item.callspec.params[param] = request.getfixturevalue(val.name)
>
value = <built-in method today of type object at 0x00007FFE9CA83650>

  1. def parse_date(value):
  2. &quot;&quot;&quot;Parse a string and return a datetime.date.
  3. Raise ValueError if the input is well formatted but not a valid date.
  4. Return None if the input isn't well formatted.
  5. &quot;&quot;&quot;

> match = date_re.match(value)
E TypeError: expected string or bytes-like object

..\venv\lib\site-packages\django\utils\dateparse.py:75: TypeError

英文:

The page of the published news on my blog, is available to any user. I use pytest to check if the page is accessible to an anonymous user.
Url is formed by using the id of the news, which I pass in the address parameters (as a tuple).

In the result I got this Type error. test_pages_availability[news:detail-news] - TypeError: expected string or bytes-like object

I had tried to format args to str, puted a coma after arg for tuple format, it didn't helped

code of test

  1. @pytest.mark.django_db
  2. @pytest.mark.parametrize(
  3. &#39;name, args&#39;,
  4. (
  5. (&#39;news:detail&#39;, pytest.lazy_fixture(&#39;news&#39;)),
  6. (&#39;news:home&#39;, None),
  7. (&#39;users:login&#39;, None),
  8. (&#39;users:logout&#39;, None),
  9. (&#39;users:signup&#39;, None),
  10. )
  11. )
  12. def test_pages_availability(client, name, args):
  13. if args is not None:
  14. url = reverse(name, args=(news.id,))
  15. else:
  16. url = reverse(name)
  17. response = client.get(url)
  18. assert response.status_code == HTTPStatus.OK

`
fixture

  1. @pytest.fixture
  2. def news():
  3. news = News.objects.create(
  4. title=&#39;Новость&#39;,
  5. text=&#39;Невероятное событие&#39;,
  6. date=datetime.today,
  7. )
  8. return news
  1. class NewsDetail(generic.DetailView):
  2. model = News
  3. template_name = &#39;news/detail.html&#39;
  4. def get_object(self, queryset=None):
  5. obj = get_object_or_404(
  6. self.model.objects.prefetch_related(&#39;comment_set__author&#39;),
  7. pk=self.kwargs[&#39;pk&#39;]
  8. )
  9. return obj
  10. def get_context_data(self, **kwargs):
  11. context = super().get_context_data(**kwargs)
  12. if self.request.user.is_authenticated:
  13. context[&#39;form&#39;] = CommentForm()
  14. return context

Traceback:

  1. request = &lt;FixtureRequest for &lt;Function test_pages_availability[news:detail-news]&gt;&gt;
  2. def fill(request):
  3. item = request._pyfuncitem
  4. fixturenames = getattr(item, &quot;fixturenames&quot;, None)
  5. if fixturenames is None:
  6. fixturenames = request.fixturenames
  7. if hasattr(item, &#39;callspec&#39;):
  8. for param, val in sorted_by_dependency(item.callspec.params, fixturenames):
  9. if val is not None and is_lazy_fixture(val):

> item.callspec.params[param] = request.getfixturevalue(val.name)
>
value = <built-in method today of type object at 0x00007FFE9CA83650>

  1. def parse_date(value):
  2. &quot;&quot;&quot;Parse a string and return a datetime.date.
  3. Raise ValueError if the input is well formatted but not a valid date.
  4. Return None if the input isn&#39;t well formatted.
  5. &quot;&quot;&quot;

> match = date_re.match(value)
E TypeError: expected string or bytes-like object

..\venv\lib\site-packages\django\utils\dateparse.py:75: TypeError

答案1

得分: 0

您的data=参数不是一个日期,而是一个将其转换为date的函数。您需要调用该方法,因此:

  1. @pytest.fixture
  2. def news():
  3. return News.objects.create(
  4. title='Твой заголовок',
  5. text='Текст новости о чем-то интересном',
  6. date=datetime<b>.today()</b>,
  7. )

对于default=&hellip; [Django-doc],您确实可以传递一个Django将调用可调用对象,但不是作为值,而是该函数调用的结果,而不是函数本身。

英文:

Your data= parameter is not a date, it is a function to convert it into a date. You need to call the method, so:

<pre><code>@pytest.fixture
def news():
return News.objects.create(
title='&#1053;&#1086;&#1074;&#1086;&#1089;&#1090;&#1100;',
text='&#1053;&#1077;&#1074;&#1077;&#1088;&#1086;&#1103;&#1090;&#1085;&#1086;&#1077; &#1089;&#1086;&#1073;&#1099;&#1090;&#1080;&#1077;',
date=datetime<b>.today()</b>,
)</code></pre>

For a <code>default=&hellip;</code>&nbsp;<sup>[Django-doc]</sup> you can indeed pass a callable that Django will then call, but not as a value, the value is then the result of the function call, not the function itself.

huangapple
  • 本文由 发表于 2023年6月22日 04:42:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526988.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定