我有以下模型:
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框架中不应该存在。
我在做什么错了?
答案 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)。