不要了解Django REST Framework KeyError

时间:2018-04-17 16:44:24

标签: django django-rest-framework

我正在通过Django REST Framework v.2 tutorial工作,我收到一个我不明白的错误。本教程介绍如何创建一个突出显示Web API的简单pastebin代码。首先创建以下模型并使用几个片段加载它:

# models.py
class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(choices=LANGUAGE_CHOICES,
                                default='python',
                                max_length=100)
    style = models.CharField(choices=STYLE_CHOICES,
                             default='friendly',
                             max_length=100)

    class Meta:
        ordering = ('created',)

# Python console
snippet = Snippet(code='foo = "bar"\n')
snippet.save()

snippet = Snippet(code='print "hello, world"\n')
snippet.save()

然后创建一个序列化程序类,将代码段实例序列化和反序列化为JSON:

# serializers.py
class SnippetSerializer(serializers.Serializer):
    pk = serializers.Field()  # Note: `Field` is an untyped read-only field.
    title = serializers.CharField(required=False,
                                  max_length=100)
    code = serializers.CharField(widget=widgets.Textarea,
                                 max_length=100000)
    linenos = serializers.BooleanField(required=False)
    language = serializers.ChoiceField(choices=LANGUAGE_CHOICES,
                                       default='python')
    style = serializers.ChoiceField(choices=STYLE_CHOICES,
                                    default='friendly')

    def restore_object(self, attrs, instance=None):
        """
        Create or update a new snippet instance, given a dictionary
        of deserialized field values.

        Note that if we don't define this method, then deserializing
        data will simply return a dictionary of items.
        """
        if instance:
            # Update existing instance
            instance.title = attrs.get('title', instance.title)
            instance.code = attrs.get('code', instance.code)
            instance.linenos = attrs.get('linenos', instance.linenos)
            instance.language = attrs.get('language', instance.language)
            instance.style = attrs.get('style', instance.style)
            return instance

        # Create new instance
        return Snippet(**attrs)

你还创建了两个CBV(我不会在这里包含它们,代码可以在上面的链接中看到),其中包含' snippet_list'和' snippet_detail'通过这些urlconf调用的视图:

# urls.py
urlpatterns = [
    url(r'^snippets/$', views.snippet_list),
    url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),
]

如果您随后执行这两个curl命令,则会获得特定代码段的片段或详细信息列表:

curl http://127.0.0.1:8000/snippets/
curl http://127.0.0.1:8000/snippets/2/

这些命令工作得很好。但是教程接着用一个简单的ModelSerializer类替换上面显示的代码片段类:

# serializers.py
class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')

但是,当我进行此替换并重新启动服务器时,我收到此错误:

KeyError at /snippets/
'id'
Request Method: GET
Request URL:  http://127.0.0.1:8000/snippets/
Django Version: 1.8.4
Exception Type: KeyError
Exception Value:
'id'
Exception Location: /Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/rest_framework/serializers.py in get_fields, line 257
Python Executable:  /Users/smith/.virtualenvs/django184/bin/python
Python Version: 2.7.13

Request Method: GET
Request URL: http://127.0.0.1:8000/snippets/

Django Version: 1.8.4
Python Version: 2.7.13
# ... Application and Middleware stuff

Traceback:
File "/Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)
File "/Users/smith/code/django/drf2/snippets/views.py" in snippet_list
  29.         return JSONResponse(serializer.data)
File "/Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/rest_framework/serializers.py" in data
  581.                 self._data = [self.to_native(item) for item in obj]
File "/Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/rest_framework/serializers.py" in to_native
  357.         for field_name, field in self.fields.items():
File "/Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/django/utils/functional.py" in __get__
  60.         res = instance.__dict__[self.name] = self.func(instance)
File "/Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/rest_framework/serializers.py" in fields
  224.         return self.get_fields()
File "/Users/smith/.virtualenvs/django184/lib/python2.7/site-packages/rest_framework/serializers.py" in get_fields
  257.                 new[key] = ret[key]

Exception Type: KeyError at /snippets/
Exception Value: 'id'

为了确保我没有创建拼写错误,我将教程中的所有代码剪切并粘贴到我的Django文件中。我也进行了互联网搜索,看看有没有人遇到这个问题。另外,我看到框架版本3的教程和模块作者在版本3中使用了相同的ModelSerializer技术。我做错了什么吗?教程中是否有错误?

0 个答案:

没有答案