Serializer relations
序列化器關係 (Serializer relations)
糟糕的程式設計師擔心程式碼。好的程式設計師擔心資料結構和它們的關係。—— Linus Torvalds
關係欄位用於表示模型關係。它們可以應用於 ForeignKey
,ManyToManyField
和 OneToOneField
關係,以及反向關係和自定義關係 (例如:GenericForeignKey
)。
注意:關係欄位在 relations.py
中宣告,但按照慣例,你應該從 serializers
模組匯入它們,使用 from rest_framework import serializers
並像 serializers.<FieldName>
檢查關係 (Inspecting relationships)
當使用 ModelSerializer
類時,將為您自動生成序列化器欄位和關係。檢查這些自動生成的欄位可以作為確定如何定製關係樣式的有用工具。
為此,使用 python manage.py shell
開啟 Django shell,然後匯入序列化器類,例項化它並列印物件表示…
>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>> > print repr(serializer) # Or `print(repr(serializer))` in Python 3.x.
AccountSerializer():
id = IntegerField(label='ID', read_only=True)
name = CharField(allow_blank=True, max_length=100, required=False)
owner = PrimaryKeyRelatedField(queryset=User.objects.all())
API 參考 (API Reference)
為了解釋各種型別的關係欄位,我們將為我們的示例使用一些簡單的模型。我們的模型將用於音樂專輯,以及每個專輯中列出的歌曲。
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
可用它的 __unicode__
方法來表示關係的目標。
例如,以下序列化器。
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',
...
]
}
該欄位是隻讀的。
引數:
many
- 如果是一對多的關係,就將此引數設定為True
。
PrimaryKeyRelatedField
PrimaryKeyRelatedField
可用於使用其主鍵表示關係的目標。
例如,以下序列化器:
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,
...
]
}
預設情況下,此欄位是讀寫的,但您可以使用 read_only
標誌更改此行為。
引數:
queryset
- 驗證欄位輸入時用於模型例項查詢的查詢集。關係必須顯式地設定查詢集,或設定read_only=True
。many
- 如果應用於一對多關係,則應將此引數設定為True
。allow_null
- 如果設定為True
,那麼該欄位將接受None
值或可為空的關係的空字串。預設為False
。pk_field
- 設定欄位來控制主鍵值的序列化/反序列化。例如,pk_field=UUIDField(format='hex')
會將 UUID 主鍵序列化為其緊湊的十六進位制表示形式。
HyperlinkedRelatedField
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
標誌更改此行為。
注意:該欄位設計用於對映到接受單個 URL 關鍵字引數的 URL 的物件,使用 lookup_field
和 lookup_url_kwarg
引數設定。
這適用於包含單個主鍵或 slug 引數作為 URL 一部分的 URL。
如果您需要更復雜的超連結表示,則需要自定義該欄位,如下面的自定義超連結欄位部分中所描述的。
引數:
view_name
- 用作關係目標的檢視名稱。如果你使用的是標準路由器類,則這將是格式為<modelname>-detail
的字串。必填。queryset
- 驗證欄位輸入時用於模型例項查詢的查詢集。關係必須顯式地設定查詢集,或設定read_only=True
。many
- 如果應用於一對多關係,則應將此引數設定為True
。allow_null
- 如果設定為True
,那麼該欄位將接受None
值或可為空的關係的空字串。預設為False
。lookup_field
- 用於查詢的目標欄位。對應於引用檢視上的 URL 關鍵字引數。預設是'pk'
。lookup_url_kwarg
- 與查詢欄位對應的 URL conf 中定義的關鍵字引數的名稱。預設使用與lookup_field
相同的值。format
- 如果使用格式字尾,則超連結欄位將使用與目標相同的格式字尾,除非使用format
引數重寫。
SlugRelatedField
SlugRelatedField
可用於使用目標上的欄位來表示關係的目標。
例如,以下序列化器:
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',
...
]
}
預設情況下,此欄位是讀寫的,但您可以使用 read_only
標誌更改此行為。
當使用 SlugRelatedField
作為讀寫欄位時,通常需要確保 slug 欄位與 unique=True
的模型欄位相對應。
引數:
slug_field
- 目標上應該用來表示它的欄位。這應該是唯一標識任何給定例項的欄位。例如,username
。必填。queryset
- 驗證欄位輸入時用於模型例項查詢的查詢集。關係必須顯式地設定查詢集,或設定read_only=True
。many
- 如果應用於一對多關係,則應將此引數設定為True
。allow_null
- 如果設定為True
,那麼該欄位將接受None
值或可為空的關係的空字串。預設為False
。
HyperlinkedIdentityField
此欄位可以作為標識關係應用,例如 HyperlinkedModelSerializer 上的 'url'
欄位。它也可以用於物件的屬性。例如,以下序列化器:
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/',
}
該欄位始終為只讀。
引數:
view_name
- 用作關係目標的檢視名稱。如果你使用的是標準路由器類,則這將是格式為<modelname>-detail
的字串。必填。lookup_field
- 用於查詢的目標欄位。對應於引用檢視上的 URL 關鍵字引數。預設是'pk'
。lookup_url_kwarg
- 與查詢欄位對應的 URL conf 中定義的關鍵字引數的名稱。預設使用與lookup_field
相同的值。format
- 如果使用格式字尾,則超連結欄位將使用與目標相同的格式字尾,除非使用format
引數重寫。
巢狀關係 (Nested relationships)
可以使用序列化器作為欄位來表示巢狀關係。
如果該欄位用於表示一對多關係,則應將 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 = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse')
>>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)
<Track: Track object>
>>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)
<Track: Track object>
>>> Track.objects.create(album=album, order=3, title='Encore', duration=159)
<Track: Track object>
>>> serializer = AlbumSerializer(instance=album)
>>> serializer.data
{
'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},
...
],
}
可寫的巢狀序列化器 (Writable nested serializers)
預設情況下,巢狀序列化器是隻讀的。如果要支援對巢狀序列化器欄位的寫操作,則需要建立 create()
和/或 update()
方法,以便顯式指定應如何儲存子關係。
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ('order', 'title', 'duration')
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
def create(self, validated_data):
tracks_data = validated_data.pop('tracks')
album = Album.objects.create(**validated_data)
for track_data in tracks_data:
Track.objects.create(album=album, **track_data)
return album
>>> data = {
'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},
],
}
>>> serializer = AlbumSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.save()
<Album: Album object>
自定義關係欄位 (Custom relational fields)
在極少數情況下,現有的關係樣式都不適合您需要的表示,您可以實現一個完全自定義的關係欄位,該欄位準確地描述應該如何從模型例項生成輸出表示。
要實現自定義關係欄位,您應該重寫 RelatedField
,並實現 .to_representation(self,value)
方法。此方法將欄位的目標作為 value
引數,並返回應用於序列化目標的表示。value
引數通常是模型例項。
如果想要實現讀寫關係欄位,還必須實現 .to_internal_value(self, data)
方法。
要提供基於 context
的動態查詢集,還可以重寫 .get_queryset(self)
,而不是在類上或初始化該欄位時指定 .queryset
。
舉個栗子
例如,我們可以定義一個關係欄位,使用它的順序,標題和持續時間將音軌序列化為自定義字串表示。
import time
class TrackListingField(serializers.RelatedField):
def to_representation(self, value):
duration = time.strftime('%M:%S', time.gmtime(value.duration))
return 'Track %d: %s (%s)' % (value.order, value.name, duration)
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackListingField(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
然後,此自定義欄位將序列化為以下表示形式。
{
'album_name': 'Sometimes I Wish We Were an Eagle',
'artist': 'Bill Callahan',
'tracks': [
'Track 1: Jim Cain (04:39)',
'Track 2: Eid Ma Clack Shaw (04:19)',
'Track 3: The Wind and the Dove (04:34)',
...
]
}
自定義超連結欄位 (Custom hyperlinked fields)
在某些情況下,您可能需要自定義超連結欄位的行為,以表示需要多個查詢欄位的 URL。
您可以通過重寫 HyperlinkedRelatedField
來實現。有兩個方法重寫:
get_url(self, obj, view_name, request, format)
get_url
方法用於將物件例項對映到其 URL 表示。
如果 view_name
和 lookup_field
屬性未配置為正確匹配 URL conf,可能會引發 NoReverseMatch
。
get_object(self, queryset, view_name, view_args, view_kwargs)
如果您想支援可寫的超連結欄位,那麼您還需要重寫 get_object
,以便將傳入的 URL 映射回它們表示的物件。對於只讀的超連結欄位,無需重寫此方法。
此方法的返回值應該是與匹配的 URL conf 引數對應的物件。
可能會引發 ObjectDoesNotExist
異常。
舉個栗子
假設我們有一個 customer 物件的 URL,它接受兩個關鍵字引數,如下所示:
/api/<organization_slug>/customers/<customer_pk>/
這不能用僅接受單個查詢欄位的預設實現來表示。
在這種情況下,我們需要重寫 HyperlinkedRelatedField
以獲得我們想要的行為:
from rest_framework import serializers
from rest_framework.reverse import reverse
class CustomerHyperlink(serializers.HyperlinkedRelatedField):
# 我們將它們定義為類屬性,因此我們不需要將它們作為引數傳遞。
view_name = 'customer-detail'
queryset = Customer.objects.all()
def get_url(self, obj, view_name, request, format):
url_kwargs = {
'organization_slug': obj.organization.slug,
'customer_pk': obj.pk
}
return reverse(view_name, kwargs=url_kwargs, request=request, format=format)
def get_object(self, view_name, view_args, view_kwargs):
lookup_kwargs = {
'organization__slug': view_kwargs['organization_slug'],
'pk': view_kwargs['customer_pk']
}
return self.get_queryset().get(**lookup_kwargs)
請注意,如果您想將此樣式與通用檢視一起使用,那麼您還需要在檢視上重寫 .get_object
以獲得正確的查詢行為。
通常,我們建議在可能的情況下使用 API 表示的平面樣式,但適度使用巢狀的 URL 樣式也是合理的。
進一步說明 (Further notes)
queryset
引數 (The queryset
argument)
queryset
引數只社用於可寫關係欄位,在這種情況下,它用於執行從原始使用者輸入對映到模型例項的模型例項查詢。
在 2.x 版本中,如果正在使用 ModelSerializer
類,則序列化器有時會自動確定 queryset
引數。
此行為現在替換為始終為可寫關係欄位使用顯式 queryset
引數。
這樣做可以減少 ModelSerializer
提供的隱藏 “魔術” 數量,使欄位的行為更加清晰,並確保在使用 ModelSerializer
快捷方式或使用完全顯式的 Serializer
類之間轉換是微不足道的。
自定義 HTML 顯式 (Customizing the HTML display)
模型的內建 __str__
方法將用於生成用於填充 choices
屬性的物件的字串表示。這些 choices 用於填充在可瀏覽的 API 中選擇的 HTML 輸入。
要為此類輸入提供自定義表示,請重寫 RelatedField
子類的 display_value()
。此方法將接收一個模型物件,並應返回一個適合表示它的字串。例如:
class TrackPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
def display_value(self, instance):
return 'Track: %s' % (instance.title)
Select field cutoffs
當在可瀏覽的 API 中渲染時,關係欄位將預設只顯示最多 1000 個可選擇的項。如果存在更多項,則會顯示 “More than 1000 items…” 的禁用選項。
此行為旨在防止模板由於顯示大量關係而無法在可接受的時間段中渲染。
有兩個關鍵字引數可用於控制此行為:
html_cutoff
- 如果設定,這將是 HTML 選擇下拉選單中顯示的選項的最大數量。設定為None
可以禁用任何限制。預設為1000
。html_cutoff_text
- 如果設定,如果在 HTML 選擇下拉選單中截斷了最大數量的項,則將顯示文字指示符。預設為"More than {count} items…"
您還可以使用 settings 中的 HTML_SELECT_CUTOFF
和 HTML_SELECT_CUTOFF_TEXT
全域性控制這些。
在強制執行截斷的情況下,您可能希望使用 HTML 表單中的普通輸入欄位。您可以使用 style
關鍵字引數執行此操作。例如:
assigned_to = serializers.SlugRelatedField(
queryset=User.objects.all(),
slug_field='username',
style={'base_template': 'input.html'}
)
反向關係 (Reverse relations)
請注意,反向關係不會自動包含在 ModelSerializer
和 HyperlinkedModelSerializer
類中。要包含反向關係,您必須顯式的將其新增到欄位列表中。例如:
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
fields = ('tracks', ...)
您通常希望確保在關係上設定了適當的 related_name
引數,可以用作欄位名稱。例如:
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
...
如果您還沒有為反向關係設定相關名稱,則需要在 fields
引數中使用自動生成的相關名稱。例如:
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
fields = ('track_set', ...)
有關更多詳細資訊,請參閱有關反向關係的 Django 文件。
通用關係 (Generic relationships)
如果要序列化通用外來鍵,則需要定義一個自定義欄位,以明確確定要如何序列化關係目標。
例如,給定標籤的以下模型,它與其他任意模型的通用關係:
class TaggedItem(models.Model):
"""
使用通用關係的標籤任意模型例項。
See: https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/
"""
tag_name = models.SlugField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
tagged_object = GenericForeignKey('content_type', 'object_id')
def __unicode__(self):
return self.tag_name
以下兩個模型,可能有相關的標籤:
class Bookmark(models.Model):
"""
A bookmark consists of a URL, and 0 or more descriptive tags.
"""
url = models.URLField()
tags = GenericRelation(TaggedItem)
class Note(models.Model):
"""
A note consists of some text, and 0 or more descriptive tags.
"""
text = models.CharField(max_length=1000)
tags = GenericRelation(TaggedItem)
我們可以定義一個可用於序列化標籤例項的自定義欄位,使用每個例項的型別來確定它應該如何序列化。
class TaggedObjectRelatedField(serializers.RelatedField):
"""
A custom field to use for the `tagged_object` generic relationship.
"""
def to_representation(self, value):
"""
Serialize tagged objects to a simple textual representation.
"""
if isinstance(value, Bookmark):
return 'Bookmark: ' + value.url
elif isinstance(value, Note):
return 'Note: ' + value.text
相關推薦
Serializer relations
序列化器關係 (Serializer relations)
糟糕的程式設計師擔心程式碼。好的程式設計師擔心資料結構和它們的關係。—— Linus Torvalds
關係欄位用於表示模型關係。它們可以應用於 ForeignKey,ManyToManyField 和 OneToOneFi
Redis系列--7、RedisTemplate和 Serializer詳解
redistemplate serializer詳解<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionF
HDU3231 Box Relations——三維拓撲刨銑
這樣的 pac hdu ati bits turn blank push 上界 HDU3231 Box Relations
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3231
題目意思:在一個三維空間上有一些棱和坐標軸平行
在訪問RESTful接口時出現:Could not write content: No serializer found for class 的問題解決小技巧收集
onu restfu zab blank rest org lips 收集 規範 註意:市面上對於寫RESTful是用RestFul,其實是不規範的,標準寫法RESTful。
在Java上,處理這個應該是沒有繼承Serializable類,然後通過Eclipse生成ser
Classifying Temporal Relations by Bidirectional LSTM over Dependency Paths
direct 批評 研究 拼接 組成 人工 clas rec 向量 雖然要寫這篇文章,但是有些地方仍然沒有了解,比如對TimeBank-Dense。因為以後沒有用這個語料的可能性,所以就直接忽略了。
這篇論文是2017ACL上的一篇短文,作者為來自日本國立情報學研究所的Fe
Serializer序列化器的定義與使用
序列化器的作用:
對資料進行校驗
對資料物件進行轉換(資料模型類和dict等資料間的轉換)
定義方法
Django REST framework中的Serializer使用類來定義,須繼承自rest_framework.serializers.Serializer。
No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$Enha
專案中使用了 mybatis 級聯查詢,返回 json 格式時報錯:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.apache.ib
Django (二)-Serializer序列化器
本章主要以圖書管理作為實驗基礎
一、定義Serializer
1. 定義方法
Django REST framework中的Serializer使用類來定義,需繼承自rest_framework.serializers.Serializer
例如:已經有了一個數據庫模型類
Serializer序列化的使用
序列化使用
我們在django shell中來學習序列化器的使用。
python manage.py shell
1 基本使用
1) 先查詢出一個圖書物件
from booktest.models import BookInfo
book = BookInfo.objects
golang下如何仿django實現serializer,十分適用!
如何實現serializer用golang
對返回的model進行 django裡的 toRepresentation()操作(update,pop,picked) 目前只針對json編碼方式,其他方式待跟進 serializer實現如下:
package serializer
Serializer序列化器
1 定義Serializer
1.1 定義方法
Django REST framework中的Serializer使用類來定義,須繼承自rest_framework.serializers.Serializer。
例如,我們已有了一個數據庫模型類BookInfo
class Bo
_042_Android_使用Serializer去生成xml檔案
轉自https://www.cnblogs.com/linfenghp/p/5393832.html,感謝作者的無私分享。
xml檔案我們可以用來儲存一些資料。例如用來備份簡訊。這個例子中,我們就用XmlSerializer介面來實現一個備份簡訊的程式。當然了,為了程式簡單化,這個程式我們並不是
spring+redis 報錯 org.springframework.core.serializer.support.DeserializingConverter.(Ljava/lang
這個問題的原因大概就是spring-data-redis.jar包版本不對 ,下面版本可以正常啟動
<dependency>
<groupId>org.springframework.data</groupId>
<artifactI
rest-framework的APIview原始碼分析,Serializer及解析器原始碼分析
rest-framework
1.安裝
方式一:pip3 install djangorestframework
方式二:pycharm圖形化介面安裝
方式三:pycharm命令列下安裝(裝在當前工程所用的直譯器下)
2.djangorestframework的APIVi
DRF 定義序列化器Serializer
定義Serializer
1. 定義方法
Django REST framework中的Serializer使用類來定義,須繼承自rest_framework.serializers.Serializer。
例如,我們已有了一個數據庫模型類BookInfo
class BookInf
DAY97 - Rest Framework(二)- 序列化元件之Serializer和ModelSerializer
一、序列化元件之Serializer
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_fram
Django框架(十九)—— 序列化元件(serializer)
目錄
序列化元件
一、利用for迴圈來實現序列化(繁瑣)
二、利用Django提供的序列化元件(不可控需要的欄位)
三、利用drf提供的序列化元件
1、基於Serializer類實現序列化——基本語法
2、基於Serializer類實現序
螞蟻金服通訊框架SOFABolt解析 |序列化機制(Serializer)
SOFA
Scalable Open Financial Architecture
是螞蟻金服自主研發的金融級分散式中介軟體,包含了構建金融級雲原生架構所需的各個元件,是在金融場景裡錘鍊出來的最佳實踐。
本文為《螞蟻金服通訊框架SOFABolt解析》系列第二篇,
Django框架 --序列化元件(serializer)
一 、Django自帶序列化元件
Django內建的serializers(把物件序列化成json字串)
from django.core import serializers
from django.core import serializers
def test(request):
django drf 的serializer原始碼分析
1,一般我們都是例項化呼叫data方法開始
dimension_serializer = self.get_serializer(
instance=queryset, many=True).data
按繼承關係,是呼叫serializer的data方法
@pro