【问题标题】:Importing data to a particular model将数据导入特定模型
【发布时间】:2016-03-03 08:32:16
【问题描述】:

我从 Order 对象的实例开始,并尝试将它们转换为 JSON 格式,该格式将用于更新表。我是 Django 特定代码结构的新手。

我选择的方法是:

  1. 将数据库中的数据作为多个Order实例加载
  2. Order 实例转换为中间Table 对象(已给出格式)
  3. Table对象序列化为JSON

到目前为止,我已经走了很远,但我无法让整个应用程序运行,除了在 Python shell 中运行它。我已经有了模型和序列化程序。

有人可以提供帮助,如何一次标记所有 Order 实例并在一次 API 调用中将它们转换为 Table 以及这个简单示例中缺少的任何其他内容吗?

models.py:

# Order corresponds to Line in the Table
class Order(models.Model):
    doc = models.CharField(max_length=200, blank=True, null=True)
    order = models.CharField(max_length=200, blank=True, null=True)
    nothing = models.CharField(max_length=200, blank=True, null=True)

    def __str__(self):
        return self.order

class Table(models.Model):
    pass

class Column(models.Model):
    data = models.CharField(max_length=200, blank=True, null=True)
    table = models.ForeignKey(Table)

    def __str__(self):
        return self.data

class Line(models.Model):
    doc = models.CharField(max_length=200, blank=True, null=True)
    order = models.CharField(max_length=200, blank=True, null=True)
    nothing = models.CharField(max_length=200, blank=True, null=True)
    table = models.ForeignKey(Table)

    def __str__(self):
        return self.order

serializers.py:

class TableSerializer(serializers.ModelSerializer):

    columns = ColumnSerializer(many=True)
    lines = LineSerializer(many=True)

    class Meta:
        model = Table
        fields = [
            'columns',
            'lines'
        ]

class ColumnSerializer(serializers.ModelSerializer):

    class Meta:
        model = Column
        fields = [
            'data'
        ]

class LineSerializer(serializers.ModelSerializer):

    class Meta:
        model = Line
        fields = [
            'doc',
            'order',
            'nothing'
        ]

对于这个关系数据:

doc         order       nothing
564251422   564210      5648
546546545   98745       4668

JSON 输出应该是:

{
    "columns": [
        {
            "data": "doc"
        },
        {
            "data": "order"
        },
        {
            "data": "nothing"
        }
    ],
    "lines": [
        {
            "doc": "564251422",
            "nothing": 0.0,
            "order": "56421"
        },
        {
            "doc": "546546545",
            "nothing": 0.0,
            "order": "98745"
        }
    ]
}

Shell 命令:

import polls.models
polls.models.Order.objects.all() # outputs all orders
table = polls.models.Table()
polls.models.Column(data="doc",table=table)
polls.models.Column(data="order",table=table)
polls.models.Column(data="nothing",table=table)
polls.models.Line(doc="564251422",order="56421",nothing="0.0",table=table)
polls.models.Line(doc="546546545",order="98745",nothing="0.0",table=table)

views.py(更新):

bunch = OrderSerializer(Order.objects.all(), many=True)                                                                              
headers = bunch.data[0].keys()                                                                                                                   
headers_prepared = map (lambda x: {'data': x} , headers)
ordered_all = ( ('columns', headers_prepared), ('lines', bunch.data) )
data = collections.OrderedDict(ordered_all)
data_json = JSONRenderer().render(data)
return JsonResponse(data_json, safe=False)

【问题讨论】:

  • 我看到您正在使用我在这里给您的答案示例:django nesting serializers in each other。但是这部分工作(序列化和反序列化)吗?你从来没有谈论过Order对象,你能告诉我们你到底想做什么(最终目标)?
  • 这是一个基本的 Web 应用程序,它应该从数据库中检索数据,然后将它们转换为对象以供内部处理(非常重要),客户端应该接收指定格式的 JSON 数据,这些数据将以表(也指定了格式)。这里使用Order是因为它是一个业务对象,需要翻译成客户端可以显示的东西(jQuery DataTables框架)。

标签: json django python-3.x object django-models


【解决方案1】:

正如我所见,这个问题可能与另一个问题(在 cmets 中提到)有关,但对于这种特殊情况......

当您使用 DjangoRestFramework(正确的方法)时,您可以获取 Json 格式的所有数据:

serialisers.py:

from rest_framework import serializers

from polls.models import Order

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ('doc', 'order', 'nothing')

# note we do not use other serializers

shell 中的下一个(未来的视图):

from rest_framework.renderers import JSONRenderer
from polls.models import Order
from polls.serializers import OrderSerializer

bunch = OrderSerializer(Order.objects.all(), many=True)

#this will output "lines" part of desired output
JSONRenderer().render(bunch.data)

#next to get columns, or i say headers
headers = bunch.data[0].keys() 
# headers = ['doc','order','nothing']
# !note will fail if bunch.data is empty

headers_prepared = map (lambda x: {'data': x} , headers)
# headers_prepared = [{'data': 'doc'}, {'data': 'order'}, {'data': 'nothing'}]

import collections # need to use OrderedDict to store in our sequence
ordered_all = ( ('columns', headers_prepared), ('lines', bunch.data) )

#finally desired output 
JSONRenderer().render( collections.OrderedDict(ordered_all)   )

#all code and output tested on my dummy data

更新在 urls.py:

urlpatterns = [
    ...
    url(r'my/', my),
    ...
]

在views.py中添加:

#as you sileny JSONResponse (from RestFramework docs) - need to show it 
from django.http import HttpResponse

class JSONResponse(HttpResponse):
"""
An HttpResponse that renders its content into JSON.
"""
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

#now our view

import collections 

def my(request):

    bunch = OrderSerializer(Order.objects.all(), many=True)

    # to get headers independent of presence of orders
    empty = OrderSerializer()
    headers = empty.data.keys()

    headers_prepared = map (lambda x: {'data': x} , headers)
    ordered_all = ( ('columns', headers_prepared), ('lines', bunch.data) )

    out = collections.OrderedDict(ordered_all)
    #finally desired output 
    return  JSONResponse( out  )

【讨论】:

  • 谢谢,我会看看的。这个问题在另一个问题上展开,以便您知道。描述问题的最佳方法是我想以一种与源格式完全不同的特定格式序列化Order,我使用类TableColumnLine 来帮助我实现这一目标.
  • 是的,你得到了正确的输出。当您第二次调用JSONRenderer().render( collections.OrderedDict(ordered_all)) 时,它不会输出列数据,但这只是一个细节。在 shell 之外查看视图或如何操作会很有趣......
  • 我快完成了:b'{"columns":[{"data":"doc"},{"data":"order"},{"data":"nothing"}],"lines":[{"doc":"564251422","order":"56421","nothing":"0.0"},{"doc":"546546545","order":"98745","nothing":"0.0"}]}' is not JSON serializable 在我 return JsonResponse(data, safe=False) 时被抛出
  • 请仔细检查您的代码或将其放入 cmets 中,就像在我的 shell(django 1.8、python 2.7)中一样,它会将所有数据打印两次,没有任何问题。
  • 关于 'not JSON serializable' 你应该删除倒数行,然后最后一行将返回 JsonResponse(data, safe=True)
猜你喜欢
  • 2021-02-10
  • 2020-11-02
  • 1970-01-01
  • 2014-08-30
  • 2012-05-10
  • 1970-01-01
  • 2011-04-14
  • 2011-08-21
  • 1970-01-01
相关资源
最近更新 更多