2014-10-13 3 views
2

У меня проблема с Django и Django REST Framework.all() получил неожиданный аргумент ключевого слова 'pk' в Django

Когда я перехожу к http://mynameislee.co.uk/albums/, он отлично работает и возвращает Django Framework отлично, но когда я пытаюсь http://mynameislee.co.uk/albums/1 Я получаю all() получил неожиданный аргумент ключевого слова 'pk'.

Это мой код.

urls.py

# API 
url(r'^albums/$', 'canary.views.album_list', name='album_list'), 
url(r'^albums/(?P<pk>[0-9])$', 'canary.views.album_detail', name='album_detail'), 

views.py

@login_required 
@api_view(['GET', 'POST']) 
def album_list(request): 

# List all tasks, or create a new task. 

if request.method == 'GET': 
    album = Album.objects.all() 
    serializer = AlbumSerializer(album, many=True) 
    return Response(serializer.data) 

elif request.method == 'POST': 
    serializer = AlbumSerializer(data=request.DATA) 
if serializer.is_valid(): 
    serializer.save() 
    return Response(serializer.data, status=status.HTTP_201_CREATED) 
else: 
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

@login_required 
@api_view(['GET', 'PUT', 'DELETE']) 
def album_detail(request, pk): 

# Get, update or delete a specific album 

try: 
    album = Album.objects.all(pk=id) 
except Album.DoesNotExist: 
    return Response(status=status.HTTP_404_NOT_FOUND) 

if request.method == 'GET': 
    serializer = AlbumSerializer(album) 
    return Response(serializer.data) 

elif request.method == 'PUT': 
    serializer = AlbumSerializer(album, data=request.DATA) 
    if serializer.is_valid(): 
    serializer.save() 
    return Response(serializer.data) 
else: 
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

elif request.method == 'DELETE': 
    album.delete() 
    return Response(status=status.HTTP_204_NO_CONTENT) 

models.py

class Album(models.Model): 

    album_id = models.AutoField(primary_key=True) 
    artist_name = models.CharField(max_length=255, blank=True) 
    album_name = models.CharField(max_length=255, blank=True) 

    def __unicode__(self): 
     return self.album_name 
+0

Правильное соглашение REST должно состоять в том, чтобы иметь/album/1, not/albums/1. Обратите внимание, что DRF делает все, что ваш код делает автоматически, если вы используете встроенные представления или виды/маршрутизаторы. –

ответ

4

Вы не можете использовать all с набором фильтров.

album = Album.objects.all(pk=id) #wrong 

Использование filter вместо:

album = Album.objects.filter(pk=id) 
>>> type(album) -> 'QuerySet' 

Вот docs с большим количеством примеров.

И как @Bjorn предложил: вы можете также использовать get, что сэкономит вам получать деталь из QuerySet:

album = Album.objects.get(pk=id) 
>>> type(album) -> 'Album' 
+0

Если 'id' - это один элемент, вы также можете использовать' Album.objects.get (pk = id) '. – Bjorn

+0

Boomcubist передает 'pk' в' album_detail', а не 'id' –

+0

Спасибо @RickyA. Меняя его на .filter, я дал QuerySet; Объект не имеет атрибута, но меняет его на .get, исправил мою проблему. – boomcubist

2

Я думаю, что вы хотите

album = Album.objects.filter(pk=id) 

вместо

album = Album.objects.all(pk=id) 
Смежные вопросы