Django のシリアライズの具体的な使用方法
I. はじめに
django rest フレームワークのシリアライゼーションコンポーネントは、間違いなくその中核をなすコンポーネントで、シリアライゼーションだけでなく、データの検証 (django のフォームと同様) にも通常最も使用するものです。
プレゼンテーションのためのシリアライズ操作を容易にするために、モデルに外部キー、多対多のケースを追加する必要があります。以下は新しいモデルです(元のデータベースを削除して再移行してください)。
models.py
from django.db import models
class UserInfo(models.Model):
user_type_choice = (
(1,"normal_user"),
(2,"member"),
)
user_type = models.IntegerField(choices=user_type_choice)
username = models.CharField(max_length=32,unique=True)
password = models.CharField(max_length=64)
foreignKey(to='UserGroup',null=True,blank=True)
roles = models.ManyToManyField(to='Role')
class UserToken(models.Model):
user = models.OneToOneField(to=UserInfo)
token = models.CharField(max_length=64)
class UserGroup(models.Model):
"""UserGroup"""
name = models.CharField(max_length=32,unique=True)
class Role(models.Model):
"""Role"""
name = models.CharField(max_length=32,unique=True)
II. 使用方法
1. 基本的な使用方法
新しいロールのurlをurls.pyに追加します。以前のurlは、邪魔にならないようにここにコメントされています。
from django.conf.urls import url
from app01 import views
urlpatterns = [
# url(r'^api/v1/auth', views.AuthView.as_view()),# url(r'^api/v1/order', views.OrderView.as_view()),
url(r'^api/v1/roles', views.RoleView.as_view()), # RoleView
# url(r'^api/(?P<version>[v1|v2]+)/user', views.UserView.as_view(),name="user_view"),
]
views.py
from rest_framework import serializers
from rest_framework.views import APIView
from django.shortcuts import HttpResponse
from app01 import models
import json
class RolesSerializer(serializers.Serializer): #Define serialization class
id=serializers.IntegerField() #define the serialized field to be extracted, with the same name as the field defined in the model
name=serializers.CharField()
class RoleView(APIView):
"""role"""
def get(self,request,*args,**kwargs):
roles=models.Role.objects.all()
res=RolesSerializer(instance=roles,many=True) #instance accept queryset object or a single model object, when there are multiple data, use many=True, single object many=Falsereturn HttpResponse(json.dumps(res.data,ensure_ascii=False))
ブラウザでhttp://127.0.0.1:8000/api/v1/roles にアクセスすると、以下のようになります。
2. カスタムシリアライズフィールド
データモデルに外部キーや多対多がある場合、シリアライズをカスタマイズする必要があります。
ユーザー情報のurlを追加
from django.conf.urls import url
from app01 import views
urlpatterns = [
# url(r'^api/v1/auth', views.AuthView.as_view()),# url(r'^api/v1/order', views.OrderView.as_view()),
url(r'^api/v1/roles', views.RoleView.as_view()),
url(r'^api/v1/userinfo', views.UserinfoView.as_view()), # User information
# url(r'^api/(?P<version>[v1|v2]+)/user', views.UserView.as_view(),name="user_view"),
]
UserinfoViewとシリアライゼーションクラス
class UserinfoSerializer(serializers.ModelSerializer):
id = serializers.IntegerField() # Define the serialized field to be extracted, with the same name as the field defined in the model
username = serializers.CharField()
password=serializers.CharField()
#CharField(source='user_type') #This method can only get the ID of user_type
sss=serializers.CharField(source='get_user_type_display') #custom field name, and the data model is not consistent, you need to specify the essence of the source call get_user_type_display() method to get the data
# rl=serializers.CharField(source='roles.all.first.name')
gp=serializers.CharField(source='group.name')
rl=serializers.SerializerMethodField() #Many-to-many serialization method one
def get_rl(self,obj): # Name fixed: field name defined by get_
"""
Custom serialization
:param obj: the passed model object, which is already encapsulated here
:return:
"""
roles=obj.roles.all().values() # get all roles
return list(roles) # the returned result must be a json serializable object
class Meta:
model = models.UserInfo
fields = ['id', 'username', 'password', 'ssss', 'rl', 'gp'] # Configure the fields to serialize
# fields = "__all__" use all the fields in the model
class UserinfoView(APIView):
"""Userinfo"""
def get(self,request,*args,**kwargs):
users=models.UserInfo.objects.all()
res=UserinfoSerializer(instance=users,many=True) # instance accept queryset object or single model object, when there are multiple data, use many=True, single object many=False
return HttpResponse(json.dumps(res.data,ensure_ascii=False))
アクセスする http://127.0.0.1:8000/api/v1/userinfo をクリックすると結果が表示されます。
上記のSerializerの他に、Serializerを継承したModelSerializerも使用でき、上記の例と同じ結果になります。
class UserinfoSerializer(serializers.ModelSerializer):
id = serializers.IntegerField() # Define the serialized field to be extracted, with the same name as the field defined in the model
username = serializers.CharField()
password=serializers.CharField()
#CharField(source='user_type') #This method can only get the ID of user_type
sss=serializers.CharField(source='get_user_type_display') #custom field name, and the data model is not consistent, you need to specify the essence of the source call get_user_type_display() method to get the data
# rl=serializers.CharField(source='roles.all.first.name')
gp=serializers.CharField(source='group.name')
rl=serializers.SerializerMethodField() #Many-to-many serialization method one
def get_rl(self,obj): # Name fixed: field name defined by get_
"""
Custom serialization
:param obj: the passed model object, which is already encapsulated here
:return:
"""
roles=obj.roles.all().values() # get all roles
return list(roles) # the returned result must be a json serializable object
class Meta:
model = models.UserInfo
fields = ['id', 'username', 'password', 'ssss', 'rl', 'gp'] # Configure the fields to serialize
# fields = "__all__" use all the fields in the model
class UserinfoView(APIView):
"""Userinfo"""
def get(self,request,*args,**kwargs):
users=models.UserInfo.objects.all()
res=UserinfoSerializer(instance=users,many=True) # instance accept queryset object or single model object, when there are multiple data, use many=True, single object many=False
return HttpResponse(json.dumps(res.data,ensure_ascii=False))
3. 連結されたテーブルのシリアライズと深さ制御
深さによる深度制御、シリアライズが深いほど可読性は高くなる
class UserinfoSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
#fields = "__all__" # Use all the fields in the model
fields = ['id', 'username', 'password', 'group', 'roles'] # configure the fields to serialize
depth = 1 # serialization depth, 1~10, it is recommended to use no more than 3
class UserinfoView(APIView):
"""Userinfo"""
def get(self,request,*args,**kwargs):
users=models.UserInfo.objects.all()
res=UserinfoSerializer(instance=users,many=True) # instance accept queryset object or single model object, when there are multiple data, use many=True, single object many=False
return HttpResponse(json.dumps(res.data,ensure_ascii=False))
リクエスト http://127.0.0.1:8000/api/v1/userinfo で、以下のような結果が得られました。
4. シリアライズされたフィールドのURL
urls.py 新しいグループ url
urlpatterns = [
# url(r'^api/v1/auth', views.AuthView.as_view()),# url(r'^api/v1/order', views.OrderView.as_view()),
url(r'^api/v1/roles', views.RoleView.as_view()),
url(r'^api/v1/userinfo', views.UserinfoView.as_view()),
url(r'^api/v1/group/(?P<xxx>\d+)', views.GroupView.as_view(),name='gp'), # New group url
# url(r'^api/(?P<version>[v1|v2]+)/user', views.UserView.as_view(),name="user_view"),
]
views.py
class UserinfoSerializer(serializers.ModelSerializer):
group=serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='xxx')
#view_name, the view alias (name) of the urls.py target url, here is the view alias of UserGroup
#lookup_field, the parameter passed to the url, i.e. the field for regular matching
#lookup_url_kwarg, the regular name of the url, which is the key in kwargs
class Meta:
models = models.UserInfo
#fields = "__all__" # use all the fields in the model
fields = ['id', 'username', 'password', 'roles', 'group'] # configure the fields to serialize
depth = 1 # serialization depth, 1~10, it is recommended to use no more than 3
class UserinfoView(APIView):
"""Userinfo"""
def get(self,request,*args,**kwargs):
users=models.UserInfo.objects.all()
res=UserinfoSerializer(instance=users,many=True,context={'request': request}) #instance accepts queryset objects or single model objects, use many=True when there are multiple data, single object many=False
# If you need to generate hyperlink fields, you need to add context={'request': request}
return HttpResponse(json.dumps(res.data,ensure_ascii=False))
class UserGroupSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserGroup
fields = "__all__"
depth = 0
class GroupView(APIView):
def get(self,request,*args,**kwargs):
group_id=kwargs.get('xxx')
group_obj=models.UserGroup.objects.get(id=group_id)
res=UserGroupSerializer(instance=group_obj,many=False) # instance accept queryset object or single model object, when there are multiple data, use many=True, single object many=False
return HttpResponse(json.dumps(res.data,ensure_ascii=False))
この時点でグループ情報にアクセスすると、http://127.0.0.1:8000/api/v1/group/1 以下のような結果になります。
ユーザー情報の閲覧では、この時点で生成されたグループはハイパーリンクの形になっています(jsonデータを見やすくするために、ここではpostmanを使ってリクエストを送信しています)。
Django のシリアライズの具体的な使用方法については、この記事がすべてです。Django のシリアライゼーションについてもっと知りたい方は、 Script House の過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。
関連
-
Pythonの文字列の詳細
-
[解決済み] np.meanとtf.reduce_meanの違いは何ですか?
-
[解決済み] Python3 で dict_keys の要素にインデックスでアクセスする
-
[解決済み] 名前パターンをインポートできない
-
[解決済み] Pythonでリストをフォーマットして各要素を別行動で表示するには?[重複]。
-
[解決済み] Kerasのtensorflowセッションはどこですか?
-
[解決済み] Python: urllib.error.HTTPError: HTTP Error 404: 見つかりません
-
LinearAlgebraError: SVDが収束しなかった(PYTHON)
-
python3 実行エラー。TypeError: タイプ 'type'のオブジェクトは、JSONシリアライザブルソリューションではありません。
-
Python共通関数まとめ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】IndexError: invalid index to scalar variableを修正する方法
-
行列の平均と標準偏差を詳細に計算するPython Numpyの実装
-
Pythonミニアプリケーション(コード付き)5選
-
[解決済み] ValueError: 解凍するために0個以上の値が必要(pythonのリスト)
-
[解決済み] python - ログで無効な値が検出されました。
-
[解決済み] TensorFlow:変数の初期化で「初期化されていない値を使おうとしています。
-
[解決済み] scrapyとpythonを使ったtsetmc.comのウェブページからのウェブスクレイピング
-
[解決済み] Python Queue の項目を調べる
-
エラー:イテレータはバイトではなく文字列を返すべき(ファイルをテキストで開いたか?
-
Pythonのエラーです。ValueError: not enough values to unpack expected 3, got 2 (解凍するための十分な値がありません。