Reputation: 5723
I'm trying to convert my existing DJANGO app to API based. I have done the front-end in Angular and working on the backend now. The data from client is going to be in json format as below
{
"title": "wue",
"author": "asd",
"addons": {
"header":"head",
"footer":"foot"
}
}
I have written the model.py
class BookDetails(models.Model):
title= models.CharField(max_length=10)
author= models.CharField(max_length=10)
addons= models.ForeignKey(Addons, null=True)
class Addons(models.Model):
header= models.CharField(max_length=10)
footer= models.CharField(max_length=10)
serializer.py
class AddonsSerializer(serializers.ModelSerializer):
class Meta:
model = Addons
fields = ('header', 'footer')
depth = 2
class BookDetailsSerializer(serializers.ModelSerializer):
addons = AddonsSerializer(many=False, read_only=True)
class Meta:
model = BookDetails
depth = 2
fields = ('title', 'author','addons')
views.py
class BookDetailsList(APIView):
def get(self, request):
stocks = BookDetails.objects.all()
serializers = BookDetailsSerializer(stocks, many=True)
return Response(serializers.data)
def post(self, request):
serializer = BookDetailsSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
my urls.py is
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^bookdetails/', views.BookDetailsList.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Now when I'm using postman to send the data then the addons field is not getting populated, it gets null value.
I have tried to write a custom create but I think somewhere I'm messing it up, but not able to figure out where.
def create(self, validated_data):
tracks_data = validated_data.pop('addons')
addons = BookDetails.objects.create(**validated_data)
Addons.objects.create(addons=addons, **tracks_data)
return addons
it gives me an error that
KeyError at /bookdetails/ 'addons'
I have tried assigning depth=2 but it is not working. what is that I'm doing wrong?
Edit 1 (removed read_only=True) still no luck:
Traceback (most recent call last):
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/argo/Django/pagination-backend/backend/publishbook/views.py", line 19, in post
serializer.save()
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/rest_framework/serializers.py", line 214, in save
self.instance = self.create(validated_data)
File "/Users/argo/Django/pagination-backend/backend/publishbook/serializers.py", line 26, in create
Addons.objects.create(addons=addons, **tracks_data)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/django/db/models/manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/django/db/models/query.py", line 399, in create
obj = self.model(**kwargs)
File "/Users/argo/Django/pagination-backend/env/lib/python3.5/site-packages/django/db/models/base.py", line 443, in __init__
raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'addons' is an invalid keyword argument for this function
Upvotes: 1
Views: 2421
Reputation: 9235
I think its your create method you need to rectify. You've got a Bookdetails model with a ForeignKey to Addon model. From my point of view, the code should be something like this, (You should remove read_only=True, Obviously)
def create(self, validated_data):
tracks_data = validated_data.pop('addons')
book_details = BookDetails.objects.create(**validated_data)
addons = Addons.objects.create(**tracks_data)
book_details.addons = addons
book_details.save()
return book_details
Hope you got what were you looking for.
Seriously, you need to re-consider about your naming conventions.
Upvotes: 0
Reputation: 2172
You are adding book details as addon to addon model itself, try updationg your code like this,
def create(self, validated_data):
tracks_data = validated_data.pop('addons')
addons = Addons.objects.create(**tracks_data)
book = BookDetails.objects.create(addons=addons, **validated_data)
return book
Upvotes: 1
Reputation: 3223
You have read_only=True
specified in your addons
field in your BookDetailsSerializer
. This prevents the addons part of the json dictionary being passed to your create
method. That's why there's a KeyError on your attempt to pop
(I guess, although if you pasted your stacktrace rather than just the error it would help).
Other than that, I'm not sure about your create
method - perhaps you could reformat it so the variable names are more meaningful. You still have the tracks_data
from the DRF example, and you've named the product of your BookDetails
create 'addons' - which doesn't really make sense and makes it hard to read. Also, could you specify which serializer the create
method is part of, as it's hard to tell just by looking at it.
Note: In general it's conventional to give Django model names singular form, so yours would be BookDetail and Addon.
Update after question edit:
Now you have an error on this line: Addons.objects.create(addons=addons, **tracks_data)
.
The error is telling you that addons
is not a valid field on the Addons
model. I think it would work just to do Addons.objects.create(**tracks_data)
.
Upvotes: 0