Ⅰ.drfシリアル化を使用した作成および更新の注意事項
①フィールドが必須でない場合、フロントエンドは値 ""の空の文字列でフィールドを渡します。現時点では、作成時にエラーが報告されます。方法はありません。フィールドに値を渡す必要があります。
解決策:
フィールドのシーケンスにallow_blank = Trueを追加します。
class ApplySerializer(serializers.ModelSerializer):
last_version = serializers.CharField(required=False, allow_blank=True)
approve_second = serializers.CharField(required=False, allow_blank=True)
task_name = serializers.CharField(required=False, allow_blank=True)
②シリアル化検証ルール
1.シングルフィールド検証
class AvailAreaSerializer(serializers.ModelSerializer):
name = serializers.CharField(
validators=[UniqueValidator(
queryset=AvailArea.objects.filter(is_delete=False), message=u'name已存在')]
)
2.複数のフィールドのチェック
class CodeConfigSerializer(serializers.ModelSerializer):
bk_id = serializers.IntegerField(required=True)
class Meta:
model = CodeConfig
fields = '__all__'
validators = [
UniqueTogetherValidator(
queryset=CodeConfig.objects.all(),
fields=(
'bk_type', 'bk_code',
),
message='该类型编码已被使用'
)
]
3.カスタムバリデーター
key_validator = RegexValidator(
re.compile('^[_a-zA-Z0-9]+$'),
message=_(u'请输入合法编码:英文数字及下划线'),
code='invalid',
)
class DictDataSerializer(serializers.ModelSerializer):
"""数据字典数据项序列化"""
key = serializers.CharField(required=True, error_messages={'blank': _(u"编码不能为空")}, max_length=LEN_LONG,
validators=[key_validator])
重みの順序:カスタムバリデーター>単一フィールド検証>複数フィールド検証
注:シーケンスリストの作成と更新が検証されます。
更新時ではなく作成時に検証する場合は、個人的な提案方法作成方法を書き直します。
class ProStoreConfigSerializer(serializers.ModelSerializer):
class Meta:
model = ProStoreConfig
exclude = ('is_deleted',)
def create(self, validated_data):
if not result:
raise serializers.ValidationError("制品库配置账户密码错误")
queryset = ProStoreConfig.objects.all()
if queryset.count():
raise serializers.ValidationError("制品库配置已配置过了")
else:
instance = super(ProStoreConfigSerializer, self).create(validated_data=validated_data)
return instance
Ⅱ。リストフィルタリング
1.オリジナルフィールドフィルタリング
class BasicConfigFilter(django_filters.FilterSet):
bk_biz_id = django_filters.Filter(name='bk_biz_id')
bk_cluster_id = django_filters.Filter(name='bk_cluster_id')
bk_module_id = django_filters.Filter(name='bk_module_id')
class Meta:
model = BasicConfig
fields = '__all__'
2.フロントエンドの単一フィールドは、バックエンドのマルチフィールド検索に対応します。
フロントエンドの入力ボックスは、受信者と携帯電話番号に従って検索し、バックエンドと同様に受信者に渡されます。
class NotifyLogFilter(django_filters.FilterSet):
receiver = django_filters.Filter(method="filter_receiver", help_text="接收者匹配")
class Meta:
model = NotifyLog
fields = '__all__'
def filter_receiver(self, queryset, name, value):
return queryset.filter(Q(receiver_name__icontains=value) | Q(receiver_phone__icontains=value))
3.カスタムフィールドフィルタリング
class ApplyFilter(django_filters.FilterSet):
bk_biz_id = django_filters.Filter(name='bk_biz_id', method="filter_by_bk_biz_id")
bk_cluster_id = django_filters.Filter(name='bk_cluster_id', method="filter_by_bk_cluster_id")
bk_module_id = django_filters.Filter(name='bk_module_id', method="filter_by_bk_module_id")
now_version = django_filters.Filter(name="now_version", lookup_expr="icontains")
creator = django_filters.Filter(name="creator", method="filter_by_creator")
class Meta:
model = Apply
fields = '__all__'
def filter_by_creator(self, queryset, name, value):
if value == "admin":
return queryset
else:
return queryset.filter(creator=value)
def filter_by_bk_biz_id(self, queryset, name, value):
return queryset.filter(basic_config__bk_biz_id=value)
def filter_by_bk_cluster_id(self, queryset, name, value):
return queryset.filter(basic_config__bk_cluster_id=value)
def filter_by_bk_module_id(self, queryset, name, value):
return queryset.filter(basic_config__bk_module_id=value)
短所:要求に基づいて一部のフィルターフィールドが取得された場合、それらをフィルター処理する方法がありません。第二に、検索の内容、フロントエンドのいくつかのフィールド値に従って検索結果のフィールド値を変更したい、それを変更することはできず、属性値の設定はサポートされていません。 listメソッドが書き直され
ました。Ⅲ。シリアル化によって返されるカスタムフィールドを追加します
class BasicConfig(Model):
bk_biz_id = models.IntegerField(_('业务id'), null=True)
bk_cluster_id = models.IntegerField(_('集群id'), null=True)
bk_module_id = models.IntegerField(_('模块id'), null=True)
publish_count = models.IntegerField(_('版本发布次数'), default=1)
# 0 未启用 1 已启用
status = models.BooleanField(_('启用状态'), default=0)
class Meta:
app_label = "configs"
verbose_name = _("基础配置")
verbose_name_plural = _("基础配置")
@property
def bk_biz_name(self):
bk_biz_name, _, _ = self.get_topo_data
return bk_biz_name
@property
def bk_cluster_name(self):
_, bk_cluster_name, _ = self.get_topo_data
return bk_cluster_name
@property
def bk_module_name(self):
_, _, bk_module_name = self.get_topo_data
return bk_module_name
@property
def get_topo_data(self):
result = cache.get(CACHE_BIZ_TOPOLOGY_NAME)
if not result:
result = get_biz_topology()
data = result.get(self.bk_biz_id)
bk_biz_name = data.get('bk_inst_name')
bk_cluster_name = None
bk_module_name = None
for i in data.get('child'):
if i.get('bk_inst_id') == self.bk_cluster_id:
bk_cluster_name = i.get('bk_inst_name')
for j in i.get('child'):
if j.get('bk_inst_id') == self.bk_module_id:
bk_module_name = j.get('bk_inst_name')
return bk_biz_name, bk_cluster_name, bk_module_name
@property
def process_config(self):
process_config_obj = ProcessConfig.objects.get(basic_config=self)
return model_to_dict(process_config_obj)
@property
def version_config(self):
version_config_obj = VersionConfig.objects.get(basic_config=self)
return model_to_dict(version_config_obj)
@property
def approve_config(self):
approve_config_obj = ApproveConfig.objects.get(basic_config=self)
return model_to_dict(approve_config_obj)
@property
def bk_biz_code(self):
biz_obj = CodeConfig.objects.filter(bk_id=self.bk_biz_id, bk_type=BIZ)
return biz_obj[0].bk_code if biz_obj else None
@property
def bk_cluster_code(self):
cluster_obj = CodeConfig.objects.filter(bk_id=self.bk_cluster_id, bk_type=CLUSTER)
return cluster_obj[0].bk_code if cluster_obj else None
@property
def bk_module_code(self):
module_obj = CodeConfig.objects.filter(bk_id=self.bk_module_id, bk_type=MODULE)
return module_obj[0].bk_code if module_obj else None
def code_version(self, date_time):
code_version = \
str(self.bk_biz_code) \
+ date_time + str(self.bk_module_code) + "." + str(self.publish_count)
return code_version
シリアル化はカスタムフィールドを返します。再表現(自己、インスタンス)メソッドは必要ありません。
class BasicConfigSerializer(serializers.ModelSerializer):
bk_biz_id = serializers.IntegerField(required=True)
bk_cluster_id = serializers.IntegerField(required=True)
bk_module_id = serializers.IntegerField(required=True)
class Meta:
model = BasicConfig
fields = ('id', 'bk_biz_id', 'bk_cluster_id', 'bk_module_id',
'bk_biz_name', 'bk_cluster_name', 'bk_module_name',
'bk_biz_code', 'bk_cluster_code', 'bk_module_code',
'process_config', 'version_config', 'approve_config',
'status', 'publish_count',
'updated_by', 'update_at',
'creator', 'create_at'
)
validators = [
UniqueTogetherValidator(
queryset=BasicConfig.objects.filter(is_deleted=0),
fields=(
'bk_biz_id', 'bk_cluster_id', 'bk_module_id'
),
message='该系统环境已配置过发布流程'
)
]
Ⅳ。カスタムメソッドはパラメータを受け入れることに注意してください
class ProcessConfigViewSet(component_viewsets.ModelViewSet):
serializer_class = ProcessConfigSerializer
queryset = ProcessConfig.objects.all()
@list_route(methods=['POST'], url_path='get_topology_data')
def get_topology_data(self, request):
"""从缓存中获取业务拓扑"""
# params = {'bk_biz_id': 2}
params = request.data
result = cache.get(CACHE_BIZ_TOPOLOGY_NAME)
if not result:
result = get_biz_topology()
result = result.get(params.get('bk_biz_id')).get('child')
return Response({"items": result, "count": len(result)})
注:カスタムメソッドがPOSTリクエストの場合、request.dataを使用して受け入れ、request.bodyを使用して受け入れないでください。ローカルで開発する場合、request.bodyはフロントエンドから渡された値を受け入れることができます。オンラインでデプロイする場合は、request。 bodyは、フロントエンドから取得できない値です。request.dataを使用してください。
また、request.dataの値は直接jsonであり、json.loads()は必要ありません。