Reputation: 13908
Here's my code:
# 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'),
This code works just fine if I visit /mypath
. However, when I run an automated test using Django's test client, I get this error:
*** TypeError: Object of type MyModel is not JSON serializable
this is my test: from django.test import TestCase, Client from blog.tests.factories.user import UserFactory from blog.tests.factories.post import 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
I suspect it has something to do with my factories:
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')
How can I make my factories serializable?
NOTE:
This question is not a duplicate. The other questions linked have view handlers that return HttpResponse
objects, instead of JsonResponse
objects. This distinction is key to my problem, because the error I'm seeing is related to JSON serialization that is supposed to be addressed by the JsonResponse
class.
Also, the other questions do not involve factories. Factories are another key component of what I'm trying to do, which is run integration tests against data generated by factories.
Upvotes: 15
Views: 1270
Reputation: 163
The code you shared assumes JSONResponse
will serialize an ORM object, but according to Django documentation, it won't:
https://docs.djangoproject.com/en/3.0/ref/request-response/#jsonresponse-objects
https://docs.djangoproject.com/en/3.0/topics/serialization/#djangojsonencoder
It will work if you serialize the Django ORM object before passing it to JSONResponse
Consider doing the following:
from django.core import serializers
data = serializers.serialize("json", MyModel.objects.all())
https://docs.djangoproject.com/en/3.0/topics/serialization/
django-rest-framework is a very popular lib used in scenarios like the one you shared https://docs.djangoproject.com/en/3.0/topics/serialization/#djangojsonencoder
Upvotes: 1
Reputation: 774
what about this:
def get_all_models(request):
return JsonResponse({"models": list(MyModel.objects.all().values())},safe=False)
the point is here:
MyModel.objects.all().values()
safe=False
Upvotes: 0