def __init__(self, *args, **kwargs):
        super(PaymentMethod, self).__init__(*args, **kwargs)

        # Gonna do_fetch = False here. We don't want to fetch every object every time we run PaymentMethod.objects.all() in the shell
        # And we won't have control over fetching when we do a filter.
        self._core_remote_object = CorePaymentMethod(
            feefighters=settings.SAMURAI_CREDENTIALS, payment_method_token=self.payment_method_token, do_fetch=False
        )

        self._get_fields_from_core()
class PaymentMethod(models.Model, RemoteObject):
    payment_method_token = models.CharField(max_length=100, editable=False, unique=True)
    user = models.ForeignKey(User, editable=False)
    last_transaction_error = models.BooleanField(default=False)  # stores whether the last transaction was an error
    disabled = models.BooleanField(default=False)

    def __init__(self, *args, **kwargs):
        super(PaymentMethod, self).__init__(*args, **kwargs)

        # Gonna do_fetch = False here. We don't want to fetch every object every time we run PaymentMethod.objects.all() in the shell
        # And we won't have control over fetching when we do a filter.
        self._core_remote_object = CorePaymentMethod(
            feefighters=settings.SAMURAI_CREDENTIALS, payment_method_token=self.payment_method_token, do_fetch=False
        )

        self._get_fields_from_core()

    def _get_fields_from_core(self):
        for field_name in self._core_remote_object.field_names + ["payment_method_token", "populated"]:
            setattr(self, field_name, getattr(self._core_remote_object, field_name))

    def _set_fields_into_core(self):
        for field_name in self._core_remote_object.field_names:
            setattr(self._core_remote_object, field_name, getattr(self, field_name))

    def fetch(self):
        self._set_fields_into_core()
        result = self._core_remote_object.fetch()
        self._get_fields_from_core()
        return result

    def redact(self):
        self._set_fields_into_core()
        result = self._core_remote_object.redact()
        self._get_fields_from_core()
        return result

    def retain(self):
        self._set_fields_into_core()
        result = self._core_remote_object.retain()
        self._get_fields_from_core()
        return result

    def update(self):
        self._set_fields_into_core()
        result = self._core_remote_object.update()
        self._get_fields_from_core()
        return result

    def clean(self):
        "checks the custom field for a unique identifier related to self.user as a security measure"

        if self.custom.get("django_user_unique", None) != secret_id_for_user(self.user):
            raise ValidationError("Secret user id doesn't match!")
        if "django_prev_payment_method_token" in self.custom:
            prev_payment_method_token_query = PaymentMethod.objects.filter(
                payment_method_token=self.custom["django_prev_payment_method_token"]
            )
            if prev_payment_method_token_query.exists():
                if prev_payment_method_token_query[0].user != self.user:
                    raise ValidationError("Old payment method token of different user.")