2017-02-13 47 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

如果我必須進行驗證,需要考慮兩個字段,那麼您的建議解決方案將不起作用。 –