【问题标题】:django rest framework - get two modelsdjango rest framework - 获取两个模型
【发布时间】:2014-01-09 12:08:37
【问题描述】:

我有多个通过外键关联的模型。我可以使用 django rest 框架一对一地单独导出它们,我也可以导出多个嵌套的。但是,我希望能够将它们本质上“连接”在一起,形成一个 json/xml 导出。

以下示例中的模型通过 jobdtl_id 上的一对一外键连接。我有一些是一对多的,但我希望当我知道如何获得一个可以链接两个不同模型的视图时,我能弄清楚这一点,就像我在下面想要的那样 -

这是我希望通过点击单个 URL 的 json 看起来像的示例

http://localhost/job/4/

{
  "job": {
    "-id": "9878",
    "-name": "This is the job",
    "-master": "blahserver",
    "-dbversion": "234",
    "-xmlversion": "1",
    "jobmst": {
      "jobmst_id": "9878",
      "jobmst_type": "2",
      "jobmst_prntid": "234",
      "jobmst_active": "Y",
      "jobmst_name": "This is the job",
      "jobmst_owner": "Owner",
      "jobdtl_id": "9878",
      "jobmst_lstchgtm": {
        "-date": "Y",
        "#text": "2013-10-23 09:22:08.0"
      },
      "jobmst_prntname": "Parent",
      "jobmst_alias": "9878"
    },
    "jobdtl": {
      "jobdtl_id": "9878",
      "jobdtl_cmd": "blah.exe",
      "jobdtl_failalarm": "NULL",
      "nodmst_id": "NULL",
      "nodlstmst_id": "NULL",
      "jobdtl_inhevent": "Y",
      "jobdtl_inhoptions": "Y",
      "jobdtl_inhagent": "Y",
      "jobdtl_inhrepeat": "Y",
      "jobdtl_inhtime": "Y",
      "jobdtl_timewin": "NULL",
      "jobdtl_saveoutput": "Y",
      "jobdtl_outputname": "NULL",
      "jobdtl_trackmethod": "1",
      "jobdtl_trackcmd": "NULL",
      "jobdtl_deplogic": "1",
      "jobdtl_rerun": "NULL",
      "jobdtl_params": "--blah --ok"
    },
    "jobdep": [
      {
        "jobdep_id": "79670",
        "jobmst_id": "9878",
        "jobdep_type": "1",
        "jobdep_jobmst": "another job",
        "varmst_id": "NULL"
      },
      {
        "-num": "2",
        "jobdep_id": "83783",
        "jobmst_id": "9878",
        "jobdep_type": "1",
        "jobdep_jobmst": "and another",
        "varmst_id": "NULL"
      }
    ],
    "trgjob": [
      {
        "trgjob_id": "22286",
        "trgmst_id": "23455",
        "jobmst_id": "9878"
      },
      {
        "-num": "2",
        "trgjob_id": "28980",
        "trgmst_id": "23521",
        "jobmst_id": "9878"
      },
      {
        "-num": "3",
        "trgjob_id": "28981",
        "trgmst_id": "9237",
        "jobmst_id": "9878"
      }
    ]
  }
}

模型基本是这样的——

class Jobdtl(models.Model):
    jobdtl_id = models.IntegerField(primary_key=True)
    jobdtl_cmd = models.TextField(blank=True)
    ....
    jobdtl_duration = models.IntegerField(blank=True, null=True)
    class Meta:
        managed = False
        db_table = 'jobdtl'

class Jobmst(models.Model):
    jobmst_id = models.IntegerField(primary_key=True)
    jobmst_type = models.SmallIntegerField()
    ....
    jobdtl_id = models.ForeignKey('Jobdtl', db_column='jobdtl_id', related_name='mstdtl', blank=True, null=True)
    def __unicode__(self):
        return self.jobmst_name   
    class Meta:
        managed = False
        db_table = 'jobmst'

结束警告我正在转换 json 从 XML 如何查找现有遗留应用程序,就像这样 -

