4

Tom Christie は、REST フレームワークを使用する正しい方向に向けて私を助けてくれましたが、別の問題があります。

注: これは、viewsets.ModelViewSet を使用しています。

元のコードでは、モデル インスタンス xyz (「20x40x50」のような座標データを保持) で zip() と split() を使用して、座標 JSON データを返すことができます。独自の toJSON() 関数を呼び出して、必要なものすべての JSON 対応出力を作成しました。次のようなものが出てきます:

[
  {
   "id" : "4"
   "x" : "500",
   "Y" : "80",
   "z" : "150"
   "color" : "yellow"
  },
  ...
]

REST Framework シリアライザーを使用する際の問題は、serializers.Field(source"xyz") のやり方しか知らないことです。「xyz」を 1 つの大きなフィールドとして返すのではなく、「x」「y」「z」を個別のフィールドとして返す方法がわかりません。

これが私のコードです:

serializers.py:
---------------
class NoteSerializer(serializers.ModelSerializer):
    owner = serializers.Field(source='owner.username')
    firstname = serializers.Field(source='owner.first_name')
    lastname = serializers.Field(source='owner.last_name')

    x = ???
    y = ???
    z = ???

class Meta:
    model = Note
    fields = ('id','owner','firstname','lastname','text','color', 'x', 'y, 'z', 'time')

そして、ここにビューがあります:

    views.py:
    ---------
    def list(self, request, format=None):
        if request.method == 'GET':
            queryset = Note.objects.filter(owner=request.user)
            serializer = NoteSerializer(queryset, many=True)
            if 'text' in request.GET:
                if self.is_numeric(request.GET['id']) and self.is_numeric(request.GET['x']) and self.is_numeric(request.GET['y']) and self.is_numeric(request.GET['z']):

                    serializer = NoteSerializer(data=request.QUERY_PARAMS)
                    intx = int(float(request.GET['x']))
                    inty = int(float(request.GET['y']))
                    intz = int(float(request.GET['z']))
                    serializer.object.xyz = str(intx) +'x'+ str(inty) +'x'+ str(intz)
                    serializer.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)

    def create(self, request, format=None):

        serializer = NoteSerializer(data=request.DATA)
        if serializer.is_valid():
            serializer.object.owner = request.user
            serializer.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

これが私のモデルです:

from django.db import models
import datetime
import json
from django.utils import timezone
from django.core.urlresolvers import reverse
from django.core import serializers
from django.contrib.auth.models import User

class Note(models.Model):
owner = models.ForeignKey('auth.User', null=True)
text = models.CharField(max_length=500)
color = models.CharField(max_length=20)
xyz = models.CharField(max_length=20)
time = models.DateTimeField((u"Note Creation Date and Time"), auto_now_add=True,  blank=True)

def __unicode__(self):
    return unicode(self.owner)

助けてくれてありがとう!Python/Django/REST は初めてです。これは非常に興味深いようですが、何日も私をイライラさせてきました.

アップデート:

serializer.object.xyzを使用してviews.pyを介してxyzにアクセスできないようです。同じエラー「Nonetypeには属性xyzがありません」と表示されます

serializer = NoteSerializer(data=request.QUERY_PARAMS)
intx = int(float(request.GET['x']))
inty = int(float(request.GET['y']))
intz = int(float(request.GET['z']))
serializer.object.xyz = str(intx) +'x'+ str(inty) +'x'+ str(intz)
serializer.save()
4

2 に答える 2

2

これに関する私のアプローチ:

COORD = dict(x=0, y=1, z=2)

class CoordinateField(serializers.Field):
    def field_to_native(self, obj, field_name):
        # retrieve and split coordinates
        coor = obj.content.split('x')

        # get coordinate value depending on coordinate key (x,y,z)
        return int(coor[COORD[field_name]])

    def field_from_native(self, data, files, field_name, into):
        into['xyz'] = u'{x}x{y}x{z}'.format(**data)
        super(CoordinateField, self).field_from_native(data, files, field_name, into)

class BloopModelSerializer(serializers.ModelSerializer):
    x = CoordinateField()
    y = CoordinateField()
    z = CoordinateField()

    class Meta:
        model = Bloop

これが結果として得られるものです:

{
    "x": 10,
    "y": 20,
    "z": 30,
    "content": "10x20x30"
},

編集:

ビュー.py

class BloopList(generics.ListCreateAPIView):
    queryset = Bloop.objects.all()
    serializer_class = BloopModelSerializer

bloop_list = Bloop.as_view()

urls.py

url(r'^api/bloops/$', 'myapp.views.bloop_list', name='bloop-list'),

提案

リスト GET メソッドを使用してオブジェクトを変更/追加するべきではありません。DRF には組み込みのクラスがあり、非常に簡単になり、正しい REST 標準に従うことができます。

たとえば、リスト メソッドは GET パラメータを使用してリクエスト データを取得しますが、これは悪い考えです。新しいオブジェクトを更新または追加するたびに、POST または PUT を使用してリクエスト ボディ内にデータを提供する必要があります。DRF は、それがデータの提供方法であると想定し、すべてを処理します。

于 2013-09-23T21:55:06.957 に答える