简体   繁体   English

Django Rest Framework-相关的序列化器

[英]Django Rest Framework - Interrelated serializers

Given the following models for which two have a ManyToMany relationship with the first, how can I construct a serializer for all three models? 给定以下模型,其中两个模型与第一个模型具有ManyToMany关系,如何为所有三个模型构造序列化器?

This is where the importance of ordering in Python is turning to be an issue. 这就是在Python中进行排序的重要性正成为一个问题的地方。

class Trail(models.Model):
    '''
    Main model for this application.  Contains all information for a particular trail
    '''
    trail_name = models.CharField(max_length=150)
    active = models.BooleanField(default=True)
    date_uploaded = models.DateTimeField(default=now())
    owner = models.ForeignKey(Account, default=1)


    class Meta:
        ordering = ('trail_name', )

class Activity(models.Model):
    '''
    A many to many join table to map an activity name to a trail.  A trail can have many
    activities
    '''
    name = models.CharField(max_length=40, unique=True)
    trails = models.ManyToManyField(Trail)

    class Meta:
        ordering = ('name', )


class Surface(models.Model):
    '''
    A many to many join table to map a surface type to many trails.  A trail can have many
    surface types.
    '''
    type = models.CharField(max_length=50, db_column='surface_type', unique=True)
    trails = models.ManyToManyField(Trail)

    class Meta:
        ordering = ('type', )

I have the following serializers in serializers.py : 我在serializers.py中有以下序列serializers.py

class TrailSerializer(serializers.ModelSerializer):
    owner = AccountSerializer()
    activities = ActivitySerializer()

    class Meta:
        model = Trail
        fields = ('trail_name', 'active', 'date_uploaded', 'owner', 'activities', )


class ActivitySerializer(serializers.ModelSerializer):
    trails = TrailSerializer()

    class Meta:
        model = Activity
        fields = ('trails', 'name', )


class SurfaceSerializer(serializers.ModelSerializer):
    trails = TrailSerializer()

    class Meta:
        model = Surface
        fields = ('trails', 'type', )

My question is, short of creating another file to contain ActivitySerializer and SurfaceSerializer , how can I ensure that TrailSerializer works as expected in order to include Activity and Surface references during serialization? 我的问题是,没有创建另一个包含ActivitySerializer and SurfaceSerializer文件,我如何确保TrailSerializer可以按预期工作,以便在序列化期间包括Activity和Surface引用?

Use Marshmallow (serialization library inspired in part by DRF serializers). 使用棉花糖 (序列化库部分受DRF序列化程序启发)。 It solves this problem, by allowing nested schemas to be reference as strings. 通过允许将嵌套模式作为字符串引用来解决此问题。 See Marshmallow: Two Way Nesting 参见棉花糖:双向嵌套

class AuthorSchema(Schema):
    # Make sure to use the 'only' or 'exclude' params to avoid infinite recursion
    books = fields.Nested('BookSchema', many=True, exclude=('author', ))
    class Meta:
        fields = ('id', 'name', 'books')

class BookSchema(Schema):
    author = fields.Nested(AuthorSchema, only=('id', 'name'))
    class Meta:
        fields = ('id', 'title', 'author')

You can use directly or use via django-rest-marshmellow by Tom Christie , which allows use of Marshmallow, while maintaining the same API as REST framework's Serializer class. 您可以直接使用,也可以通过Tom Christie的 django-rest-marshmellow使用,它允许使用棉花糖,同时保持与REST框架的Serializer类相同的API。

I'm not aware of a way to achieve the same result using just DRFs serializers. 我不知道仅使用DRF序列化器即可达到相同结果的方法。

See also: Why Marshmallow? 另请参阅: 为什么选择棉花糖?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM