Reputation: 60
Please help me out of this django REST framework issue .I am trying to create on rest api which which will populate data in two tables based on argument passed .
My models look like .
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)
I have my serializer.py file which is looking like .
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
Now I passing the rest body like.
{
"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"
}]
}
But whenever I am making post request I am getting the error
Traceback
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
Please do let me know if you need any other info I am still not able to solve out this question .
I am not able to identify this issue as I am new in DRF .
Please do let me know what might I am doing wrong here .My views looklike .
@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)
Upvotes: 0
Views: 1424
Reputation: 359
Forgive me if this is off track but it looks to me like the model doesn't know anything about the nested field (vdi). Did you try popping it off validated_data?
Here's a small (untested) example of what I have been working on using djangorestframework==3.1.3 with 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)
With this I can POST nested JSON without thinking about the foreign key:
{
"child": {
"child_data": "asdf"
}
}
GET also returns the nested representation with this setup.
I hope this helps.
Upvotes: 1