實踐代碼:
外鍵為 ManyToManyField 時:
class Role(models.Model): """ 角色 """ name = models.CharField(verbose_name='角色名稱', max_length=32, unique=True) permissions = models.ManyToManyField('Permission', verbose_name='權限', blank=True) desc = models.CharField(verbose_name='描述', max_length=50, blank=True) class Meta: verbose_name = '角色' verbose_name_plural = verbose_name ordering = ['id'] def __str__(self): return self.name class User(AbstractUser): id = models.AutoField(verbose_name="用戶ID", primary_key=True) username = models.CharField(max_length=32, verbose_name="姓名", unique=True) password = models.CharField(max_length=128, verbose_name="密碼") email = models.EmailField(max_length=128, verbose_name="郵箱", unique=True) role = models.ManyToManyField(Role, verbose_name='角色', blank=True) class Meta: verbose_name = '用戶信息' verbose_name_plural = verbose_name db_table = 'users' def __str__(self): return self.username ### serializers class UserInfoSerializer(serializers.ModelSerializer): """ 用戶信息 """ role = serializers.SlugRelatedField(many=True, read_only=True, slug_field="name") #### slug_field="name",選擇序列號需要展示的屬性 ,name及 Role表中的name字段
class Meta:
model = User fields = "__all__"
depth = 1
外鍵為 ForeignKey 時。只需要將 many=True 去掉。
參考資料:
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" }