我有两个模型:Foo含有一个owner字段,而Bar与Foo有关联:
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)
我不希望用户A能够看到用户B的东西,反之亦然。这个功能基本上可以很好地实现,但有一个例外:
用户A创建了一个Foo实例,但并没有立即创建链接到Foo的Bar实例。此时,用户B可以猜测到用户A的Foo实例的URL,并在创建他自己的Bar实例时指定该URL。
此时,用户A会得到一个他没有创建的Bar实例。
我对Django和rest_framework都很陌生,所以我不知道如何解决这个问题。有人能帮我找到正确的方向吗?我的第一个想法是使用BarSerializer中的foo字段来过滤Foos,使用queryset。但我不知道如何从那里访问auth.User对象。