首页 > 解决方案 > 来自 django 视图集中请求的额外字段

问题描述

我正在使用 django 视图集,我希望验证请求中有一个额外的字段。

我想要的是应该来自请求的额外字段role_id。如果通过了角色 ID,我应该将员工转换为用户并将角色 ID 分配给用户。

即使我从请求中发送 role_id,但我无法在 create 或 update 方法中获取它。有人可以帮我知道如何从回复中获取额外的字段

序列化程序.py

class EmployeeModelSerializer(serializers.ModelSerializer):
    """Employee model serializer"""

    address = EmployeeAddressModelSerializer(required=False)
    detail = EmployeeDetailModelSerializer(required=False)
    demographic = EmployeeDemographicModelSerializer(required=False)
    contact = EmployeeContactModelSerializer(required=False)
    nok = EmployeeNokModelSerializer(required=False)
    visa = EmployeeVisaModelSerializer(required=False)
    dbs = EmployeeDBSModelSerializer(required=False)
    job_detail = EmployeeJobDetailModelSerializer(required=False)
    preference = EmployeePreferenceModelSerializer(required=False)
    skills = EmployeeSkillsModelSerializer(many=True, read_only=True)
    user = UserModelSerializer(required=False)



    serializersMap = {
        "address": EmployeeAddressModelSerializer,
        "detail": EmployeeDetailModelSerializer,
        "demographic": EmployeeDemographicModelSerializer,
        "contact": EmployeeContactModelSerializer,
        "nok": EmployeeNokModelSerializer,
        "visa": EmployeeVisaModelSerializer,
        "dbs": EmployeeDBSModelSerializer,
        "job_detail": EmployeeJobDetailModelSerializer,
        "preference": EmployeePreferenceModelSerializer,
        "user": UserModelSerializer,
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.context["gender"] = None
        self.context["title"] = None
        self.context["marital_status"] = None
        self.context["employee_status"] = None

    def internal_validate(self, data, field):
        self.context[field] = data
        if data == None:
            return data
        elif data.id:
            return data.id
        return data

    def validate_gender(self, data):
        return self.internal_validate(data, "gender")

    def validate_title(self, data):
        return self.internal_validate(data, "title")

    def validate_marital_status(self, data):
        return self.internal_validate(data, "marital_status")

    def validate_employee_status(self, data):
        return self.internal_validate(data, "employee_status")

    user = serializers.SlugRelatedField(
        read_only=True,
        slug_field='username'
    )

    class Meta:
        """Meta class."""

        model = Employee
        fields = '__all__'

    def get_fullname(self, obj):
        return obj.first_name + " " +  obj.last_name

    def create(self, data):
        data["address"] = self.saveForeign(data, "address")
        data["detail"] = self.saveForeign(data, "detail")
        data["demographic"] = self.saveForeign(data, "demographic")
        data["contact"] = self.saveForeign(data, "contact")
        data["nok"] = self.saveForeign(data, "nok")
        data["visa"] = self.saveForeign(data, "visa")
        data["dbs"] = self.saveForeign(data, "dbs")
        data["job_detail"] = self.saveForeign(data, "job_detail")
        data["preference"] = self.saveForeign(data, "preference")
        data.pop("skills", None)
        
        self.setContext(data)

        employee = Employee.objects.create(**data)        
        
        return employee

    def update(self, instance, data):
        instance.address = self.updateForeign(instance.address, data, "address")
        instance.detail = self.updateForeign(instance.detail, data, "detail")
        instance.demographic = self.updateForeign(instance.demographic, data, "demographic")
        instance.contact = self.updateForeign(instance.contact, data, "contact")
        instance.nok = self.updateForeign(instance.nok, data, "nok")
        instance.visa = self.updateForeign(instance.visa, data, "visa")
        instance.dbs = self.updateForeign(instance.dbs, data, "dbs")
        instance.job_detail = self.updateForeign(instance.job_detail, data, "job_detail")
        instance.preference = self.updateForeign(instance.preference, data, "preference")
        self.setContext(data)

        return super(EmployeeModelSerializer, self).update(instance, data)


    def saveForeign(self, data, name):
        field = data.get(name)
        data.pop(name, None)

        if field is None:
            return None

        serializer = self.serializersMap.get(name)(data=field)
        if serializer.is_valid(raise_exception=True):
            return serializer.save()

    def updateForeign(self, instance, data, name):
        field = data.get(name)
        data.pop(name, None)

        if field is None:
            return None

        
        if not instance:
            serializer = self.serializersMap.get(name)(data=field, context={})
            if serializer.is_valid(raise_exception=True):
                return serializer.save()
        else:
            serializer = self.serializersMap.get(name)(instance, data=field, context={})
            if serializer.is_valid(raise_exception=True):
                return serializer.update(instance, field)

    def setContext(self, data):
        if self.context["gender"] != None:
            data["gender"] = self.context['gender']

        if self.context["title"] != None:
            data["title"] = self.context['title']

        if self.context["marital_status"] != None:
            data["marital_status"] = self.context['marital_status']

        if self.context["employee_status"] != None:
            data["employee_status"] = self.context['employee_status']




视图.py

    """Employee view set"""

    # authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    queryset = Employee.objects.filter(is_active=True).order_by('-modified')
    serializer_class = EmployeeModelSerializer
    
    filter_backends = (SearchFilter, OrderingFilter, DjangoFilterBackend)
    filter_fields = [
        "job_detail__employment_type_id",
        "job_detail__employee_category_id",
        "job_detail__job_title_id",
        "skills__name__id"
    ]
    
    ordering_fields = [
        'modified',
        'job_detail__branch__name',
        'full_name',
        'reference',
        'employee_status__name',
        'address__name'
    ]
    
    search_fields = [
        'full_name',
        'last_name',
        
        'address__zip_code',
        'contact__mobile_number'
    ]

    def destroy(self, request, pk=None):

        employee = self.get_object()
        employee.is_active = False
        employee.save()
        
        return Response({'message': 'deleted!'}, status=status.HTTP_200_OK)

模型.py

class Employee(Person):
    user = models.ForeignKey(
        'users.User',
        null=True,
        on_delete=models.SET_NULL
    )

    employee_status = models.ForeignKey(
        'core.Employee_Status',
        null=True,
        blank=True,
        on_delete=models.SET_NULL
    )

    title = models.ForeignKey(
        'core.Title',
        null=True,
        blank=True,
        on_delete=models.SET_NULL
    )

    payroll_ref = models.CharField(
        'Payroll -Reference',
        max_length=25,
        blank=True,
        default=''
    )

    address = models.OneToOneField(
        'employees.Employee_Address',
        null=True,
        on_delete=models.SET_NULL
    )

    contact = models.OneToOneField(
        'employees.Employee_Contact',
        null=True,
        on_delete=models.SET_NULL
    )

    dbs = models.OneToOneField(
        'employees.Employee_dbs',
        null=True,
        on_delete=models.SET_NULL
    )

    demographic = models.OneToOneField(
        'employees.Employee_Demographic',
        null=True,
        on_delete=models.SET_NULL
    )

    detail = models.OneToOneField(
        'employees.Employee_Detail',
        null=True,
        on_delete=models.SET_NULL
    )

    job_detail = models.OneToOneField(
        'employees.Employee_Job_Detail',
        null=True,
        on_delete=models.SET_NULL
    )

    nok = models.OneToOneField(
        'employees.Employee_NOK',
        null=True,
        on_delete=models.SET_NULL
    )

    preference = models.OneToOneField(
        'employees.Employee_Preference',
        null=True,
        on_delete=models.SET_NULL
    )

    visa = models.OneToOneField(
        'employees.Employee_Visa',
        null=True,
        on_delete=models.SET_NULL
    )

    skills = models.ManyToManyField(
        'employees.Employee_Skill',
        related_name='Employee',
    )

    class Meta:
        verbose_name = 'Employee - Basic Info'
        verbose_name_plural = 'Employees - Basic Info'

请求参数

{
    "first_name": "first name",
    "last_name": "last name",
    "date_of_birth": "2017-02-12",
    "is_active": true,
    "role_id": "role_id_goes_here",
    "address": {
        "name": "address name",
        "line_1": "line 1",
        "city": "city",
        "state": "state",
        "country": "country",
        "zip_code": "zip code"
    },
    "nok": {
        "no": "123sad",
        "full_name": "full name nok",
        "mobile": 123456789,
        "email": "jesus@iconos.mx",
        "title": null
    },
    "title": null
}

标签: djangodjango-rest-frameworkdjango-viewsdjango-serializer

解决方案


推荐阅读