2017-01-17 6 views
1

私はユーザーがフィードを購読できる休憩APIを備えたdjangoアプリケーションを構築しています。django-rest-framework:多対多の関係を表現する方法は?

私のモデルは次のようになります。

class Profile(models.Model): 
    user = models.OneToOneField(
     User, # standard django user 
     on_delete=models.CASCADE, 
     primary_key=True 
    ) 

    subscriptions = models.ManyToManyField(Feed, related_name="subscribers") 

class Feed(models.Model): 
    # These feeds are read-only for the subscribers 
    pass 

は英語で説明:

を各ユーザープロファイルを持っています。これらのプロファイルはフィードに登録できます。 フィードは購読することしかできず、ユーザは によって作成または更新することはできません。

現在のユーザーのサブスクリプションを作成、読み取り、更新、および削除するための残りのエンドポイントを公開したいと考えています。もちろん、一般的なビューであるListCreateAPIViewRetrieveUpdateDeleteAPIViewを使用したいと思いますが、このシリアライザとクエリーセットを使いやすくする方法を見つけることはできません。

私は/me/subscriptions/でフィードのリストを直接返しましたが、POSTはサブスクリプションを作成する代わりにフィードを作成するので奇妙です。

私は混乱しています...どんなヒントもありがとうございます!

+0

ユーザープロファイルは 'request.user'に基づいていますか?例えば、 'GET''/subscriptions/'はそのユーザのために' Feed'を返すべきです。 'POST'はそのユーザへのmtmリンクを作成するべきですか? –

答えて

2

あなたがModelViewSetと上書きcreate方法を使用することができます。

views.py:

from rest_framework import status 
from rest_framework import viewsets 


class FeedViewSet(serializers.ModelViewSet): 

    serializer_class = FeedSerializer 

    def get_queryset(self): 
     # show an only related Feed objects to a request.user 
     profile = request.user.profile 
     return Feed.objects.filter(subscribers=profile) 

    def create(self, request, *args, **kwargs): 
     pk = request.data.get('pk') 
     profile = request.user.profile 
     feed = Feed.objects.get(pk=pk) 
     profile.subscriptions.add(feed) 
     return Response('subscription feed updated!', status=status.HTTP_201_CREATED) 

    # list will work by default 
    # other methods like update, delete, retrieve 
    # you could set with NOT_IMPLEMENTED status 
    def update(self, request, *args, **kwargs): 
     return Response(status=status.HTTP_501_NOT_IMPLEMENTED) 

urls.py:サブスクリプションを更新するためのエンドポイントを持っています

from rest_framework import routers 

router = routers.SimpleRouter() 
router.register('subscriptions', FeedViewSet, base_name='subscription') 

request.userを基準にしてProfileである。 /subscriptions/からGETFeedProfileの間のリンクを作成するデータ{'pk': <Feed_pk>}/subscriptions/にしてrequest.userPOSTによってフィルタリングすべてFeedのオブジェクトが表示されます。

+0

それは賢明な解決策のように聞こえる。しかし、私は多対多の関係でオブジェクトを定義して、できるだけそれを公開すると、コードが簡単でコードが少なくないかどうか疑問に思っています。 – aspyct

+0

@aspyct違いはありません。オブジェクトを作成するのではなくリンクを作成しているので、 'create'メソッドをオーバーライドする必要があります。 –