天天看點

Django Rest Framework 序列化關系模型

這兩天一直在學習 Django Rest Framework 這個架構,這是一個非常流行的 REST API 架構,深度整合 Django。但與傳統 MVC 模式的不同, Django REST Framework 在使用過程中,需要了解一些新的東西。結合官方 API 分享一下架構中關于序列化關系模型的了解。

序列化模型與序列化關系模型

序列化模型,顧名思義,即對 models 裡的資料模型作序列化。而序列化關系模型則是對 models 裡資料模型中帶有關系的如

ForeignKey

,

ManyToManyField

OneToOneField

字段作序列化。Django Rest Framework 提供了靈活的序列化關系模型,讓開發者可以自由定制序列化資料模型。

序列化關系模型

根據官方的例子來看一下每一個關系模型的介紹。

資料模型如下:

class Album(models.Model):
    album_name = models.CharField(max_length=100)
    artist = models.CharField(max_length=100)

class Track(models.Model):
    album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
    order = models.IntegerField()
    title = models.CharField(max_length=100)
    duration = models.IntegerField()

    class Meta:
        unique_together = ('album', 'order')
        ordering = ['order']

    def __unicode__(self):
        return '%d: %s' % (self.order, self.title)
           

StringRelatedField

使用

StringRelatedField

将傳回一個對應關系 model 的

__unicode__()

方法的字元串。

這個字段是隻讀的。

參數:

  • many

    如果應用于多對多關系,則應将此參數設定為

    True

序列化模型如下

class AlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.StringRelatedField(many=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')
           

序列化結果如下:

{
    'album_name': 'Things We Lost In The Fire',
    'artist': 'Low',
    'tracks': [
        '1: Sunflower',
        '2: Whitetail',
        '3: Dinosaur Act',
        ...
    ]
}
           

PrimaryKeyRelatedField

PrimaryKeyRelatedField

将傳回一個對應關系 model 的主鍵。

  • queryset

    用于在驗證字段輸入時模型執行個體查找。 關系必須明确設定

    queryset

    ,或設定

    read_only = True

  • many

    如果是對應多個的關系,就設定為

    True

  • allow_null

    如果設定為

    True

    ,則該字段将接受

    None

    的值或為空的關系的空字元串。預設為

    False

  • pk_field

    設定為一個字段以控制主鍵值的序列化/反序列化。例如,

    pk_field = UUIDField(format ='hex')

    将UUID主鍵序列化為緊湊的十六進制表示。
class AlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')
           
{
    'album_name': 'Undun',
    'artist': 'The Roots',
    'tracks': [
        89,
        90,
        91,
        ...
    ]
}
           

HyperlinkedRelatedField

HyperlinkedRelatedField

将傳回一個超連結,該連結指向對應關系 model 的詳細資料,

view-name

是必選參數,為對應的視圖生成超連結。

  • view_name

    用作關系目标的視圖名稱。如果使用的是标準路由器類,那麼它的格式為

    <modelname>-detail

    的字元串
  • queryset

    驗證字段輸入時用于模型執行個體查詢的查詢器。關系必須明确設定

    queryset

    read_only = True

  • many

    True

  • allow_null

    True

    None

    False

  • lookup_field

    應該用于查找的目标上的字段。應該對應于引用視圖上的

    URL

    關鍵字參數。預設值為

    pk

  • lookup_url_kwarg

    與查找字段對應的

    URL conf

    中定義的關鍵字參數的名稱。預設使用與

    lookup_field

    相同的值
  • format

    如果使用

    format

    字尾,超連結字段将對目标使用相同的

    format

    字尾,除非使用

    format

    參數進行覆寫。
class AlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.HyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='track-detail'
    )

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')
           
{
    'album_name': 'Graceland',
    'artist': 'Paul Simon',
    'tracks': [
        'http://www.example.com/api/tracks/45/',
        'http://www.example.com/api/tracks/46/',
        'http://www.example.com/api/tracks/47/',
        ...
    ]
}
           

SlugRelatedField

SlugRelatedField

将傳回一個指定對應關系 model 中的字段,需要擦參數

slug_field

中指定字段名稱。

  • slug_field

    應該用于表示目标的字段。這應該是唯一辨別任何給定執行個體的字段。例如

    username

    。這是必選參數
  • queryset

    驗證字段輸入時用于模型執行個體查詢的查詢器。 關系必須明确設定

    queryset

    read_only = True

  • many

    True

  • allow_null

    True

    None

    False

class AlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='title'
     )

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')
           
{
    'album_name': 'Dear John',
    'artist': 'Loney Dear',
    'tracks': [
        'Airport Surroundings',
        'Everything Turns to You',
        'I Was Only Going Out',
        ...
    ]
}
           

HyperlinkedIdentityField

HyperlinkedIdentityField

将傳回指定

view-name

的超連結的字段。

  • view_name

    應該用作關系目标的視圖名稱。如果您使用的是标準路由器類,則它将是格式為

    <model_name>-detail

    的字元串。必選參數
  • lookup_field

    URL

    pk

  • lookup_url_kwarg

    URL conf

    lookup_field

  • format

    format

    format

    format

    參數進行覆寫
class AlbumSerializer(serializers.HyperlinkedModelSerializer):
    track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'track_listing')
           
{
    'album_name': 'The Eraser',
    'artist': 'Thom Yorke',
    'track_listing': 'http://www.example.com/api/track_list/12/',
}
           

嵌套序列化關系模型

在序列化模型中指定嵌套序列化關系模型将傳回一個該嵌套序列化關系模型對應的資料模型中序列化的資料。

讀起來有些拗口,看例子吧。

  • many

    True

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ('order', 'title', 'duration')

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')
           
{
    'album_name': 'The Grey Album',
    'artist': 'Danger Mouse',
    'tracks': [
        {'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
        {'order': 2, 'title': 'What More Can I Say', 'duration': 264},
        {'order': 3, 'title': 'Encore', 'duration': 159},
    ],
}