mll*_*llm 96 python django django-rest-framework
我有一个关于处理m2m /通过模型及其在django rest框架中的表示的问题.我们来看一个经典的例子:
models.py:
from django.db import models
class Member(models.Model):
    name = models.CharField(max_length = 20)
    groups = models.ManyToManyField('Group', through = 'Membership')
class Group(models.Model):
    name = models.CharField(max_length = 20)
class Membership(models.Model):
    member = models.ForeignKey('Member')
    group = models.ForeignKey('Group')
    join_date = models.DateTimeField()
serializers.py:
imports...
class MemberSerializer(ModelSerializer):
    class Meta:
        model = Member
class GroupSerializer(ModelSerializer):
    class Meta:
        model = Group
views.py:
imports...
class MemberViewSet(ModelViewSet):
    queryset = Member.objects.all()
    serializer_class = MemberSerializer
class GroupViewSet(ModelViewSet):
    queryset = Group.objects.all()
    serializer_class = GroupSerializer
在获取成员实例时,我成功接收了所有成员的字段及其组 - 但是我只获得了组的详细信息,而没有来自成员模型的额外详细信息.
换句话说,我希望收到:
{
   'id' : 2,
   'name' : 'some member',
   'groups' : [
      {
         'id' : 55,
         'name' : 'group 1'
         'join_date' : 34151564
      },
      {
         'id' : 56,
         'name' : 'group 2'
         'join_date' : 11200299
      }
   ]
}
注意join_date.
我已经尝试了很多解决方案,当然包括关于它的Django Rest-Framework官方页面,似乎没有人给出一个合适的简单答案 - 我需要做些什么才能包含这些额外的字段?我发现它更直接与django-tastypie但有一些其他问题,更喜欢休息框架.
小智 126
怎么样.....
在MemberSerializer上,在其上定义一个字段,如:
groups = MembershipSerializer(source='membership_set', many=True)
然后在您的会员序列化程序上,您可以创建:
class MembershipSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.Field(source='group.id')
    name = serializers.Field(source='group.name')
    class Meta:
        model = Membership
        fields = ('id', 'name', 'join_date', )
这具有创建序列化值的整体效果,组具有所需的成员资格,然后它使用自定义序列化程序来提取要显示的位.
编辑:由@bryanph评论,在DRF 3.0中serializers.field重命名为serializers.ReadOnlyField,所以这应该是:
class MembershipSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.ReadOnlyField(source='group.id')
    name = serializers.ReadOnlyField(source='group.name')
    class Meta:
        model = Membership
        fields = ('id', 'name', 'join_date', )
任何现代实施
小智 13
我遇到了这个问题,我的解决方案(使用DRF 3.6)是在对象上使用SerializerMethodField并显式查询Membership表,如下所示:
class MembershipSerializer(serializers.ModelSerializer):
    """Used as a nested serializer by MemberSerializer"""
    class Meta:
        model = Membership
        fields = ('id','group','join_date')
class MemberSerializer(serializers.ModelSerializer):
    groups = serializers.SerializerMethodField()
    class Meta:
        model = Member
        fields = ('id','name','groups')
    def get_groups(self, obj):
        "obj is a Member instance. Returns list of dicts"""
        qset = Membership.objects.filter(member=obj)
        return [MembershipSerializer(m).data for m in qset]
这将返回groups键的dicts列表,其中每个dict都是从MembershipSerializer序列化的.要使其可写,您可以在MemberSerializer中定义自己的创建/更新方法,在该方法中迭代输入数据并显式创建或更新成员资格模型实例.
| 归档时间: | 
 | 
| 查看次数: | 19989 次 | 
| 最近记录: |