Django 测试客户端不会自动序列化工厂

Posted

技术标签:

【中文标题】Django 测试客户端不会自动序列化工厂【英文标题】:Django test client does not automatically serialize factories 【发布时间】:2019-09-13 08:24:35 【问题描述】:

这是我的代码:

# models.py
class MyModel(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=10)
    ...

# views.py
def get_all_models(request):
    return JsonResponse("models": list(MyModel.objects.all()))

# urls.py
path('/mypath', views.get_all_models, name='get_all_models'),

如果我访问/mypath,这段代码就可以正常工作。但是,当我使用 Django 的测试客户端运行自动化测试时,我得到了这个错误:

*** TypeError: Object of type MyModel is not JSON serializable

这是我的测试: 从 django.test 导入 TestCase,客户端 从 blog.tests.factories.user 导入 UserFactory 从 blog.tests.factories.post 导入 PostFactory

class MyModelTest(TestCase):
    def setUp(self):
        self.user = UserFactory.create()
        self.post = MyModelFactory.create(user=self.user)
        self.client = Client()

    def test_get_all_models(self):
        response = self.client.get("/mypath")
        pass

我怀疑这与我的工厂有关:

import factory
from .models import User, MyModel

class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = User

    username = factory.Faker('word')
    email = factory.Faker('email')

class MyModelFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = MyModel

    user = factory.SubFactory(UserFactory)
    name = factory.Faker('name')

如何使我的工厂可序列化?

注意: 这个问题不是重复的。链接的其他问题的视图处理程序返回 HttpResponse 对象,而不是 JsonResponse 对象。这种区别是我的问题的关键,因为我看到的错误与应该由 JsonResponse 类解决的 JSON 序列化有关。

另外,其他问题不涉及工厂。工厂是我正在尝试做的另一个关键组件,它是针对工厂生成的数据运行集成测试。

【问题讨论】:

<Django object > is not JSON serializable的可能重复 不是重复的。问这个问题的人返回的是 HttpResponse,而我使用的是 JsonResponse。而且这个问题不涉及工厂男孩。 您确定在浏览器中转到/mypath 时有效吗?开发数据库有数据吗? 确实如此,工厂也按预期工作 MyModel 类是否有额外的属性或方法?如果是这样,请更新问题以包含课程的全部内容。 【参考方案1】:

您分享的代码假定JSONResponse 将序列化一个 ORM 对象,但根据 Django 文档,它不会:

https://docs.djangoproject.com/en/3.0/ref/request-response/#jsonresponse-objects

https://docs.djangoproject.com/en/3.0/topics/serialization/#djangojsonencoder

如果您在将 Django ORM 对象传递给JSONResponse 之前对其进行序列化,它将起作用

考虑执行以下操作:

from django.core import serializers
data = serializers.serialize("json", MyModel.objects.all())

https://docs.djangoproject.com/en/3.0/topics/serialization/

django-rest-framework 是一个非常流行的库,用于您分享的场景中 https://docs.djangoproject.com/en/3.0/topics/serialization/#djangojsonencoder

【讨论】:

【参考方案2】:

这个呢:

def get_all_models(request):
    return JsonResponse("models": list(MyModel.objects.all().values()),safe=False)

重点在这里:

MyModel.objects.all().values()
safe=False

【讨论】:

@dopatraman 我更新了我的答案,只需将 safe=False 添加到 JsonResponse 感谢您的回复,但即使添加 safe=False 也不能阻止错误抛出

以上是关于Django 测试客户端不会自动序列化工厂的主要内容,如果未能解决你的问题,请参考以下文章

Django 不会为某些测试用例重新加载夹具

django-redis结合drf实现缓存

Django-序列化

Django7 序列化

Django序列化

Django序列化