为什么JsonResponse不自动序列化我的Django模型?

时间:2019-05-06 20:30:24

标签: json django python-3.x

我有以下模型:

class BaseModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True


class User(AbstractUser):
    username = models.CharField(max_length=255, unique=True)
    email = models.EmailField(unique=True, null=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


class Post(BaseModel):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    content_url = models.URLField(null=False)

我希望能够获取数据库中的所有模型。当我这样做时:

urlpatterns = [
    path("", views.get_all_posts, name="get_all_posts")]

def get_all_posts(request):
    return JsonResponse({"posts": Post.objects.all()})

我收到有关JSON序列化的错误。因此,根据其他帖子的建议,我这样做:

def get_all_posts(request):
    posts = serializers.serialize('json', Post.objects.all())
    return JsonResponse({"posts": json.loads(posts)})

但是我得到了一个这样形状的物体:

('[{"model": "api.post", "pk": 1, "fields": {"created_at": '
 '"2019-05-06T20:22:43.928Z", "updated_at": "2019-05-06T20:22:43.928Z", '
 '"user": 1, "content_url": "tmp/posts/None.md"}}]')

您看到这太荒谬了吗?要获取帖子的实际内容,我需要将每个“响应”映射到其fields属性,即使这样,我仍然缺少主键!

我想知道为什么JSON响应接口不这么简单:

def get_all_posts(request):
    return JsonResponse({"posts": Post.objects.all()})

似乎要向客户端提供序列化JSON,我必须跳过一系列的循环,说实话,这些循环在生产Web框架中不应该存在。

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

format='python' 功能中将 serialize() 用作:

def get_all_posts(request):
    posts = serializers.serialize('python', Post.objects.all())
    return JsonResponse({"posts": posts})

答案 1 :(得分:0)

使用queryset values() / values_list()方法进行序列化:

def get_all_posts(request):
    return JsonResponse({"posts": Post.objects.values_list()})

它还支持跨域字段,因此不会有嵌套的序列化,这很容易出错:

def get_all_posts(request):
    return JsonResponse({
        "posts": Post.objects.values('content_url', 'user__username')
    })

但是对于某些复杂的fleid值,它也可能会失败。在这种情况下,可以在理解循环中将复杂的类型转换为简单的Python类型,或者使用第三方序列化程序(例如DRF或tastypie)。