Repository: ansible/awx
File: awx/api/serializers.py (Python)

Code before:
        return attrs

    def validate_with_obj(self, attrs, obj):
        """
        Overwrite this if you need the model instance for your validation.

        :param dict attrs: The names and values of the model form fields.
        :raise django.core.exceptionsValidationError: Raise this if your
            validation fails.

            To make the error shown at the respective form field, instantiate
            the Exception with a dict containing the field name as key and the
            error message as value.

            Example: ``ValidationError({"password": "Not good enough!"})``
        :return: None
        """
        return

    def reverse(self, *args, **kwargs):
        kwargs['request'] = self.context.get('request')
        return reverse(*args, **kwargs)

    @property
    def is_detail_view(self):
        if 'view' in self.context:
            if 'pk' in self.context['view'].kwargs:
                return True
        return False


class EmptySerializer(serializers.Serializer):
    pass


class UnifiedJobTemplateSerializer(BaseSerializer):
    # As a base serializer, the capabilities prefetch is not used directly,
    # instead they are derived from the Workflow Job Template Serializer and the Job Template Serializer, respectively.
    capabilities_prefetch = []

    class Meta:
        model = UnifiedJobTemplate
        fields = ('*', 'last_job_run', 'last_job_failed', 'next_job_run', 'status', 'execution_environment')

    def get_related(self, obj):
        res = super(UnifiedJobTemplateSerializer, self).get_related(obj)
        if obj.current_job:
            res['current_job'] = obj.current_job.get_absolute_url(request=self.context.get('request'))
        if obj.last_job:
            res['last_job'] = obj.last_job.get_absolute_url(request=self.context.get('request'))
        if obj.next_schedule:

Review comment (suggestion):
Requesting clarification in method docstring - does `obj` have updated attributes?

There are 2 cases:
 - new object
 - updating existing object

In the 1st case the answer is obvious. In the 2nd case, I don't know if I have the "old object" or the "new object".

Code after:
            for k in attrs.keys():
                if k not in exclusions:
                    attrs[k] = getattr(obj, k)
        except DjangoValidationError as exc:
            # DjangoValidationError may contain a list or dict; normalize into a
            # dict where the keys are the field name and the values are a list
            # of error messages, then raise as a DRF ValidationError.  DRF would
            # normally convert any DjangoValidationError to a non-field specific
            # error message; here we preserve field-specific errors raised from
            # the model's full_clean method.
            d = exc.update_error_dict({})
            for k, v in d.items():
                v = v if isinstance(v, list) else [v]
                v2 = []
                for e in v:
                    if isinstance(e, DjangoValidationError):
                        v2.extend(list(e))
                    elif isinstance(e, list):
                        v2.extend(e)
                    else:
                        v2.append(e)
                d[k] = list(map(force_str, v2))
            raise ValidationError(d)
        return attrs

    def validate_with_obj(self, attrs, obj):
        """
        Overwrite this if you need the model instance for your validation.

        :param dict attrs: The names and values of the model form fields.
        :param obj: An instance of the class's meta model.

            If the serializer runs on a newly created object, obj contains only
            the attrs from its serializer. If the serializer runs because an
            object has been edited, obj is the existing model instance with all
            attributes and values available.
        :raise django.core.exceptionsValidationError: Raise this if your
            validation fails.

            To make the error appear at the respective form field, instantiate
            the Exception with a dict containing the field name as key and the
            error message as value.

            Example: ``ValidationError({"password": "Not good enough!"})``

            If the exception contains just a string, the message cannot be
            related to a field and is rendered at the top of the model form.
        :return: None
        """
        return