如何使用Django-rest-framework创建与模型不同的视图

时间:2015-02-02 16:07:56

标签: python django django-rest-framework

所以,我有两类服务器和数据中心;

 class Datacenter(models.Model):

    name = models.CharField(max_length=50)
    status = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

 class Servers(models.Model):

    datacenter = models.ForeignKey(Datacenter)
    hostname = models.CharField(max_length=50)

    def __unicode__(self):
        return self.hostname

并且想创建一个视图,返回数据中心的详细信息以及所有相关的服务器,所以当我这样做时;

http://127.0.0.1:8000/datacenter/1/

我得到类似的东西;

 {
   "id": 1,
   "name": "TestDC"
 }

但我真正希望获得的是这样的事情;

{
"id": 1,
"name": "TestDC",
"Servers": [
    {
      "id": 1,
      "hostname": "Server1",
    },
    {
      "id": 2,
      "hostname": "Server2",
    }
  ]
}

现在我的观点是这样的;

 class DatacenterViewSet(viewsets.ModelViewSet):

     queryset = datacenter.objects.all()
     serializer_class = datacenterSerializer

和我的序列号;

 class DatacenterSerializer(serializers.HyperlinkedModelSerializer):
     class Meta:
         model = Datacenter
         fields = ('id','name')

我也想在其他方法中使用该服务器列表;

http://127.0.0.1:8000/datacenter/1/Servers

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

嵌套服务器:

如果你想(几乎)完全按照你给出的样本作为样本,那就是:

class ServersSerializer(serializers.ModelSerializer):
    class Meta:
        model = Servers
        fields = ('id', 'hostname')

class DatacenterSerializer(serializers.ModelSerializer):
    servers = ServersSerializer(source='servers_set')

    class Meta:
        model = Datacenter
        fields = ('id', 'name')

如果您想显示两个模型的所有字段,只需删除“&f”字段即可。线。

这也可以在没有source关键字参数的情况下工作,但是需要相关名称来匹配'服务器'属性名称(您可以通过将related_name =' servers'添加到Servers模型上的数据中心字段来实现此目的。)

DRF的文档非常好,你关心的位是serializer relations

深层网址

要实现嵌套的URL结构,您可以简单地创建一个与上面匹配的url模式,如下所示:

url(r'^datacenter/(?P<datacenter_id>\d+)/Servers$', 'views.dc_servers',name="dc_servers")

将使用数据中心的ID作为kwarg datacenter_id来调用您的视图。然后,您将使用该ID通过datacenter_id过滤视图的查询集。

您必须自己研究如何撰写该视图,以下是views docs以帮助您入门。

一些常见的Django提示:模型通常应该具有单数名称而不是复数,并且添加related_name参数通常是一件好事(显式优于隐式)。

答案 1 :(得分:1)

要显示服务器,您可以在序列化程序上执行此操作:

class DatacenterSerializer(serializers.HyperlinkedModelSerializer): 

    servers = serializers.HyperlinkedRelatedField(
        many=True
    )
    class Meta: 
        model = Datacenter 
        fields = ('id','name', 'servers')

如果要显示服务器的多个字段,则应创建一个ServerSerializer,其中包含您要显示的字段,然后替换该行:

    servers = serializers.HyperlinkedRelatedField(
        many=True
    )

使用:

    servers = ServerSerializer(many=True)

有关详细信息,请查看文档:{​​{3}}

答案 2 :(得分:1)

谢谢你们的回答,最后我要做的就是在模型中添加related_name,现在看起来像这样;

class Datacenter(models.Model):

name = models.CharField(max_length=50)
status = models.CharField(max_length=50)

def __unicode__(self):
    return self.name

class Servers(models.Model):

datacenter = models.ForeignKey(Datacenter,related_name="servers")
hostname = models.CharField(max_length=50)

def __unicode__(self):
    return self.hostname

关于深度URL,我正在检查文档,应该可以使用SimpleRouter完成,但找不到任何示例来查看如何实现它; {前缀} / {查找} / {方法名} /

http://www.django-rest-framework.org/api-guide/routers/