我一直在学习教程here,除了我没有创建代码段网络工具,我正在创建RPG字符管理器,一直在将'snippet
'换成'[ C0]”。另一个主要区别是我的法师通过他们的超类mage
仅拥有一个用户(这是我以后可以添加其他字符类型,如狼人和吸血鬼的用户!)
访问NWODCharacter
时出现此错误:
http://localhost:8000/users/
[它似乎取决于以下事实:我的AttributeError at /users/
'User' object has no attribute 'mages'
Environment:
Request Method: GET
Request URL: http://localhost:8000/users/
Django Version: 1.7.1
Python Version: 3.4.2
Installed Applications:
('autocomplete_light',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'characters')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "C:\Python34\lib\site-packages\django\core\handlers\base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python34\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "C:\Python34\lib\site-packages\django\views\generic\base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\rest_framework\views.py" in dispatch
407. response = self.handle_exception(exc)
File "C:\Python34\lib\site-packages\rest_framework\views.py" in dispatch
404. response = handler(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\rest_framework\generics.py" in get
269. return self.list(request, *args, **kwargs)
File "C:\Python34\lib\site-packages\rest_framework\mixins.py" in list
46. return Response(serializer.data)
File "C:\Python34\lib\site-packages\rest_framework\serializers.py" in data
615. ret = super(ListSerializer, self).data
File "C:\Python34\lib\site-packages\rest_framework\serializers.py" in data
212. self._data = self.to_representation(self.instance)
File "C:\Python34\lib\site-packages\rest_framework\serializers.py" in to_representation
565. self.child.to_representation(item) for item in iterable
File "C:\Python34\lib\site-packages\rest_framework\serializers.py" in <listcomp>
565. self.child.to_representation(item) for item in iterable
File "C:\Python34\lib\site-packages\rest_framework\serializers.py" in to_representation
423. attribute = field.get_attribute(instance)
File "C:\Python34\lib\site-packages\rest_framework\relations.py" in get_attribute
350. relationship = get_attribute(instance, self.source_attrs)
File "C:\Python34\lib\site-packages\rest_framework\fields.py" in get_attribute
69. instance = getattr(instance, attr)
Exception Type: AttributeError at /users/
Exception Value: 'User' object has no attribute 'mages'
模型将FK固定到django定义的Mage
,而django-rest-frameworks需要做一些魔术才能将两者连接起来。但是我使用继承的事实在某种程度上阻止了django-rest-frameworks mojo。
所以我的模型看起来像:
User
我的序列化器看起来像这样:
class NWODCharacter(models.Model):
class Meta:
abstract = True
SUB_RACE_CHOICES = ()
FACTION_CHOICES = ()
name = models.CharField(max_length=200)
player = models.ForeignKey('auth.User')
created_date = models.DateTimeField(auto_now_add=True, auto_now=False)
updated_date = models.DateTimeField(auto_now_add=False, auto_now=True)
published_date = models.DateTimeField(blank=True, null=True)
sub_race = models.CharField(choices=SUB_RACE_CHOICES, max_length=50)
faction = models.CharField(
choices=FACTION_CHOICES, max_length=50, null=True)
class Characteristics(models.Model):
class Meta:
abstract = True
VIRTUE_CHOICES = (('prudence', 'Prudence'), ('justice', 'Justice'),
('temperance', 'Temperance'), ('fortitude',
'Fortitude'), ('faith', 'Faith'),
('hope', 'Hope'), ('charity', 'Charity'))
VICE_CHOICES = (('lust', 'Lust'), ('gluttony', 'Gluttony'), ('greed', 'Greed'),
('sloth', 'Sloth'), ('wrath', 'Wrath'), ('envy', 'Envy'), ('pride', 'Pride'))
power_level = IntegerRangeField(min_value=1, max_value=10, default=1)
energy_trait = IntegerRangeField(min_value=1, max_value=10, default=7)
virtue = models.CharField(choices=VIRTUE_CHOICES, max_length=50)
vice = models.CharField(choices=VICE_CHOICES, max_length=50)
morality = IntegerRangeField(min_value=0, max_value=10, default=7)
size = IntegerRangeField(min_value=1, max_value=10, default=5)
class Mage(NWODCharacter, Characteristics):
def __str__(self):
return self.name
这些是我的简单观点
class MageSerializer(serializers.ModelSerializer):
player = serializers.ReadOnlyField(source='player.username')
class Meta:
model = Mage
fields = ('id', 'player', 'name', 'created_date', 'updated_date', 'published_date',
'sub_race', 'faction', 'power_level', 'energy_trait', 'virtue', 'vice', 'morality', 'size',)
class UserSerializer(serializers.ModelSerializer):
mages = serializers.PrimaryKeyRelatedField(
many=True, queryset=Mage.objects.all())
class Meta:
model = User
fields = ('id', 'username', 'mages')
如何解决这种差异?
您需要使用相关名称来从用户访问法师。但是在您的情况下,您正在使用抽象类。
您需要像这样更改外键class MageList(generics.ListCreateAPIView):
queryset = Mage.objects.all()
serializer_class = MageSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
def perform_create(self, serializer):
serializer.save(player=self.request.user)
class MageDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Mage.objects.all()
serializer_class = MageSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
:player
然后在序列化器中使用该相关名称:
player = models.ForeignKey('auth.User', related_name="%(class)s_by_user")
在此处了解更多信息:class UserSerializer(serializers.ModelSerializer):
mage_by_user = serializers.PrimaryKeyRelatedField(
many=True, queryset=Mage.objects.all())
class Meta:
model = User
fields = ('id', 'username', 'mage_by_user')