我正在通过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技术。我做错了什么吗?教程中是否有错误?