Reputation: 11420
Following is my model definition
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)
Following is my serializer
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
I have defined validate() method in serializer, which performs validations at serializer level(not at field level). Now, the problem is that, for PATCH
http method, where only certain fields are involved, it gives keyerror for those fields, which are not part of request body.
What's the best way to write the above validate() method, so that it works in both POST, PUT and PATCH methods ?
Thanks in advance.
Upvotes: 11
Views: 5072
Reputation: 2214
Use self.partial
in the validate method to find out if it's a partial update.
def validate(self, data):
if self.partial:
print("Partial update")
return data
Upvotes: 11
Reputation: 134
you can define validate_< field_name > method to validate specific field, in this way if the field is included in request data, it will be validated; otherwise it will not be validated.
For example:
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
Upvotes: 0