2016-09-06 10 views
2

私は2つのモデルがあります:Djangoの残りのフレームワーク:フィルター/検証関連分野

class Foo(models.Model): 
    owner = models.ForeignKey('auth.User') 
    name = models.CharField(max_length=20, null=True) 

class Bar(models.Model): 
    foo = models.OneToOneField(Foo, related_name='bar') 
    [...] 

私は表現のためのHyperlinkedModelSerializerを使用します:

class BarSerializer(serializers.HyperlinkedModelSerializer): 
    foo = serializers.HyperlinkedRelatedField(view_name='foo-detail', queryset=Foo.objects.all()) 
    [...] 

    class Meta: 
     model = Bar 
     fields = ('foo', [...]) 

class FooSerializer(serializers.HyperlinkedModelSerializer): 
    owner = serializers.SlugRelatedField(read_only=True, slug_field='username') 
    bar = serializers.HyperlinkedRelatedField(view_name='bar-detail', read_only=True) 

    class Meta: 
     model = Foo 
     fields = ('name', 'bar', 'owner') 
のFooとの関係を持っている所有者フィールドを運びfooとbar

私の見解は次のようになります。

class FooViewSet(viewsets.ModelViewSet): 
    queryset = Foo.objects.all() 
    serializer_class = FooSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwner,) 

    def get_queryset(self): 
     user = self.request.user 

     if not user.is_authenticated(): 
      return Foo.objects.none() 

     if user.username == "admin": 
      return Foo.objects.all() 

     return Foo.objects.filter(owner=user) 

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

class BarViewSet(viewsets.ModelViewSet): 
    queryset = Bar.objects.all() 
    serializer_class = BarSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwner,) 

    def get_queryset(self): 
     user = self.request.user 

     if not user.is_authenticated(): 
      return Bar.objects.none() 

     if user.username == "admin": 
      return Bar.objects.all() 

     return Bar.objects.filter(foo__owner=user) 

私はwhantユーザーAができるようにしないでくださいユーザBのものを見ることができます。逆もまた同様です。これまでのところ、1つの例外を除いてかなりうまくいきます:

ユーザAはFooのインスタンスを作成しましたが、FooにリンクするBarのインスタンスを即座に作成しません。ユーザーBはUser AのFooインスタンスへのURLを推測し、Barのインスタンスを作成するときにそのURLを指定できます。

この時点で、ユーザーAは作成しなかったBarのインスタンスを取得します。

私はDjangoとrest_frameworkを初めて使うので、これを解決する方法はわかりません。誰かが正しい軌道に乗ることができますか?私の最初の考えは、BarSerializerのfooフィールドを使って、クエリーセットを使ってFoosをフィルタリングすることでした。しかし、そこからauth.Userオブジェクトにアクセスする方法を理解していませんでした。

答えて

0

include it in its contextの場合、シリアライザ内でリクエストにアクセスできます。 次に、バーシリアライザの内部にfield level validationを入れます:

def validate_foo(self, val): 
    user = self.context['request'].user 

    try: 
     foo = Foo.objects.get(pk=val) 
    except Foo.DoesNotExist: 
     raise serializers.ValidationError("Some Error") 

    if foo.user is not user: 
     raise serializers.ValidationError("Some Error") 

    return value 
関連する問題