1. 程式人生 > 其它 >django之 rest_framework 序列化 model 外來鍵時的處理方式

django之 rest_framework 序列化 model 外來鍵時的處理方式

參考資料:

https://blog.csdn.net/chexiansheng/article/details/89339025

https://blog.csdn.net/weixin_30376453/article/details/98360039

在定義資料的序列化器時,外來鍵(即所屬的分類)欄位如何序列化?

對於關聯欄位,可以採用以下幾種方式:

1、PrimaryKeyRelatedField

此欄位將被序列化為關聯物件的主鍵。type = serializers.PrimaryKeyRelatedField(label=‘分類’, read_only=True)

type = serializers.PrimaryKeyRelatedField(label=‘分類’, queryset=BookInfo.objects.all())

指明欄位時需要包含read_only=True或者queryset引數:
•包含read_only=True引數時,該欄位將不能用作反序列化使用
•包含queryset引數時,將被用作反序列化時引數校驗使用

2、 StringRelatedField

此欄位將被序列化為關聯物件的字串表示方式(即__str__方法的返回值)
type = serializers.StringRelatedField(label=‘分類’)

3、SlugRelatedField

此欄位將被序列化為關聯物件的指定欄位資料
type = serializers.SlugRelatedField(label=‘分類’, read_only=True, slug_field=‘bpub_date’)
slug_field指明使用關聯物件的哪個欄位

4、使用關聯物件的序列化器

hbook = BookInfoSerializer()
此欄位只可以用GET方法

5、重寫to_representation方法

序列化器的每個欄位實際都是由該欄位型別的to_representation方法決定格式的,可以通過重寫該方法來決定格式。
注意,to_representations方法不僅侷限在控制關聯物件格式上,適用於各個序列化器欄位型別。
定義一個新的關聯欄位:
class TypeRelateField(serializers.RelatedField):
“”“自定義用於處理分類的欄位”""
def to_representation(self, value):
return ‘Book: %d %s’ % (value.id, value.btitle)
指明type為typeRelateField型別
type = typeRelateField(read_only=True)

6.HyperlinkedRelatedField

可以用於使用超連結表示關係的目標

例如,以下序列化程式:

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/’,
…
]
}

預設情況下,此欄位是讀寫的,但您可以使用該read_only標誌更改此行為。

many引數

如果關聯的物件資料不是隻有一個,而是包含多個數據,如想序列化分類TypeInfo資料,每個TypeInfo物件關聯的商品GoodInfo物件可能有多個,此時關聯欄位型別的指明仍可使用上述幾種方式,只是在宣告關聯欄位時,多補充一個many=True引數即可

例如:

class BlogListSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    user = BlogUserInfoSerializer()
    title = serializers.CharField()
    like_user = serializers.ManyRelatedField(serializers.SlugRelatedField(slug_field="username", source="user_id"), queryset=User.objects.all(), source="follow")
    topic_name = serializers.SlugRelatedField(slug_field="name", source="topic", queryset=Topic.objects.all())
    create_at = serializers.DateTimeField()
 
class Blog(models.Model):
    follow = models.ManyToManyField(User, verbose_name="關注", related_name="follow_blog")
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="blog")
    title = models.CharField(max_length=100)
    content = models.TextField(max_length=200000)
    topic = models.ForeignKey(Topic, null=True, verbose_name="話題", on_delete=models.CASCADE)
    create_at = models.DateTimeField(verbose_name="建立時間", auto_now_add=True)

class Topic(models.Model):
    name = models.CharField(verbose_name="名稱", max_length=100)
    create_at = models.DateTimeField(verbose_name="建立時間", auto_now_add=True)

返回結果如下:

{
            "id": 158,
            "user": {
                "id": 50,
                "avatar": "https://xxx.xxx.cn/media/191b6193972a439e9886187f249bd2d9.jpg",
                "username": "語家",
                "sex": 2
            },
            "title": "想開個童裝店?",
            "like_user": [
                "13800138000"
            ],
            "topic_name": "#你們攢錢為了什麼#",
            "create_at": "2018-10-15 16:21:36"
}