Django Rest框架属性错误

Posted

技术标签:

【中文标题】Django Rest框架属性错误【英文标题】:Django Rest framework attributeerror 【发布时间】:2017-07-28 22:22:00 【问题描述】:

我正在阅读一本介绍 Django 和 Django Rest 框架的书。本教程创建了一个包含游戏、类别、玩家和分数的休息 API,它们之间具有合适的关系模型。 我在插入游戏类别时偶然发现了一个问题,我收到以下错误:

AttributeError at /game-categories/
'GameCategory' object has no attribute 'games'
Request Method: POST
Request URL:    http://127.0.0.1:8000/game-categories/
Django Version: 1.10.5
Exception Type: AttributeError
Exception Value:    
'GameCategory' object has no attribute 'games'
Exception Location: C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\fields.py in get_attribute, line 103
Python Executable:  C:\Users\user\AppData\Local\Programs\Python\Python36-32\python.exe
Python Version: 3.6.0
Python Path:    
['C:\\Python\\Django01\\gamesapi',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36-32\\python36.zip',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36-32\\DLLs',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36-32\\lib',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36-32',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages']
Server time:    Wed, 8 Mar 2017 09:40:42 +0000

我的GameGameCategory型号如下:

class GameCategory(models.Model):
    name = models.CharField(max_length=200)

    class Meta:
        ordering = ('name',)

    def __str__(self):
        return self.name

class Game(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=200, blank=True, default='')
    game_category = models.ForeignKey(GameCategory, related_name='games', on_delete=models.CASCADE)
    release_date = models.DateTimeField()
    game_category = models.CharField(max_length=200, blank=True, default='')
    played = models.BooleanField(default=False)

    class Meta:
        ordering = ('name',)
    def __str__(self):
        return self.name

还有我的 urls.py 的 sn-p:

urlpatterns = [
    url(r'^game-categories/$', views.GameCategoryList.as_view(),name=views.GameCategoryList.name),
    url(r'^game-categories/(?P<pk>[0-9]+)$', views.GameCategoryDetail.as_view(), name=views.GameCategoryDetail.name),

views.py:

from games.models import GameCategory
from games.models import Game
from games.models import Player
from games.models import PlayerScore    
from games.serializers import GameCategorySerializer
from games.serializers import GameSerializer
from games.serializers import PlayerSerializer
from games.serializers import PlayerScoreSerializer
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.reverse import reverse

class GameCategoryList(generics.ListCreateAPIView):
    queryset=GameCategory.objects.all()
    serializer_class=GameCategorySerializer
    name='gamecategory-list'

class GameCategoryDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset=GameCategory.objects.all()
    serializer_class = GameCategorySerializer
    name = 'gamecategory-detail'

class GameList(generics.ListCreateAPIView):
    queryset=Game.objects.all()
    serializer_class = GameSerializer
    name = 'game-detail'

class GameDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset=Game.objects.all()
    serializer_class=GameSerializer
    name='game-detail'

序列化器.py

from rest_framework import serializers
from games.models import GameCategory
from games.models import Game
from games.models import Player
from games.models import PlayerScore
import games.views

class GameCategorySerializer(serializers.HyperlinkedModelSerializer):
    games = serializers.HyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='game-detail'
    )

    class Meta:
        model = GameCategory
        fields = ('url','pk','name','games')

class GameSerializer(serializers.HyperlinkedModelSerializer):
    #We want to display the game categorys name instead of the id
    game_category = serializers.SlugRelatedField(queryset=GameCategory.objects.all(), slug_field='name')

    class Meta:
        model = Game
        fields = (
            'url',
            'game_category',
            'name',
            'release_date',
            'played'
        )

我对 Python 还是很陌生,更不用说 Django,所以我很难从给出的调试信息中找出错误。

谁能帮我理解问题出在哪里以及为什么?

【问题讨论】:

【参考方案1】:

GameCategorySerializer 中删除HyperlinkedModelSerializer 怎么样?

class GameCategorySerializer(serializers.ModelSerializer):
    # rest here unchanged

查看here了解更多信息。

[更新]:Game 模型中有重复项!

game_category = models.ForeignKey(GameCategory, related_name='games', on_delete=models.CASCADE)

game_category = models.CharField(max_length=200, blank=True, default='')

您应该将第二个 game_category 字段重命名为其他名称。因此,您得到的错误。 GameCategorySerializer 尝试处理此字段(它没有 related_name 属性)而不是第一个 (ForeignKey) 字段。

【讨论】:

谢谢,但不幸的是它没有任何区别。完全相同的错误。 我想我找到了...更新了我的答案! 你是对的。这确实是重复的。你是如何从错误中推断出来的?我现在有另一个错误(没有这样的列:games_game.game_category_id),但我更想知道如何自己调试这些。有任何想法吗?谢谢 我没有从错误中解决它。我只是将您的代码复制粘贴到我的 IDE 中并立即突出显示它!您也应该使用 IDE。它使开发变得容易得多!关于另一个错误,似乎数据库在表games_game 下没有列game_category_id(经典数据库错误)。那么,解决方案是什么?需要的话戳我! 太棒了。谢谢。删除了我的迁移文件夹(和数据库),重新运行迁移及其现在的工作。关于 Python 的(免费)IDE 有什么建议吗?尽可能轻量化。干杯

以上是关于Django Rest框架属性错误的主要内容,如果未能解决你的问题,请参考以下文章

django.test.client 上的 Django rest 框架导入错误

django rest框架错误需要一个字段

Django rest框架:如何全局更改错误响应格式

如何使用 django rest 框架禁用 HTML 错误页面的返回?

Django rest 框架,Django 通道,Ionic2 - websocket 握手错误

为啥通过 django rest 框架注册用户时出现状态码错误