djangoRESTフレームワークの学習と使用の概要

Ⅰ.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()は必要ありません。

おすすめ

転載: blog.csdn.net/qq_42631707/article/details/106915583