所以下面我有一些代码来测试某人创建帖子并且该帖子有一个功能hash_tag
在本例中是“#video”。该代码采用Post
body
并使用正则表达式查找以“#”开头的任何单词。如果是,那么它会创建或获取HashTag
来自HashTag
桌子。然后设置该列表HashTag
to the hash_tags
下的属性Post
.
由于某种原因CreatePostSerializer
序列化程序抛出一个没有意义的异常。序列化器抛出异常ValidationError({'hash_tags': [ErrorDetail(string='Invalid pk "[\'video\']" - object does not exist.', code='does_not_exist')]})
。这没有意义的原因是因为当我调试并在之后立即设置断点时except Exception as e
under views.py
这就是我得到的
>>>e
ValidationError({'hash_tags': [ErrorDetail(string='Invalid pk "[\'video\']" - object does not exist.', code='does_not_exist')]})
>>>HashTag.objects.get(pk='video')
<HashTag: HashTag object (video)>
>>>request.data['hash_tags']
['video']
So the >>>
代表我输入到调试器中的内容。我基本上停在队伍里了return Response...
我们可以看到e
is the ValidationError
我提到过,但是我们可以看到它声称不存在的对象确实存在。为什么序列化程序会抛出“ValidationError - 对象不存在”?
Note:我有另一个测试,它执行完全相同的操作并通过,但没有传递视频文件,这让我相信 Django 在传入正文的情况下正在做一些不同的事情multi-part
。我还尝试过只设置一个哈希标签的情况hash_tags
=而不是列表并且它有效。但这是一种黑客攻击,更清洁的解决方案是首选。
助手.py
import re
def extract_hashtags(text):
regex = "#(\w+)"
return re.findall(regex, text)
test.py
def test_real_image_upload_w_hash_tag(self):
image_file = retrieve_test_image_upload_file()
hash_tag = 'video'
response = self.client.post(reverse('post'),
data={'body': f'Some text and an image #{hash_tag}',
'images': [image_file]},
**{'HTTP_AUTHORIZATION': f'bearer {self.access_token}'})
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
views.py
def set_request_data_for_post(request, user_uuid: str):
request.data['creator'] = user_uuid
post_text = request.data['body']
hash_tags_list = extract_hashtags(post_text)
hash_tags = [HashTag.objects.get_or_create(hash_tag=ht)[0].hash_tag for ht in hash_tags_list]
if len(hash_tags) > 0:
request.data['hash_tags'] = hash_tags
return request
def create_post(request):
user_uuid = str(request.user.uuid)
request = set_request_data_for_post(request=request, user_uuid=user_uuid)
try:
serializer = CreatePostSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
post_obj = serializer.save()
except Exception as e:
return Response(dict(error=str(e),
user_message=error_message_generic),
status=status.HTTP_400_BAD_REQUEST)
return Response(serializer.data, status=status.HTTP_201_CREATED)
序列化器.py
from rest_framework import serializers
from cheers.models import Post
class CreatePostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('creator', 'body', 'uuid', 'created', 'updated_at', 'hash_tags')
model.py
class Post(models.Model):
# ulid does ordered uuid creation
uuid = models.UUIDField(primary_key=True, default=generate_ulid_as_uuid, editable=False)
created = models.DateTimeField('Created at', auto_now_add=True)
updated_at = models.DateTimeField('Last updated at', auto_now=True, blank=True, null=True)
creator = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="post_creator")
body = models.CharField(max_length=POST_MAX_LEN, validators=[MinLengthValidator(POST_MIN_LEN)])
hash_tags = models.ManyToManyField(HashTag, blank=True)
class HashTag(models.Model):
hash_tag = models.CharField(max_length=HASH_TAG_MAX_LEN, primary_key=True, validators=[
MinLengthValidator(HASH_TAG_MIN_LEN)])