简体   繁体   中英

Django REST framework: “invalid keyword argument” error but field exists in the model

I'm using Django with the REST Framework. I'm defining an APIView and in it, I create an ORM object using create(). One of the fields I pass the create function is failing, saying it's not a valid keyword argument. This is a new field I'm adding. The field exists in the model and the serializer. Another similar new field is NOT failing.

Traceback:

Internal Server Error: /api/new_thing
Traceback (most recent call last):
  File "/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/local/lib/python2.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/local/lib/python2.7/site-packages/rest_framework/views.py", line 466, in dispatch
    response = self.handle_exception(exc)
  File "/local/lib/python2.7/site-packages/rest_framework/views.py", line 463, in dispatch
    response = handler(request, *args, **kwargs)
  File "/other_app/rest_apis.py", line 336, in post
    flag=false
  File "/local/lib/python2.7/site-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/local/lib/python2.7/site-packages/django/db/models/query.py", line 346, in create
    obj = self.model(**kwargs)
  File "/local/lib/python2.7/site-packages/django/db/models/base.py", line 480, in __init__
    raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'doohickeys' is an invalid keyword argument for this function

API View:

class NewThing(APIView):

    renderer_classes = (JSONRenderer,)
    serializer_class = StuffSerializer

    @detail_route(methods=['POST'])
    def post(self, request, pk, format=None):
        # do stuff
        whatsits_list = [] # list of ORM objects
        doohickeys_list = [] # list of ORM objects
        thing = Thing.objects.create(
            whatsits=whatsits_list, # this is not failing
            doohickeys=doohickeys_list, # this is failing
            flag=false
        )
        # return some stuff

Model:

from django.db import models
from other_app.models import Doohickey, Whatsit

class Thing(models.Model):
    whatsits = models.ManyToManyField('other_app.Whatsit', related_name='things', blank=True)    
    doohickeys = models.ManyToManyField('other_app.Doohickey', related_name='things', blank=True)
    flag = models.BooleanField(default=True)

Serializer:

class StuffSerializer(serializers.ModelSerializer):
    doohickeys = serializers.PrimaryKeyRelatedField(queryset=Doohickey.objects.all(), many=True, allow_empty=True)

    class Meta:
        model = Stuff
        fields = ('id',
                  'doohickeys',
                  'whatsits',
                  'public',
        )

Any idea why I'm getting an error on the doohickey key? I've tried using a debugger to trace through the code and it looks like it's an exception being caught by the dispatch() function in the REST framework APIView class.

Thanks!

You can't use a many-to-many field until the object is saved, because it's really a through table that uses the IDs of the objects on each side. So create the object first, then add the doohickeys.

thing = Thing.objects.create(...)
thing.doohickeys.add(*doohickeys_list)

Note though what you're doing is quite odd. The whole point of django-rest-framework is that you use the serializer, which takes care of all this logic for you - you have defined a serializer but you're not using it, you seem to be bypassing that completely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM