在django rest框架中创建视图中处理外键

时间:2015-10-19 07:21:02

标签: python django django-rest-framework

我有两种模式:

class Foo(models.Model):
    name = models.CharField(max_length=64)

class Bar(models.Model):
    foo = models.ForeignKey(Foo)
    name = models.CharField(max_length=64)

和那些序列化程序

class FooSerializer(serializers.ModelSerializer):
    class Meta:
        model = Foo
        fields = ('pk', 'name')

class BarSerializer(serializers.ModelSerializer):
    foo = ???
    class Meta:
        model = Bar
        fields = ('pk', 'foo', 'name')

我需要为/bar/create对象创建一个api Bar,例如:

  • 我只在输入json
  • 中提供Foo主键
  • 我使用Bar序列化的foo检索FooSerializer个对象。

所以,我们考虑在db中有这个Foo(pk=1, name='foo')对象,我想这样做:

  • 请求:
    • POST / bar / create
    • content = {'foo': 1, 'name': 'bar'}
  • 响应
    • {'foo': {'pk': 1, 'name': 'foo'}, 'name': 'bar'}

我怎么能这么做? 这样做是一种好习惯吗?

2 个答案:

答案 0 :(得分:0)

一种方法是将alias字段放入嵌套对象中,并使别名嵌套对象成为只读:

class BarSerializer(serializers.ModelSerializer):
    foo_obj = FooSerializer(required=False,read_only=True)
    class Meta:
        model = Bar
        fields = ('pk', 'foo', 'foo_obj', 'name')

如果存在foo,则会将其置于Bar的{​​{1}}字段中。在客户端,您必须保持foo_objfoo同步,这真的很臭。

答案 1 :(得分:0)

  1. 如何实现:实现此目的的一种方法是使用2个序列化程序,您将根据请求类型进行选择:
  2.     class BarSerializer(serializers.ModelSerializer):
            class Meta:
                model = Bar
                fields = ('pk', 'foo', 'name')
    
        class BarNestedSerializer(BarSerializer):
            class Meta(BarSerializer.Meta):
                depth = 2
    
    
        class BarView(generics.ListCreateAPIView):
            queryset = Bar.objects.all()
    
            def get_serializer_class(self):
                return BarNestedSerializer if self.action == 'list' else BarSerializer
    
    1. 如何完成:为Foo对象设置一个单独的路径,您将在前端缓存并根据ID显示其查找值。在一天结束时,它实际上取决于您的用例,但通常只有在必要时才能避免嵌套。