【问题标题】:Django queryset to JSON object nested by primary keyDjango查询集到由主键嵌套的JSON对象
【发布时间】:2019-03-15 22:58:50
【问题描述】:

我正在尝试将查询集解析为 JSON 对象,以便每个键都是模型的主键,每个值都是包含所有其他字段的 JSON 对象。

myjson = {
           apple:  { color: "r", calories: 10},
           banana: { color: "w", calories: 50}
​         }

这是收集数据的模型和 Django 视图(基于此blog post):

class Fruit(models.Model):
    fruit_id = models.CharField(primary_key=True)
    color = models.CharField(max_length=50)
    calories = models.IntegerField()

def get_FruitsTableDjango(request):
    fruits_table = Fruit.objects.all().values()
    fruits_table_list = list(fruits_table )  # important: convert the QuerySet to a list object
    return JsonResponse(fruits_table_list , safe=False)

但是在客户端(通过 AJAX),这会返回一个对象数组:

mydata = [
           0: { fruit_id: "apple", color: "r", calories: 10},
           1: { fruit_id: "banana", color: "w", calories: 50}
]

我还发现了here 我如何可以按预期重做这个数组:

//Restructure JSON by fruit_id name
fruits= {},
mydata.forEach(function (a) {
    var temp = {};
    Object.keys(a).forEach(function (k) {
        if (k === 'fruit_id') {
            fruits[a[k]] = temp; //gets fruit_id
            return;
        }
        temp[k] = a[k]; //fill the temp variable with elements
    });
});
mydata=fruits; //overwrite initial array with nicely-rearranged-by-fruitId object

我基本上有两个问题:

  1. 是否有更直接的方法来获取所需的 JSON(由主键嵌套)?
  2. 如果不是,客观上哪里是执行对象解析逻辑的最佳位置:在 Javascript 中的客户端(如上),或在服务器端,例如在 Django 视图中?

​​​​

【问题讨论】:

  • 使用 django rest 框架。很容易实现它
  • @webbyfox 谢谢,我正在考虑探索这个选项,但对它的了解仍然有限。您能否简要说明如何使用 DRF“轻松”实现这一目标?

标签: python json django


【解决方案1】:

在 DRF 中,

假设我有 model.py 如下

from django.db import models


class OrganisationalUnitGrouper(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

    @property
    def unit(self):
        return self.organisationalunit_set.all()


class OrganisationalUnit(models.Model):
    unit_id = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    display = models.CharField(max_length=255)
    description = models.CharField(max_length=255)
    path = models.CharField(max_length=255)
    ou_group = models.ForeignKey(OrganisationalUnitGrouper, on_delete=models.PROTECT)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "OU Unit"

序列化器你可以像这样定义

from rest_framework import serializers

from .models import OrganisationalUnitGrouper, OrganisationalUnit


class OUSerializer(serializers.ModelSerializer):
    # id = serializers.IntegerField(required=False)

    class Meta:
        model = OrganisationalUnit
        fields = ("unit_id", "name", "display", "description", "path")


class OUGroupSerializer(serializers.ModelSerializer):
    unit = OUSerializer(many=True)

    class Meta:
        model = OrganisationalUnitGrouper
        fields = ("name", "unit")

视图集可以是

from rest_framework import viewsets

from .serializers import OUSerializer, OUGroupSerializer
from .models import OrganisationalUnitGrouper, OrganisationalUnit


class OUGroupViewSet(viewsets.ModelViewSet):

    queryset = OrganisationalUnitGrouper.objects.all()
    serializer_class = OUGroupSerializer


class OUViewSet(viewsets.ModelViewSet):

    queryset = OrganisationalUnit.objects.all()
    serializer_class = OUSerializer

这将为您提供嵌套 API。

【讨论】:

  • 谢谢,但对我来说,这仍然返回一个“未嵌套”的数组,例如http://127.0.0.1:8000/api/fruit/ 返回:[ { "fruit_id": "apple", "color": "r", "calories": "10"}, {...} ]。你真的得到一个嵌套的 JS 对象吗? { apple: { color: "r", calories: 10}, banana: { color: "w", calories: 50} }?
猜你喜欢
  • 1970-01-01
  • 2013-03-18
  • 2020-06-19
  • 2011-06-19
  • 2021-09-21
  • 2020-10-04
  • 1970-01-01
  • 2017-12-21
  • 2020-04-25
相关资源
最近更新 更多