【发布时间】:2019-09-24 11:48:50
【问题描述】:
我有这些模型:
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 框架中。
我做错了什么?
【问题讨论】:
-
您可以创建自己的serializer 来指定如何序列化模型。事实上,您准确地回答了您的问题:因为有很多方法可以序列化模型,例如,您可能不想包含用户模型的散列密码。事实上,如果你做一个 REST api,你最好使用
ViewSets,因此不要自己构造各种视图。 -
我的意思是,序列化的一个子集是如此普遍,以至于它们应该开箱即用
-
有些模型不能直接序列化为 JSON。如何处理多对多关系?外键?日期和日期时间字段?使用哪种格式? Django Rest Framework 为您提供了许多情况下的序列化器,使工作更容易,但查看代码以了解序列化对象并不明显。您想要 JSON 的方式与其他人想要的 JSON 不同。
-
我没有使用 DRF,也不打算使用。我希望只用 Django 就可以做到这一点。诚然,有很多方法可以进行序列化,但应该提供一种开箱即用的通用方法,并在需要时提供扩展选项。
-
@dopatraman:如果你在模型中添加额外的属性会怎样?例如,如果那是一个 HTTP 会话(不是真正“可序列化”的东西)怎么办。 Linux 的禅意是:“让每个工具都做一项工作,并且把这项工作做得很好”。通常最好用可以有效重用的非常小的元素来设计一个系统。
标签: json django python-3.x