2017-05-27 94 views
0

我對如何執行我認爲我應該能夠解決的問題感到困惑,但幾個小時後我卻不知所措。我正在學習Django和DRF,所以一切似乎都是一場鬥爭。Django Rest Framework - 如何在使用ListCreateAPIView時POST POST

我已經使用Django Rest Framework編寫了一個API。我能夠在NOTE Serializer上執行GET請求,但不能執行PUSH請求(我可以推送到STOCK serializer的罰款)。基於我寫(使用Django的REST框架網站說明)的代碼,當我嘗試使用下面的命令要發佈:

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')), 

] 

我做錯了什麼?

+0

股票必須是股票列表...它不能是一個字典...因爲你在序列化程序中添加了很多= True,序列化程序期望該股票是一個列表的字典.. – zaidfazil

+0

嗨Fazil,感謝建議,但即使我刪除主= True,我仍然得到同樣的錯誤。如果將HTTP post改爲'http POST http://127.0.0。1:8000/api/v1/notes/note ='api test'stock = [「test」]'Authorization:Token 1235454545656'',I get a different error:'{ 「stock」:[ 「錯誤的類型。預計pk值,收到str。「 ''''' ] }'。還有其他建議嗎? – shaz

+0

實際需要通過序列化程序中的庫存字段傳遞的數據是什麼?是「測試」book_code還是用戶? – zaidfazil

回答

0

我回到基礎知識,並重新開始使用DRF。首先,我關閉了Token Authentication並使用基本身份驗證進行測試。其次,我嘗試使用Browsable API而不是cURL/HTTPie來推送。我發現我無法使用Browsable API來推送。

這告訴我問題不在於cURL/HTTPie的語法,最終我發佈了關於Browsable API的問題的單獨question。一旦解決了問題,我可以通過Browsable API和cURL/HTTPie進行POST/PUT/DELETE。當用戶不是被回答的對象所有者時,我有關於推送的單獨問題here

總之,現在這個問題已經解決,因爲有兩個問題/答案。

0

當您需要發佈通過NoteSerializer數據,您的數據需要在此格式,

{ 
    "user": "some_user", 
    "note": "some_note", 
    "date_created": "28-05-2017", #some_date 
    "stock": [ 
       { 
        "id": "2", #some_id 
        "user": "some_user", 
        "book_code": "some_book_code" 
       }, 
       { 
        "id": "3", #some_id 
        "user": "some_user", 
        "book_code": "some_book_code" 
       } 
      ] 
} 

串行會引發錯誤,如果它不是以這種格式。對於序列化程序中的每個字段,django將required = True設置爲默認值。

否則,您需要從庫存序列化器中刪除不需要的字段。

+0

謝謝Fazil。在語法上,使用HTTPIE甚至CURL,語法是什麼?假設在數據庫中有一個名爲'Test'的股票'book_code',我需要註釋來引用。你描述它的方式和基於模型和視圖,我期望三個字段由模型/視圖,'user','date_created'和'id'填充。所以我唯一需要提供的是'note'和'stock'我想要說明_against_(在這種情況下'Test')。 – shaz

相關問題