DRF 處理模型中的選項字段

2021-09-13 02:28:14 字數 3513 閱讀 4551

django 中常常要用到選項字段

為了提高資料庫效率和使用者可讀性,我們實際儲存的是整數,顯示的時候以字串顯示。

這個屬性在 django admin 得到了很好的處理,但到了 django rest framework 就不會自動轉化了。

下面的在get的時候顯示字串,但這個欄位就變成唯讀但了。

# models.py

class user(abstractuser):

gender_choices = (

('m', 'male'),

('f', 'female'),

)gender = models.charfield(max_length=1, choices=gender_choices)

# serializers.py

class userserializer(serializers.modelserializer):

# 自定義了gender 字段,該欄位變成唯讀的了。

gender = serializers.charfield(source='get_gender_display')

class meta:

model = user

# viewsets.py

class userviewset(viewsets.modelviewset):

queryset = user.objects.all()

serializer_class = userserializer

這裡涉及到乙個有趣的例項方法:

get_foo_display

對於模型中含有++choices++引數的字段, foo 是字段的名字, get_foo_display() 返回選項的可讀字串

要實現 model 中的 choice field, 在 get 的時候顯示選項名字,在post的時候既能字串又能接受id

比如模型中有個status

# models.py

class commoninfo(models.model):

inactive = 0

published = 1

pending = -1

draft = -2

reported = -3

deleted = -4

status_choices = (

(inactive, 'inactive'),

(published, 'published'),

(pending, 'pending'),

(draft, 'draft'),

(reported, 'reported'),

(deleted, 'deleted'),

)status = models.smallintegerfield(

choices=status_choices, default=published)

# utils.py

from rest_framework import serializers

from collections import ordereddict

class choicedisplayfield(serializers.field):

"""custom choicefield serializer field."""

def __init__(self, choices, **kwargs):

"""init."""

self._choices = ordereddict(choices)

super(choicedisplayfield, self).__init__(**kwargs)

# 返回可讀性良好的字串而不是 1,-1 這樣的數字

def to_representation(self, obj):

"""used while retrieving value for the field."""

return self._choices[obj]

def to_internal_value(self, data):

"""used while storing value for the field."""

for i in self._choices:

# 這樣無論使用者post上來但是choices的 key 還是value 都能被接受

if i == data or self._choices[i] == data:

return i

raise serializers.validationerror("acceptable values are .".format(list(self._choices.values())))

# serializers.py

from utils import choicedisplayfield

class commoninfoserializer(serializers.modelserializer):

inactive = 0

published = 1

pending = -1

draft = -2

reported = -3

deleted = -4

status_choices = (

(inactive, 'inactive'),

(published, 'published'),

(pending, 'pending'),

(draft, 'draft'),

(reported, 'reported'),

(deleted, 'deleted'),

)status = choicedisplayfield(choices=status_choices)

from rest_framework import serializers

from collections import ordereddict

class choicedisplayfield(serializers.choicefield):

"""custom choicefield serializer field."""

def __init__(self, choices, **kwargs):

"""init."""

self._choices = ordereddict(choices)

super(choicedisplayfield, self).__init__(**kwargs)

# 返回可讀性良好的字串而不是 1,-1 這樣的數字

def to_representation(self, obj):

"""used while retrieving value for the field."""

return self._choices[obj]

參考

django模型 欄位和選項

一 常用字段 1 字段型別 使用時需要引入django.db.models包,字段型別如下 autofield 自動增長的integerfield,通常不用指定,不指定時django會自動建立屬性名為id的自動增長屬性 booleanfield 布林字段,值為true或false nullboole...

Django中欄位選項的使用

所有的模型欄位都可以接收一定數量的引數,比如charfield至少需要乙個max length引數。下面的這些引數是所有欄位都可以使用的,並且是可選的。說明 該值為true時,django在資料庫可以null儲存空值。預設值為false。對於儲存字串型別資料的字段,請盡量避免將此引數設為true,那...

Django框架 模型層 字段屬性和選項

django根據屬性的型別確定以下資訊 django會為表建立自動增長的主鍵列,每個模型只能有乙個主鍵列,如果使用選項設定某屬性為主鍵列後django不會再建立自動增長的主鍵列。預設建立的主鍵列屬性為id,可以使用pk代替,pk全拼為primary key。注意 pk是主鍵的別名,若主鍵名為id2,...