django rest框架中的嵌套关​​系

时间:2015-02-20 06:07:32

标签: python json django rest django-rest-framework

请帮我解决这个django REST框架问题。我正在尝试创建rest api,它将根据传递的参数在两个表中填充数据。

我的模特看起来像。

class WorkloadType(models.Model):

    type = models.CharField(max_length=60)
    status = models.BooleanField(default=True)


class Workload(models.Model):

    workload_type =  models.ForeignKey(WorkloadType)
    workload_group = models.IntegerField(blank=True, null=True)
    name = models.CharField(max_length = 60)
    hdd_gb = models.IntegerField(blank=True, null=True)
    ssd_gb = models.IntegerField(blank=True, null=True)
    iops = models.CharField(max_length = 60)
    vcpu  = models.IntegerField(blank=True, null=True)
    cpu = models.IntegerField(blank=True, null=True)
    created_date = models.DateTimeField(auto_now_add=True, blank=True)
    status = models.BooleanField(default=True)

class VdiWorkload(models.Model):

    workload = models.ForeignKey(Workload)
    provision_type = models.CharField(max_length = 60)
    number_of_users = models.IntegerField()
    json_data =  models.CharField(max_length=255,blank = True,null = True)
    status = models.BooleanField(default=True)
    created_date = models.DateTimeField(auto_now_add=True, blank=True) 

我的serializer.py文件看起来像。

from django.forms import widgets
from rest_framework import serializers
from models import WorkloadType,Workload, \
    VdiWorkload,DbWorkload,\
    VmWorkload,ExchangeWorkload,RawWorkload
class VdiSerializer(serializers.Serializer):


    class Meta:
        model = VdiWorkload


class WorkloadSerializer(serializers.Serializer):

    vdi = VdiSerializer(required = False)
    pk = serializers.IntegerField(read_only=True)
    workload_group =  serializers.IntegerField(required=False)
    workload_type = serializers.CharField(max_length = 10)
    name = serializers.CharField(max_length = 60)
    hdd_gb = serializers.IntegerField()
    ssd_gb = serializers.IntegerField()
    iops = serializers.CharField(max_length = 60)
    vcpu  = serializers.IntegerField()
    cpu = serializers.IntegerField()

    class Meta:
        model = Workload
        fields = ('vdi','workload_group','workload_type','name','hdd_gb','ssd_gb','iops','vcpu','cpu')

    def create(self, validated_data):
        """
        Create and return a new `Workload` instance, given the validated data.
        """

        wt = WorkloadType.objects.get(type = validated_data['workload_type'])
        validated_data['workload_type'] = wt
        print "=-=-=-=-=-=-=-=-=-=-=-=-=------"
        if not validated_data['workload_group']:
            workload_group = Workload.objects.latest('workload_group')
            validated_data['workload_group'] = workload_group
        else:
            try:
                workload_group = Workload.objects.latest('workload_group')
                validated_data['workload_group'] = workload_group + 1
            except:validated_data['workload_group']  = 1

        #try:node_exist = Workload.objects.get(name = validated_data['name'])
        #except:node_exist = None
        #if node_exist:
        #    raise  serializers.ValidationError('Node name already exist.')
        #else:
        wl = Workload.objects.create(**validated_data)
        VdiWorkload.objects.create(workload=wl, **validated_data)

        return wl

现在我把剩下的身体传递过来了。

{
   "type": "Exchange",
   "iops": "22",
   "name": "another model",
   "hdd_gb": "23",
   "ssd_gb": "320",
   "hdd_count": "123",
   "ssd_count": "4",
   "memory": "123",
   "core": "114",
   "rackspace": "6",
   "vcpu":"12",
   "workload_type":"VDI",
   "workload_group":true,
  "cpu":"1",
  "vdi":[{
                 "provision_type":"user",
                 "number_of_users":"10",
                 "json_data":"any extra data which we want"
             }]

}

但每当我发帖请求时,我都会收到错误

回溯

raceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/csrf.py" in wrapped_view
77. return view_func(*args, **kwargs)
File "/home/rohit/workspace/sizer/src/sizer/Workload/views.py" in workload_list
49. serializer.save()
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in save
164. self.instance = self.create(validated_data)
File "/home/rohit/workspace/sizer/src/sizer/Workload/WorkloadSerializer.py" in create
63. return Workload.objects.create(**validated_data)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py" in create
137. return self.get_query_set().create(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in create
375. obj = self.model(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in __init__
367. raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0])

Exception Type: TypeError at /workload/workloadlist/
Exception Value: 'vdi' is an invalid keyword argument for this functi

如果您需要任何其他信息,请告诉我,我仍然无法解决这个问题。

我无法识别此问题,因为我是DRF的新手。

请让我知道我在这里做错了什么。我的观点看起来很像。

@csrf_exempt
def workload_list(request):
    """
    List all code users, or create a new user.
    """
    print "Herer I am *****************************111111"
    if request.method == 'GET':
        print "Herer I am *****************************"
        workloads = Workload.objects.all()
        serializer = WorkloadSerializer(workloads, many=True)
        return JSONResponse(serializer.data)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = WorkloadSerializer(data=data)
        print serializer
        print "****************** I am in ***********views now "
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data, status=201)
        return JSONResponse(serializer.errors, status=400)

1 个答案:

答案 0 :(得分:1)

请原谅我,如果这是偏离轨道,但在我看来,模型对嵌套字段(vdi)一无所知。您是否尝试将其从validated_data中弹出?

这是一个小的(未经测试的)我使用Django == 1.7使用djangorestframework == 3.1.3的例子。

models.py:

class Child(models.Model):
    child_data = models.CharField(max_length=255)

class Parent(models.Model):
    # Set 'related_name' to the nested field name in the serializer.
    child_id = models.ForeignKey(Child, related_name='child')

serializers.py:

class ChildSerializer(serializers.ModelSerializer):
    class Meta:
        model = Child

class ParentSerializer(serializers.ModelSerializer):
    # The ForeignKey in the model is supplied with this name so that GET
    # requests can populate this and the source field below makes it
    # accessible in create after validation.
    child = TestInfoSerializer(source='child_id')

    class Meta:
        model = Parent
    fields = ('child', )

    def create(self, validated_data):
        child_data = validated_data.pop('child_id')  # strip out child_id for subsequent Parent create
        try:
            # try to find an existing row to fulfill the foreign key
            child_instance = Child.objects.filter(**child_data)[0]
        except IndexError:
            # create a new row
            child_instance = Child.objects.create(**child_data)
        return Parent.objects.create(child_id=child_instance, **validated_data)

有了这个,我可以在不考虑外键的情况下POST嵌套JSON:

{
    "child": {
        "child_data": "asdf"
    }
}

GET也会使用此设置返回嵌套表示。

我希望这会有所帮助。