關係字段用於表示模型關係。它們可以應用到ForeignKey,ManyToManyField和OneToOneField關係,以及扭轉的關係,以及自定義關係等GenericForeignKey。
下面我們就一對多關係爲例:
MODEL:
class Kuaidi(models.Model):
name=models.CharField(max_length=40,verbose_name='快遞公司')
daimai=models.CharField(max_length=11,unique=True,verbose_name='公司代碼')
address=models.CharField(max_length=100,verbose_name='公司地址')
class Meta:
db_table='kuaidi'
verbose_name='快遞公司'
verbose_name_plural=verbose_name
def __str__(self):
return self.name
class Goods(models.Model):
name=models.CharField(max_length=40,verbose_name='商品名')
danhao=models.CharField(max_length=11,unique=True,verbose_name='快遞單號')
price=models.DecimalField(decimal_places=2,max_digits=9,verbose_name='商品價格')
kuaidi_id=models.ForeignKey(Kuaidi,on_delete=models.CASCADE,related_name='kuaidi',verbose_name='外鍵關聯')
class Meta:
db_table='goods'
verbose_name = '商品'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
StringRelatedField
該字段是隻讀的。
參數:
many- 如果應用於對多關係,則應將此參數設置爲True。
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi = serializers.StringRelatedField(many=True)
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')
PrimaryKeyRelatedField
PrimaryKeyRelatedField 可以用於使用其主鍵表示關係的目標ID。
參數:
queryset - 驗證字段輸入時用於模型實例查找的查詢集。關係必須顯式設置或設置查詢集read_only=True。
many- 如果應用於多對多關係,則應將此參數設置爲True。
allow_null- 如果設置爲True,則該字段將接受None可爲空的關係的值或空字符串。默認爲False。
pk_field - 設置爲字段以控制主鍵值的序列化/反序列化。例如,pk_field=UUIDField(format=‘hex’)將UUID主鍵序列化爲其緊湊的十六進制表示。
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi = serializers.PrimaryKeyRelatedField(many=True,read_only=True)
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')
HyperlinkedRelatedField## 標題
可以用於使用超鏈接表示關係的目標,默認情況下,此字段是讀寫的,但可以使用該read_only標誌更改此行爲。
參數:
view_name - 應該用作關係目標的視圖名稱。如果您正在使用標準路由器類,則這將是具有該格式的字符串-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參數覆蓋。
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi=serializers.HyperlinkedIdentityField(view_name='demo:goods-detail',read_only=True,many=True)
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')
SlugRelatedField
用於使用目標上的字段來表示關係的目標,用作讀寫字段時,通常需要確保slug字段對應於帶有的模型字段unique=True。
參數:
slug_field - 目標上應該用於表示它的字段。這應該是唯一標識任何給定實例的字段。例如,username。 需要
queryset - 驗證字段輸入時用於模型實例查找的查詢集。關係必須顯式設置或設置查詢集read_only=True。
many- 如果應用於多對多關係,則應將此參數設置爲True。
allow_null- 如果設置爲True,則該字段將接受None可爲空的關係的值或空字符串。默認爲False。
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi=serializers.SlugRelatedField(many=True,read_only=True,slug_field='name')
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')
HyperlinkedIdentityField
可以作爲標識關係應用,例如’url’HyperlinkedModelSerializer上的字段。它也可以用於對象的屬性。HyperlinkedRelatedField是可以讀寫的,而HyperlinkedIdentityField始終爲只讀。
參數:
view_name - 應該用作關係目標的視圖名稱。如果您正在使用標準路由器類,則這將是具有該格式的字符串<model_name>-detail。 要求。
lookup_field - 目標上應該用於查找的字段。應該對應於引用視圖上的URL關鍵字參數。默認是’pk’。
lookup_url_kwarg - URL conf中定義的關鍵字參數的名稱,該參數對應於查找字段。默認使用相同的值lookup_field。
format- 如果使用格式後綴,超鏈接字段將爲目標使用相同的格式後綴,除非使用format參數覆蓋
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi=serializers.HyperlinkedIdentityField(view_name='demo:goods-detail',many=True,read_only=True)
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')
嵌套關係
嵌套關係可以使用序列化程序作爲字段來表示。
如果該字段用於表示多對多關係,則應將該many=True標誌添加到序列化程序字段。
默認情況下,嵌套序列化程序是隻讀的
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi=GoodsSerializers(many=True,read_only=True)
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')
可寫嵌套序列化程序
如果要支持對嵌套序列化程序字段的寫操作,則需要創建create()和/或update()方法,以便明確指定應如何保存子關係。
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi=GoodsSerializers(many=True)
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')
def create(self, validated_data):
tracks_data = validated_data.pop('kuaidi_id')
good = Goods.objects.create(**validated_data)
for track_data in tracks_data:
Goods.objects.create(good=good, **track_data)
return good
自定義關係字段
可以實現一個完全自定義的關係字段,該字段準確描述應如何從模型實例生成輸出表示。
要實現自定義關係字段,應該覆蓋RelatedField並實現該.to_representation(self, value)方法。此方法將字段的目標作爲value參數,並應返回應用於序列化目標的表示。該value參數通常是模型實例。
如果要實現讀寫關係字段,還必須實現該.to_internal_value(self, data)方法。
要提供基於的動態查詢集context,您還可以覆蓋.get_queryset(self)而不是.queryset在類上指定或初始化字段時。
class GoodsSerializers(serializers.ModelSerializer):
class Meta:
model=Goods
fields='__all__'
class GoodsRelatedField(serializers.RelatedField):
def to_representation(self, value):
return '快遞商品爲:%s' % value.name
class KuaidiSerializers(serializers.ModelSerializer):
kuaidi=GoodsRelatedField(read_only=True,many=True)
class Meta:
model=Kuaidi
fields=('name','daimai','address','kuaidi')