Resumen de aprendizaje y uso de django rest framework

Ⅰ. Precauciones para la creación y actualización mediante serialización drf
① Cuando un campo no es obligatorio, el front-end pasa el campo con el valor "" cadena vacía. En este momento, informará de un error cuando se cree. No hay forma para crearlo, y solicitar esto El campo debe pasar un valor.
Solución:
Agregue allow_blank = True a la secuencia del campo

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)

②Reglas de verificación de serialización
1. Verificación de campo único

class AvailAreaSerializer(serializers.ModelSerializer):
    name = serializers.CharField(
        validators=[UniqueValidator(
            queryset=AvailArea.objects.filter(is_delete=False), message=u'name已存在')]
    )

2. Comprobación de varios campos

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. Validador personalizado

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])

Orden de peso: validador personalizado> validación de campo único> validación de campo múltiple.
Nota: La creación y actualización de la lista de secuencia será verificada.
Si desea verificar al crear, no al actualizar, método de sugerencia personal Vuelva a escribir el método de creación

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

Ⅱ. Filtrado de listas
1. Filtrado de campos originales

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. El campo único de front-end corresponde a la búsqueda de múltiples campos de back-end.
Un cuadro de entrada en el front-end, busca según el destinatario y el número de teléfono móvil, y pasa al receptor como el back-end

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. Filtrado de campos personalizados

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)

Desventajas: cuando se obtienen algunos campos de filtro en función de la solicitud, no hay forma de filtrarlos. En segundo lugar, el contenido de la búsqueda, desea cambiar el valor del campo en el resultado de la búsqueda de acuerdo con algunos valores de campo de la interfaz, no es posible cambiarlo y la configuración del valor del atributo no es compatible. Solo el el método de lista se reescribe
. Ⅲ. Agregar campos personalizados devueltos por serialización

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

La serialización devuelve campos personalizados, no es necesario volver a representar el método (auto, instancia)

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='该系统环境已配置过发布流程'
            )
        ]

Ⅳ. Tenga en cuenta que el método personalizado acepta parámetros

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)})

Nota: Cuando el método personalizado es una solicitud POST, use request.data para aceptar, no use request.body para aceptar. Cuando se desarrolla localmente, request.body puede aceptar el valor pasado por la interfaz. Cuando se implementa en línea, request. body es el valor que no se puede recuperar de la interfaz, use request.data.
Y el valor de request.data es directamente json, sin necesidad de json.loads ().

Supongo que te gusta

Origin blog.csdn.net/qq_42631707/article/details/106915583
Recomendado
Clasificación