2016-09-06 397 views
2

我有兩個型號:美孚攜帶所有者場和酒吧具有相對富:Django的REST框架:過濾器/驗證相關領域

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

我的看法是這樣的:

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的東西,反之亦然。目前爲止,該方法運行良好,只有一個例外:

用戶A創建了Foo的實例,但並未立即創建鏈接到Foo的Bar實例。現在,用戶B可以猜測用戶A的Foo實例的URL,並指定創建其實例的Bar時的情況。

此時,用戶A獲取他沒有創建的Bar實例。

我是新來的Django和rest_framework,所以我不知道如何解決這個問題。有人能讓我走上正軌嗎?我的第一個想法是使用BarSerializer中的foo字段來使用queryset過濾Foos。但我沒有弄清楚如何從那裏訪問auth.User對象。

回答

0

如果你使用include it in its context,你可以訪問Serializer中的請求。 然後你可以在裏面的Bar序列化程序:

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