<?xml version="1.0"?>
<job id="9878" name="This is the job" master="blahserver" dbversion="532" xmlversion="1">
    <jobmst>
        <jobmst_id>9878</jobmst_id>
        <jobmst_type>2</jobmst_type>
        <jobmst_prntid>234</jobmst_prntid>
        <jobmst_active>Y</jobmst_active>
        <jobmst_name>This is the job</jobmst_name>
        <jobmst_owner>Owner</jobmst_owner>
        <jobdtl_id>9878</jobdtl_id>
        <jobmst_lstchgtm date="Y">2013-10-23 09:22:08.0</jobmst_lstchgtm>
        <jobmst_prntname>Parent</jobmst_prntname>
        <jobmst_alias>9878</jobmst_alias>
    </jobmst>
    <jobdtl>
        <jobdtl_id>9878</jobdtl_id>
        <jobdtl_cmd>blah.exe</jobdtl_cmd>
        <jobdtl_failalarm>NULL</jobdtl_failalarm>
        <nodmst_id>NULL</nodmst_id>
        <nodlstmst_id>NULL</nodlstmst_id>
        <jobdtl_inhevent>Y</jobdtl_inhevent>
        <jobdtl_inhoptions>Y</jobdtl_inhoptions>
        <jobdtl_inhagent>Y</jobdtl_inhagent>
        <jobdtl_inhrepeat>Y</jobdtl_inhrepeat>
        <jobdtl_inhtime>Y</jobdtl_inhtime>
        <jobdtl_timewin>NULL</jobdtl_timewin>
        <jobdtl_saveoutput>Y</jobdtl_saveoutput>
        <jobdtl_outputname>NULL</jobdtl_outputname>
        <jobdtl_trackmethod>1</jobdtl_trackmethod>
        <jobdtl_trackcmd>NULL</jobdtl_trackcmd>
        <jobdtl_deplogic>1</jobdtl_deplogic>
        <jobdtl_rerun>NULL</jobdtl_rerun>
        <jobdtl_params>--blah --ok</jobdtl_params>
    </jobdtl>
    <jobdep>
        <jobdep_id>79670</jobdep_id>
        <jobmst_id>9878</jobmst_id>
        <jobdep_type>1</jobdep_type>
        <jobdep_jobmst>another job</jobdep_jobmst>
        <varmst_id>NULL</varmst_id>
    </jobdep>
    <jobdep num="2">
        <jobdep_id>83783</jobdep_id>
        <jobmst_id>9878</jobmst_id>
        <jobdep_type>1</jobdep_type>
        <jobdep_jobmst>and another</jobdep_jobmst>
        <varmst_id>NULL</varmst_id>
    </jobdep>
    <trgjob>
        <trgjob_id>22286</trgjob_id>
        <trgmst_id>23455</trgmst_id>
        <jobmst_id>9878</jobmst_id>
    </trgjob>
    <trgjob num="2">
        <trgjob_id>28980</trgjob_id>
        <trgmst_id>23521</trgmst_id>
        <jobmst_id>9878</jobmst_id>
    </trgjob>
    <trgjob num="3">
        <trgjob_id>28981</trgjob_id>
        <trgmst_id>9237</trgmst_id>
        <jobmst_id>9878</jobmst_id>
    </trgjob>
</job>

【问题讨论】:

  • 那不是有效的 json,你想要一个结果数组吗?还是列出两个模型的父对象?只要它是只读的,使用自定义序列化程序就很容易。读/写复合序列化器需要一些人的工作。
  • 我更新了 json,希望它更有意义。是的,它只需要只读。
  • @whoiearth 打开/关闭的花括号的数量不匹配,所以很难弄清楚确切的 json 结构是什么,请您纠正这个..
  • 我已对其进行了更新,以包含我认为正确的格式化 json。我还包含了我想要基于它的源 XML。

标签: django django-models django-views django-rest-framework django-class-based-views


【解决方案1】:

我通过在 views.py 中执行以下操作找到了解决方案

...
@csrf_exempt        
def tesxml_test(request, pk):
    """
    Retrieve, update or delete a code snippet.
    """
    try:
        mst = Jobmst.objects.using('database1').get(jobmst_id=pk)
        dtl = Jobdtl.objects.using('database1').get(jobdtl_id=pk)
        dep = Jobdep.objects.using('database2').filter(jobmst_id=pk).order_by('jobdep_id')
        trg = Trgjob.objects.using('database1').filter(jobmst_id=pk).order_by('trgjob_order')
    except Jobmst.DoesNotExist:
        return HttpResponse(status=404)

    if request.method == 'GET':
        #Get String Results of 4 queries
        jobmststring = JobmstSerializer(mst)
        jobdtlstring = JobdtlSerializer(dtl)
        jobdepstring = JobdepSerializer(dep)
        trgjobstring = TrgjobSerializer(trg)
        #Get serialized Results of 4 queries
        jobmst_serialized = {'jobmst': jobmststring.data}
        jobdtl_serialized = {'jobdtl': jobdtlstring.data}
        jobdep_serialized = {'jobdep': jobdepstring.data}
        trgjob_serialized = {'trgjob': trgjobstring.data}

        jobgroup = jobmst_serialized, jobdtl_serialized, jobdep_serialized, trgjob_serialized,


        jobgroupresponse = TESXMLResponse(jobgroup)
        return jobgroupresponse
...

它并不完美,但它让我进入了我的问题的下一步,即自定义渲染器以获取根字段中的数据,我有另一个 SO 问题:)

【讨论】:

    【解决方案2】:
    class MSTSerializer(serializers.HyperlinkedModelSerializer):
        jobdtl_id = DTLSerializer()
        class Meta:
            model = Jobmst
            fields = ('id', 'url', 'jobdtl_id'...)
    
    class DTLSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = Jobdtl
            fields = ('id', 'url',  ...)
    

    会产生更正确的数据结构

    {
        "jobmst_id": 4,
        "jobmst_type": 1,
        "jobdtl_id": {
           "jobdtl_id": 4,
           "jobdtl_cmd": null,
           "jobdtl_duration": 1379
        },
    
    }
    

    【讨论】:

    • 是的,这就是我目前正在做的,但它包含 2 个问题。
    • 是的,这就是我目前正在做的,但它包含 2 个问题。 1.它通过将jobdtl_id链接到下一个模型来创建我不一定想要的层次结构。 2.一些外键的顺序并不总是在同一个方向。理想情况下,我希望能够输入localhost/job/4 并获得所有与 jobmst_id 列相关的表。有些表可能会返回多个值,有些则没有,但最后我希望它像我最初的问题一样显示出来,基本上是将单独的 json 全部连接到 1 中。
    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多