Django Rest Framework - 如何在使用ListCreateAPIView时进行POST

时间:2017-05-27 15:08:52

标签: django django-rest-framework

我对如何执行我认为应该能够解决的问题感到很困惑,但几个小时后我感到很茫然。我正在学习Django和DRF所以一切看起来都很艰难。

我使用Django Rest Framework编写了一个API。我可以在NOTE Serializer上执行GET请求而不是PUSH请求(我可以推送到STOCK serializer罚款)。根据我编写的代码(使用Django Rest Framework网站上的说明),当我尝试使用以下命令进行POST时:

http POST http://127.0.0.1:8000/api/v1/notes/ note='api test' {"stock":"test"} 'Authorization: Token 1235454545656'

我收到以下错误:

HTTP/1.0 400 Bad Request
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Date: Sat, 27 May 2017 14:51:52 GMT
Server: WSGIServer/0.2 CPython/3.6.0
Vary: Accept
X-Frame-Options: SAMEORIGIN

{
    "stock": [
        "This field is required."
    ]
}

我知道这是必需的...这就是为什么我把它包含在PUSH请求中的原因!有人可以解释我做错了什么以及如何纠正它?

这是我的book/models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
import uuid

class Stock(models.Model):
    '''
    Model representing the stock info.
    '''
    user = models.ForeignKey(User)
    book_code = models.CharField(max_length=14, null=True, blank=True)

    def __str__(self):
        return self.book_code

class Note(models.Model):
    '''
    Model representing the stock note.
    '''
    user = models.ForeignKey(User)
    note = models.TextField(max_length=560)
    stock = models.ForeignKey(Stock)
    date_note_created = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.note

这是我的api/serializer.py

from bookstock.models import Stock, Note
from rest_framework import serializers

class StockSerializer(serializers.ModelSerializer):

    class Meta:
        model = Stock
        fields = ('id', 'user', 'book_code')

class NoteSerializer(serializers.ModelSerializer):
    stock = StockSerializer(many=True)
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())


    class Meta:
        model = Note
        fields = ('user', 'note', 'stock', 'date_note_created')

这是我的api/views.py

from rest_framework import generics
from bookstock.models import Stock, Note
from api.serializers import StockSerializer
from rest_framework.permissions import IsAuthenticated

class StockList(generics.ListCreateAPIView):
    serializer_class = StockSerializer
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        user = self.request.user
        return Stock.objects.filter(user=user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user, )

    def perform_update(self, serializer):
        serializer.save(user=self.request.user)

class NoteList(generics.ListCreateAPIView):
    serializer_class = NoteSerializer
    permission_classes = (IsAuthenticated, )

    def get_queryset(self):
        user = self.request.user
        return Note.objects.filter(user=user)

    def perform_create(self, serializer):
        serializer.save(data=self.request.data)

    def perform_update(self, serializer):
        serializer.save(data=self.request.data)

这是我的api/urls.py

from django.conf.urls import url, include
from api import views
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [
    url(r'^v1/stocks/$', views.StockList.as_view()),
    url(r'^v1/notes/$', views.NoteList.as_view()),
    url(r'^v1/api-token-auth/', obtain_auth_token),
    url(r'v1/api-auth/', include('rest_framework.urls', namespace='rest_framework')),

]

我做错了什么?

2 个答案:

答案 0 :(得分:0)

当您需要通过NoteSerializer发布数据时,您的数据需要采用这种格式,

<!doctype html>
<head>
  <base href="https://cdn.rawgit.com/download/polymer-cdn/1.5.0/lib/">
  <link rel="import" href="polymer/polymer.html">
</head>

<body>

  <dom-module id="x-container">
    <template>
      <!-- doesn't show the expected value of '3' -->
      <div>In container; # of items:[[listItems.length]]</div>
      <x-list listItems="{{listItems}}"></x-list>
    </template>

    <script>
      Polymer({
      is: 'x-container'
      });
    </script>
  </dom-module>


  <dom-module id="x-list">
    <template>
      <div>In x-list 1; # of items:[[listItems.length]]</div>
    </template>

    <script>
      Polymer({
      is: 'x-list',
      properties: {
      listItems: {type: Array, value: [1,2,3], notify: true}
      }});
    </script>
  </dom-module>

  <x-container listItems="{{listItems}}"></x-container >

</body>
如果不是这种格式,

Serializer会引发错误。对于序列化程序中的每个字段,django将required = True设置为默认值。

否则,您需要从Stock序列化程序中删除不需要的字段。

答案 1 :(得分:0)

我回到基础并再次使用DRF。首先,我关闭了令牌身份验证并使用基本身份验证进行测试。其次,我尝试使用Browsable API而不是cURL / HTTPie来推送。我发现我无法使用Browsable API推送。

这告诉我问题不在于cURL / HTTPie的语法,最后我发布了关于Browsable API问题的单独question。一旦解决了,我就可以通过Browsable API和cURL / HTTPie进行POST / PUT / DELETE。当用户不是被回答here的对象所有者时,我有一个关于PUSHing的单独问题。

简而言之,这个问题现在由于另外两个问题/答案而得到解决。