2017-03-08 2 views
0

Je travaille sur un livre qui présente Django et le framework de repos django. Le tutoriel crée une API de repos avec des jeux, des catégories, des joueurs et des scores avec un modèle relationnel approprié entre eux. Je suis tombé sur un problème lors de l'insertion d'une catégorie de jeu, je reçois l'erreur suivante:django rest framework attributeerror

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 

Mes modèles de jeu et GameCategory sont les suivantes:

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 

et l'extrait de mon urls.py :

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' 

serializers.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' 
     ) 

Je suis encore très nouveau pour Python, et encore moins django si mal à la source de l'erreur ici à partir des informations de débogage donné. Est-ce que quelqu'un peut m'aider à comprendre où est le problème et pourquoi?

Merci

Répondre

1

Que diriez-vous de retirer HyperlinkedModelSerializer de GameCategorySerializer?

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

Vérifiez here pour plus d'informations. [UPDATE]: Vous avez une duplication à l'intérieur du modèle Game!

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

et

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

Vous devez renommer le deuxième champ game_category à autre chose. Ainsi, l'erreur que vous obtenez. GameCategorySerializer essaie de gérer ce champ (qui n'a pas d'attribut related_name) au lieu du premier (ForeignKey).

+0

Merci, mais malheureusement, cela n'a fait aucune différence. Exact même erreur. – LDJ

+0

Je pense que je l'ai trouvé ... Mis à jour ma réponse! –

+0

Vous avez raison. C'était en effet un doublon. Comment l'avez-vous déduit de l'erreur? J'ai une autre erreur maintenant (pas une telle colonne: games_game.game_category_id) mais je préférerais savoir comment déboguer moi-même. Des idées? Merci – LDJ