from rest_framework import serializers
python
先後端交互主要有get
,post
,puch
,put
,deleter
數據庫
其中用到序列化的get
django
用到反序列化的剩下四中後端
serializers.Serializer
的類class UserSerializer(serializers.Serializer): username = serializers.CharField() #不須要的字段=serializers.CharField(write_only=True) sex = serializers.IntegerField() gender = serializers.SerializerMethodField() def get_gender(self, user_obj): return user_obj.get_sex_display() icon = serializers.SerializerMethodField() #SerializerMethodField爲自定義字段 def get_icon(self, user_obj): icon_url = 'http://127.0.0.1:8000{}{}'.format(settings.MEDIA_URL, user_obj.icon) return icon_url
自定義字段,拿gander
字段舉例在models中是框架
SEX_CHOICES = [ (0, '男'), #choices選擇中,括號裏前者表示填寫的值,後者表示對應的值 (1, '女'), ] # 爲choices的字段,獲取值後的映射關係 get_字段名_display() sex = models.IntegerField(choices=SEX_CHOICES, default=0)
def get_gender(self, user_obj): return user_obj.get_sex_display()
基於GET請求的get_固定寫法 def get_model類中有字段(self,obj): #邏輯處理 return 修改後的代碼
須要序列化字段
函數
在不作任何處理的狀況下
咱們定義的類裏面的字段必須在model類中必須存在該字段read_only=True
SerializerMethodField
及自定義字段類型不用遵照類裏面的字段必須在model類中必須存在該字段
不須要序列化字段
post
write_only=True
from rest_framework.views import APIView class UserAPIView(APIView): def get(self, request, *args, **kwargs): user_obj = models.User.objects.all().frist user_obj_data = '''咱們自定義的Serializer類'''(user_obj).data return APIResponse(0, 'ok', results=user_obj_data)
.data
many=True
還需傳入這個參數many
這個參數默認是False全部咱們序列化單個參數時候不須要傳入many
單列集合
,不能是多列集合注
:ui
[a,b,c.....]
|{a,b,c.....}
|(a,b,c.....)
|QuerySet
{k1:v1,k2:v2.......}
serializers.Serializer
的類class UserDeserializer(serializers.Serializer): username = serializers.CharField( min_length=3, error_messages={ 'min_length': '用戶名過短' } ) password = serializers.CharField( min_length=3, error_messages={ 'min_length': '密碼過短' } ) re_password = serializers.CharField( min_length=3, required=True, error_messages={ 'min_length': '確認密碼過短', 'required': '確認密碼不能爲空' } )
相較於序列化定義
反序列化中增長了條件的篩選url
注意點
:若是類的字段值應用在反序列化,咱們能夠在他的字段的屬性上加上write_only=True
rest
裏面所說起的字段必須傳入
經常使用的約數條件與django中from組件約數條件有點相似
:
error_messages
錯誤信息的屬性required
是否爲空max_length
最長min_length
最短invalid
格式class UserDeserializer(serializers.Serializer): ....... def validate_字段名稱(self,value): #代碼塊 if 狀況不知足: raise serializers.ValidationError('異常信息') #拋出異常 return value #也就是對字段數據進行二次處理
class UserDeserializer(serializers.Serializer): ....... def validate(self, attrs): #attrs是全部字段的一個相似字典的集合 #咱們要其中某個字段 attrs.get('字段名') return attrs # 最終結果拋出異常或者返回attrs
咱們若是想自定義create的相關內容咱們能夠Serializer類中
再加個create
方法
class UserDeserializer(serializers.Serializer): ....... def create(self, validated_data): try: return modles中的類.objects.create(**validated_data) except: raise IOError('數據庫入庫失敗')
咱們更具需求能夠先自定義一個APIResponse,繼承rest_framework中的Response也能夠直接使用他自帶的
自定義APIResponse,建議自定義
from rest_framework.response import Response """ Response({ 'status': 0, 'msg': 'ok', 'results': [], 'token': '' }, headers={}, status=200, content_type="") APIResponse(0, 'ok', results, status, headers, content_type) """ class APIResponse(Response): def __init__(self, data_status, data_msg, results=None, status=None, headers=None, content_type=None, **kwargs): data = { 'status': data_status, 'msg': data_msg } if results is not None: data['results'] = results data.update(kwargs) super().__init__(data=data, status=status, headers=headers, content_type=content_type)
在視圖函數中的設置
class UserAPIView(APIView): def post(self, request, *args, **kwargs): #通常都是post請求 request_data = request.data user_ser = '''咱們自定義的Serializer類'''(data=request_data) #傳入request.data if user_ser.is_valid(): # 自定義處理校驗成功的邏輯 user_obj = user_ser.save() return APIResponse(0, 'ok', results=serializers.UserSerializer(user_obj).data ) else: # 自定義返回錯誤信息 return APIResponse(1, 'failed', results=user_ser.errors)
咱們若是想自定義update的相關內容咱們能夠Serializer類中
再加個update
方法
class UserDeserializer(serializers.Serializer): ....... def update(self, instance, validated_data): # instance自定義傳入的要更新的原數據(pk | obj | queryset) # validated_data校驗經過後的新數據 # instance的值外部反序列化傳入要更新的自定義標識決定 instance.update(**validated_data) return instance.first()
在視圖函數中的設置
單總體改
class UserV2APIView(APIView): def put(self, request, *args, **kwargs): pk = kwargs.get('pk') if not pk: return APIResponse(1, 'pk error') user_query = models.User.objects.filter(pk=pk, is_delete=False) if not user_query: return APIResponse(1, 'user error') # 第一種:user_query完成數據的更新 # user_query = models.User.objects.filter(pk=pk) # user_query.update(**kwargs) # 第二種:user_obj完成數據的更新 # user_obj = models.User.objects.filter(pk=pk).first() # type: models.User # user_obj.username = 'new_username' # ... # user_obj.save() #這裏的instance必須傳參(pk | obj | queryset) request_data = request.data user_ser = serializers.UserV2Serializer(instance=user_query, data=request_data) if user_ser.is_valid(): # save的返回值是由update內部自定義的返回值決定 user_obj = user_ser.save() return APIResponse(0, 'ok', results=serializers.UserV2Serializer(user_obj).data ) else: return APIResponse(1, 'failed', user_ser.errors)
單刪
或單體修改
如今數據都是很重要的通常狀況下不會吧數據刪除只會作個標記字段其本質仍是局部更新
def delete(self, request, *args, **kwargs): pk = kwargs.get('pk') if not pk: return APIResponse(1, 'pk error') user_obj = models.User.objects.filter(pk=pk, is_delete=False).first() if not user_obj: return APIResponse(1, '刪除失敗') user_obj.is_delete = True user_obj.save() return APIResponse(0, '刪除成功')
model.py
create_time = models.DateTimeField(auto_now_add=True, null=True) is_delete = models.BooleanField(default=False)
setting.py
時區相關設置
LANGUAGE_CODE = 'zh-hans' #其中 zh-Hans是簡體中文 zh-Hant是繁體中文 TIME_ZONE = 'Asia/Shanghai' #上海時間 USE_I18N = True #國際化支持 I18N USE_L10N = True USE_TZ = False #USE_TZ設置爲True,Django會使用系統默認設置的時區即America/Chicago,此時的TIME_ZONE無論有沒有設置都不起做用。
注意點:
USE_TZ爲True
,TIME_ZONE
無論有沒有設置都不起做用