如何将模型转换成格式良好的 JSON 字符串?

53 阅读2分钟

在 Django 中,我们经常需要将模型数据转换为 JSON 字符串以便在前端使用。默认情况下,可以使用 serializers.serialize() 方法将模型数据序列化为 JSON 字符串,但这种方法生成的 JSON 字符串并不是我们想要的格式。例如,对于以下模型:

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

使用 serializers.serialize() 方法将 Book 模型数据序列化为 JSON 字符串后,得到的结果如下:

[
  {
    "pk": 1,
    "model": "books.book",
    "fields": {
      "title": "Book One",
      "authors": [
        1,
        2
      ],
      "publisher": 1,
      "publication_date": "2013-07-01"
    }
  },
  {
    "pk": 2,
    "model": "books.book",
    "fields": {
      "title": "Book Two",
      "authors": [
        1,
        3
      ],
      "publisher": 2,
      "publication_date": "2013-07-05"
    }
  }
]

可以看到,作者和出版商只显示了 ID,而不是详细信息。

  1. 解决方案

为了将模型数据转换为我们想要的 JSON 格式,我们可以使用以下两种方法:

方法一:使用第三方库

我们可以使用 Tastypie 或 django-rest-framework 等第三方库来将模型数据序列化为 JSON 字符串。这些库都提供了丰富的功能,可以让我们轻松地自定义 JSON 格式。

方法二:自定义序列化方法

我们也可以自定义序列化方法来将模型数据转换为 JSON 字符串。我们可以为每个模型定义一个 as_dict() 方法,该方法将模型数据转换为一个字典,然后使用 json.dumps() 方法将字典转换为 JSON 字符串。例如,对于 Book 模型,我们可以定义如下 as_dict() 方法:

def as_dict(self):
    return {
        "id": self.id,
        "title": self.title,
        "authors": [author.as_dict() for author in self.authors.all()],
        "publisher": self.publisher.as_dict(),
        "publication_date": self.publication_date.strftime("%Y-%m-%d")
    }

然后,我们在视图中使用 json.dumps() 方法将字典转换为 JSON 字符串,并返回给前端。例如:

def getAllBooks(request):
    book_list = Book.objects.all()
    book_list_data = [book.as_dict() for book in book_list]
    return HttpResponse(json.dumps(book_list_data), content_type="application/json")

这样,我们就可以得到我们想要的 JSON 格式:

[
  {
    "id": 1,
    "title": "Book One",
    "authors": [
      {
        "id": 1,
        "first_name": "Eric",
        "last_name": "Qian",
        "email": "eric@example.com"
      },
      {
        "id": 2,
        "first_name": "Douglas",
        "last_name": "Adams",
        "email": "douglas@example.com"
      }
    ],
    "publisher": {
      "id": 1,
      "name": "Publisher One",
      "address": "1 Avenue",
      "city": "SYD",
      "state": "NSW",
      "country": "AU",
      "website": "http://www.example.com/"
    },
    "publication_date": "2013-07-01"
  },
  {
    "id": 2,
    "title": "Book Two",
    "authors": [
      {
        "id": 1,
        "first_name": "Eric",
        "last_name": "Qian",
        "email": "eric@example.com"
      },
      {
        "id": 3,
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "jane@example.com"
      }
    ],
    "publisher": {
      "id": 2,
      "name": "Publisher Two",
      "address": "2 Avenue",
      "city": "MEL",
      "state": "VIC",
      "country": "AU",
      "website": "http://www.example2.com/"
    },
    "publication_date": "2013-07-05"
  }
]