在将我学到的技能应用到更大的企业项目之前,我正在开发一个小项目来练习Django REST Framework(以及后来的React前端)。
该项目是一个后端API,可以让某人看到主角在费城永远阳光的每一集中犯下的潜在罪行和侵权行为。为此,我创建了this GitHub存储库并在其中放置了一个Django项目。
我发现自己在浏览器调试视图中遇到错误,我在为网站添加新的模型/序列化/视图时无法弄清楚:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/characters/
Django Version: 1.10.6
Python Version: 3.6.0
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'offense_api.apps.OffenseApiConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/Users/person/.virtualenvs/IASIP/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
42. response = get_response(request)
File "/Users/person/.virtualenvs/IASIP/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/Users/person/.virtualenvs/IASIP/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/person/.virtualenvs/IASIP/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/Users/person/Workspace/IASIP_API/offense_api/views.py" in character_list
70. return JsonResponse(serializer.data, safe=False)
File "/Users/person/.virtualenvs/IASIP/lib/python3.6/site-packages/rest_framework/serializers.py" in data
729. ret = super(ListSerializer, self).data
File "/Users/person/.virtualenvs/IASIP/lib/python3.6/site-packages/rest_framework/serializers.py" in data
262. self._data = self.to_representation(self.instance)
File "/Users/person/.virtualenvs/IASIP/lib/python3.6/site-packages/rest_framework/serializers.py" in to_representation
647. self.child.to_representation(item) for item in iterable
Exception Type: TypeError at /characters/
Exception Value: 'ModelBase' object is not iterable
这只发生在“字符”页面上,该页面应与我的其他列表视图相同,即季节列表。
Serializers.py
from rest_framework import serializers
from offense_api.models import Season, Episode, Character
class SeasonSerializer(serializers.ModelSerializer):
episodes = serializers.StringRelatedField(many=True)
class Meta:
model = Season
fields = ('season_number', 'episodes')
class EpisodeSerializer(serializers.ModelSerializer):
class Meta:
model = Episode
fields = ('episode_number', 'episode_title', 'episode_season')
class CharacterSerializer(serializers.ModelSerializer):
class Meta:
model = Character
fields = ('character_legal_first_name', 'character_legal_last_name', 'character_preferred_name',)
Models.py
from django.db import models
class Season(models.Model):
season_created = models.DateTimeField(auto_now_add=True)
season_number = models.IntegerField(unique=True)
def __unicode__(self):
return self.season_number
def __str__(self):
return str(self.season_number)
class Episode(models.Model):
episode_season = models.ForeignKey(Season, related_name='episodes', on_delete=models.CASCADE)
episode_created = models.DateTimeField(auto_now_add=True)
episode_number = models.IntegerField()
episode_title = models.CharField(max_length=300, default='')
def __unicode__(self):
return '%d. %d' % (self.episode_season.season_number, self.episode_number)
def __str__(self):
return '%d. %d' % (self.episode_season.season_number, self.episode_number)
class Meta:
unique_together = ('episode_season', 'episode_number')
ordering = ('episode_number',)
class Character(models.Model):
character_created = models.DateTimeField(auto_now_add=True)
character_legal_first_name = models.CharField(max_length=50, default='', null=True)
character_legal_last_name = models.CharField(max_length=100, default='', null=True)
character_preferred_name = models.CharField(max_length=150, default='', primary_key=True)
def __unicode__(self):
return self.character_preferred_name
def __str__(self):
return self.character_preferred_name
class Meta:
ordering = ('character_preferred_name',)
Views.py
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from offense_api.models import Episode, Season, Character
from offense_api.serializers import EpisodeSerializer, SeasonSerializer, CharacterSerializer
@csrf_exempt
def season_list(request):
"""
List all seasons, or create a new one.
:param request:
:return:
"""
if request.method == 'GET':
seasons = Season.objects.all()
serializer = SeasonSerializer(seasons, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = SeasonSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
@csrf_exempt
def season_detail(request, pk):
"""
Retrieve, update, or delete a season.
:param request:
:param pk:
:return:
"""
try:
season = Season.objects.get(pk=pk)
except Season.DoesNotExist:
return HttpResponse(status=404)
if request.method == 'GET':
serializer = SeasonSerializer(season)
return JsonResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = SeasonSerializer(season, data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status=400)
elif request.method == 'DELETE':
season.delete()
return HttpResponse(status=204)
@csrf_exempt
def character_list(request):
"""
List all characters, or create a new one.
:param request:
:return:
"""
if request.method == 'GET':
characters = Character.objects.all()
serializer = CharacterSerializer(Character, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = CharacterSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
Urls.py
from django.conf.urls import url
from offense_api import views
urlpatterns = [
url(r'^seasons/$', views.season_list),
url(r'^seasons/(?P<pk>[0-9]+)/$', views.season_detail),
url(r'^characters/$', views.character_list),
]
需要修改哪些内容才能解决此错误?
答案 0 :(得分:2)
在views.py中,您将类Character传递给序列化程序。您应该传递数据字符。
也不要使用首选名称作为主键,它可能很容易变得非唯一