Как ввести метод класса модели в админке Django

У меня есть модель, которая имеет методы класса. При тестировании методы класса работают и изменяют экземпляры модели в соответствии с моими потребностями. Проблема заключается в использовании этого метода класса в админке. Когда приложение не может оплатить сбор за несвоевременную оплату, создается еще одна транзакция, изменяющая баланс. Метод в моделях украшен декоратором @classmethod:

class Transactions(models.Model):

    application = models.ForeignKey(Application, 
    related_name='application_id', blank=True, null=True)
    transaction_type = models.CharField(max_length=56, 
    choices=TRANSACTION_TYPE, null=True)
    transaction_source = models.CharField(max_length=56, 
    choices=TRANSACTION_SOURCE, null=True)
    transaction_method = models.CharField(max_length=56, 
    choices=TRANSACTION_METHOD, null=True)
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    created_date = models.DateField()
    posted_date = models.DateField()
    external_reference = models.CharField(max_length=100, null=True, 
    verbose_name='External Reference')

    def __unicode__(self):
        return self.application.forename + " " + 
        self.application.surname + "(" + str(self.application.id) + ")"

    @classmethod
    def late_payment_fee(cls, app, desired_action):
        """
        This function enacts a late payment fee to an application as a 
        transaction
        :param app: application the fee is going to be applied to
        :param desired_action: either True or False, when reversing the 
        fee the transaction shouldn't be deleted,
        just another transaction of the opposite effect in order to 
        help loans collection with tracking, True will
        enact a feee, False will reverse the fee
        :return: a transaction which is stored in the database
        """
        today = str(date.today())
        if desired_action:
            trans_type = MISSEDREPAYMENTFEE
            amount = float(12)
        else:
            trans_type = MISSEDREPAYMENTFEEREVERSAL
            amount = float(-12)
        cls.create_trasaction(app, trans_type, INTERNALBOOKING, 
        INTERNALBOOKING, amount, today, today, None)

Мне нужно, чтобы это было так, когда статус изменен или когда в админке для приложения установлен флажок, запускается метод класса. У меня есть переопределенные модели Google в админе, но я не могу ничего найти. Вот админ:

class ApplicationAdmin(ImportExportModelAdmin):
    resource_class = ApplicationResource
    search_fields = ['forename', 'surname']
    list_filter = ('status', 'underwritingresult', 'test', 'signed', 
    'mandateapproved', 'dealership', 'brand')
    list_select_related = ('instalment',)
    list_display = ('id', 'SPV_ID', 'forename', 'surname'......
    inlines = [
        InstalmentInline,
        AddressInline
    ]
    exclude = ['customer', 'accountnumber', 'sortcode']
    readonly_fields = ('Account_Number', 'Sort_Code', 'SPV_ID')

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = []
        if obj.locked :
            for field in self.model._meta.fields:
                readonly_fields.append(field.name)
        else:
            readonly_fields = ('Account_Number', 'Sort_Code', 'SPV_ID')
        return readonly_fields

    def Account_Number(self, obj):
        return Decrypt(obj.accountnumber)

    def Sort_Code(self, obj):
        return Decrypt(obj.sortcode)

    def SPV_ID(self, obj):
        return obj.spv.id

    def has_delete_permission(self, request, obj=None):
        return False

Большое спасибо за чтение этого.

1 ответ

Решение

Теперь я нашел решение (извините, если мой начальный вопрос был не очень ясен). Оказалось, что мне нужно переопределить функцию сохранения в модели приложения. Однако при этом возникла другая проблема. Если пользователь изменил что-то мягкое, например, имя клиента, тогда метод класса сработает и создаст новые транзакции, хотя реальных изменений не было. Из-за этого мы должны переопределить init и функцию save в модели, но все же фактически сохранить. Для этой модели нам интересно узнать, изменился ли статус или был применен поздний сбор. Чтобы сделать это, мы должны сохранить начальные значения статуса, переопределив метод init в модели:

__initial_status = None
__initial_fee_status = None

def __init__(self, *args, **kwargs):
    """
    This function overrides the __init__ function in order to
    save initial_status facilitating comparisons in the save function
    :param args: allows the function to accept an arbitrary number of 
    arguments and/or keyword arguments
    :param kwargs: same as above
    """
    super(Application, self).__init__(*args, **kwargs)
    self.__initial_status = self.status
    self.__initial_fee_status = self.feeadded 

Теперь мы сохранили их, мы можем передать их через нашу функцию сохранения. Если есть изменение, мы можем использовать метод класса:

def save(self, *args, **kwargs):
    """
    This function overrides the standard save function. The application
    is still saved, however, other functions are fired when it is 
    saved.
    :return: creates reversal commission and dealership transactions
    if the status is CANCELLED
    """
    if self.signed and self.status != self.__initial_status:
        if self.status == Application.CANCELLED:
            Transactions.create_commision_trasaction(app=self, 
            reverse=True)
            Transactions.create_dealership_trasaction(app=self, 
            reverse=True)
        elif self.status == Application.OK:
            Transactions.create_commision_trasaction(app=self, 
            reverse=False)
            Transactions.create_dealership_trasaction(app=self, 
            reverse=False)

    if self.signed and self.feeadded != self.__initial_fee_status:
        if self.feeadded:
            Transactions.late_payment_fee(app=self, desired_action=True)
        elif self.feeadded is False:
            Transactions.late_payment_fee(app=self, desired_action=False)

    super(Application, self).save(*args, **kwargs)
Другие вопросы по тегам