django - 如何使用 DRF 和 HyperlinkedModelSerializer 序列化程序测试 POST 方法
问题描述
我正在使用 Django Rest Framework (DRF),并且正在尝试测试 POST 方法。
这些是我的模型:
class CustomUser(AbstractUser):
def __str__(self):
return self.email
class Meta:
ordering = ('id',)
verbose_name = 'user'
class Brand(Group):
owner = models.ForeignKey(User,
on_delete=models.CASCADE,
related_name='%(class)ss',
related_query_name='%(class)s')
description = models.TextField('description', max_length=3000, blank=True)
facebook_url = models.URLField('facebook url', blank=True)
twitter_url = models.URLField('twitter url', blank=True)
instagram_url = models.URLField('instagram url', blank=True)
pinterest_url = models.URLField('pinterest url', blank=True)
portfolio_url = models.URLField('portfolio url', blank=True)
phone_number = PhoneNumberField('phone number', blank=True)
这些是我的序列化程序:
class CustomUserSerializer(HyperlinkedModelSerializer):
brands = HyperlinkedRelatedField(
many=True,
read_only=True,
view_name='brand-detail'
)
class Meta:
model = CustomUser
fields = (
'url',
'username',
'email',
'brands',
)
class BrandSerializer(HyperlinkedModelSerializer):
addresses = HyperlinkedRelatedField(many=True,
read_only=True,
view_name='address-detail')
class Meta:
model = Brand
fields = (
'url',
'name',
'owner',
'description',
'facebook_url',
'twitter_url',
'instagram_url',
'pinterest_url',
'portfolio_url',
'phone_number',
)
这些是我的看法:
class CustomUserViewSet(ModelViewSet):
""""A view set for viewing and editing custom users."""
queryset = CustomUser.objects.all()
serializer_class = CustomUserSerializer
class BrandViewSet(ModelViewSet):
"""A view set for viewing and editing brands."""
queryset = Brand.objects.all()
serializer_class = BrandSerializer
这是我的测试,我正在使用 pytest:
@pytest.mark.django_db
def test_create_brand_with_valid_data(client):
"""Tests POST method with valid data to create a Brand instance."""
user = CustomUser.objects.create(username='x',
email='x@example.com',
password='abc123', )
data = {
'owner': f'http://testserver/api/users/{user.id}/',
'name': 'NA',
}
print(data)
response = client.post(reverse('address-list'),
data=json.dumps(data),
content_type='application/json')
assert response.status_code == HTTP_201_CREATED
我得到的不是 201 响应,而是 400,所以我做错了什么,但我不知道是什么。
追溯:
_________________________________________________________________________________ test_create_brand_with_valid_data _________________________________________________________________________________
client = <django.test.client.Client object at 0x10c2199b0>
@pytest.mark.django_db
def test_create_brand_with_valid_data(client):
"""Tests POST method with valid data to create a Brand instance."""
user = CustomUser.objects.create(username='x',
email='x@example.com',
password='abc123', )
data = {
'owner': f'http://testserver/api/users/{user.id}/',
'name': 'NA',
}
print(data)
response = client.post(reverse('address-list'),
data=json.dumps(data),
content_type='application/json')
> assert response.status_code == HTTP_201_CREATED
E assert 400 == 201
E + where 400 = <Response status_code=400, "application/json">.status_code
api/tests/test_brand.py:98: AssertionError
解决方案
这很尴尬,所以问题是我请求错误的端点。下面的代码解决了我的问题,它也避免了对 url 进行硬编码:
import json
from rest_framework.request import Request
from rest_framework.reverse import reverse
from rest_framework.status import (HTTP_200_OK,
HTTP_404_NOT_FOUND,
HTTP_201_CREATED,
HTTP_400_BAD_REQUEST,
HTTP_204_NO_CONTENT)
from rest_framework.test import APIRequestFactory
@pytest.mark.django_db
def test_create_brand_with_valid_data(client):
"""Tests POST method with valid data to create a Brand instance."""
user = CustomUser.objects.create(username='x',
email='x@example.com',
password='abc123', )
factory = APIRequestFactory()
request = factory.get('/')
context = {'request': Request(request)}
user_serializer = CustomUserSerializer(user, context=context)
data = {
'owner': user_serializer.data['url'],
'name': 'NA',
}
response = client.post(reverse('brand-list'),
data=json.dumps(data),
content_type='application/json')
assert response.status_code == HTTP_201_CREATED
这个测试就像一个魅力。
推荐阅读
- c# - 将登录用户分配给 FormView 控件内的文本框
- github - 在 GitHub 操作下运行时将多个 cmake 库目标组合成一个目标失败
- python - 如何编辑我的 postgreSQL 查询以按日期选择几列的最新行
- javascript - 名称断水平条形图 Plotly JS
- javascript - 将表单数据发送到 Spring Boot 的最简单方法是什么?
- typescript - 形式的通用约束 `
`其中`E`是`枚举`? - c# - 在 C# 中将 URL 字符串解析为协议字符串、服务器字符串和域字符串?
- java - 为什么 BufferedWriter 不写入文件?
- r - R:在哪里可以找到所有 Rfast 函数的源代码
- .htaccess - 将目录重定向到子域