2017-02-13 50 views
1

以下是我模型定义验证在django的其余框架补丁方法

class ProfessionalQualification(Log_Active_Owned_Model_Mixin): 

    PROF_TEACHER = 1 
    PROF_ENGINEER = 2 
    PROF_DOCTOR  = 4 
    PROF_PROFESSOR = 8 
    PROF_MANAGER = 16 
    PROF_CLERK  = 32 
    PROF_SALESMAN = 64 
    PROF_BUSINESSMAN= 128 
    PROF_OTHER  = 129 

    VALID_PROFESSIONS = (
     (PROF_TEACHER,  "Teacher" ), 
     (PROF_ENGINEER,  "Engineer" ), 
     (PROF_DOCTOR,  "Doctor" ), 
     (PROF_PROFESSOR, "Professor"), 
     (PROF_MANAGER,  "Manager" ), 
     (PROF_CLERK,  "Clerk" ), 
     (PROF_SALESMAN,  "Salesman" ), 
     (PROF_BUSINESSMAN, "Businessman"), 
     (PROF_OTHER,  "Other" ) 
    ) 

    profession_type   = IntegerField(choices=VALID_PROFESSIONS, null=False, blank=False) 
    profession_type_name = CharField(max_length=60, null=True, blank=True) 
    institue    = CharField(max_length=160, null=False, blank=False) 
    address     = ForeignKey(to=City, null=False) 
    year_start    = CurrentYearField(null=False, blank=False) 
    in_progress    = BooleanField(null=False, blank=False) 
    year_end    = CurrentYearField(null=True, blank=True) 

以下是我串行器在串行器

class ProfQualSerializer(OwedModelSerializerMixin, ModelSerializer): 

    #address = ConcreteAddressSerializer() 
    class Meta: 
     model = UserProfessionalQual 
     fields = (
        "profession_type", "profession_type_name", \ 
        "institue", "address", "year_start", 
        "in_progress", "year_end" 
       ) 

    def validate(self, dict_input): 
     errors = defaultdict(list) 
     profession_type = dict_input["profession_type"] 

     if profession_type == UserProfessionalQual.PROF_OTHER: 
      try: 
       RestAPIAssert(dict_input.get("profession_type_name", None), 
           "Profession-type-name must be passed, for other type of profession", 
           log_msg="Profession-type-name not passed", exception=ValidationError) 

      except ValidationError as e: 
       errors["profession_type"].append(str(e)) 

     year_start = dict_input["year_start"] 
     year_end = dict_input.get("year_end", None) 
     in_progress = dict_input.get("in_progress", None) 

     request  = self._context["request"] 
     user_dob = request.user.dob 
     age   = request.user.age 

     current_time = datetime.datetime.now() 
     if not user_dob: 
      user_dob = relativedelta(current_time, years=age) 

     if year_start < user_dob.year: 
      errors["year_start"].append("Year-start can't be before user's DOB") 

     elif year_start > year_end: 
      errors["year_start"].append("Year-end can't be before year-start") 

     elif year_end > current_time.year: 
      dict_input["in_progress"] = True 

     else: 
      # if user have not passed in_progress flag, then 
      # set it false. 
      if dict_input.get("in_progress", None) == None: 
       dict_input["in_progress"] = False 

     if errors: 
      raise ValidationError(errors) 

     return dict_input 

我已经定义validate()方法,其中在串行器级执行验证(不是在现场级别)。现在,问题在于,对于仅涉及特定字段的http方法,它为那些不属于请求主体部分的字段提供了键错误。

什么是编写上述validate()方法的最佳方法,以便它可以在POST,PUT和PATCH方法中使用?

在此先感谢。

+0

当与有不同的本密钥数量词典处理,我总是使用'获得()'呼叫。您在代码中混用了该密钥和直接密钥访问。如果不知道究竟哪个键抛出了错误,我建议的最好的方法是将所有字典键访问改为使用'.get()',然后将它们包含在条件中以正确处理它们是否为None。 – Neelik

+1

@ Neelik,问题不在于访问字典。我可以肯定使用get()。但是,我的问题是重要的。如何处理patch(),create()和put()方法验证。在create()和put()中,所有键都可用,但在patch()中,某些键可能会丢失。我可以为它编写简单的解决方案。但我想知道如何做到这一点的标准方法。 –

回答

1

您可以定义validate_ < field_name>方法来验证特定字段,这样如果字段包含在请求数据中,它将被验证;否则它不会被验证。

例如:

def validate_year_start(self, value): 
    year_start = value 
    request  = self._context["request"] 
    user_dob = request.user.dob 
    age   = request.user.age 

    current_time = datetime.datetime.now() 
    if not user_dob: 
     user_dob = relativedelta(current_time, years=age) 

    if year_start < user_dob.year: 
     raise serializers.ValidationError({"year_start":"Year-start can't be before user's DOB"}) 
    return value 
+0

如果我必须进行验证,需要考虑两个字段,那么您的建议解决方案将不起作用。 –