【问题标题】:Nested Relationship in django rest frameworkdjango rest框架中的嵌套关​​系
【发布时间】:2015-02-20 06:07:32
【问题描述】:

请帮我解决这个 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)

【问题讨论】:

  • 您的 serializers.py 中有哪些导入?
  • @ssbrewster serializer.py 在模型之后给出
  • 对不起,我不清楚 - 您在 serializers.py 文件顶部的导入是什么?它们没有显示在您问题的代码中

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


【解决方案1】:

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

这是我一直在使用 djangorestframework==3.1.3 和 Django==1.7 的一个小型(未经测试)示例。

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)

有了这个我可以发布嵌套的 JSON 而无需考虑外键:

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

GET 还通过此设置返回嵌套表示。

我希望这会有所帮助。

【讨论】:

  • 仅供参考,简化变量命名(删除 _id)可以使此示例在不需要源和相关名称参数的情况下运行。
猜你喜欢
  • 2014-09-18
  • 2017-06-28
  • 2016-05-30
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 2018-10-05
  • 2020-11-07
  • 2014-05-21
相关资源
最近更新 更多