1

我有一个具有类方法的模型。在测试类方法工作并根据我的需要更改模型实例。问题是在管理员中使用此类方法。当应用程序无法支付滞纳金时,应用程序创建另一个更改余额的交易。模型中的方法用 @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)

我需要获取它,以便在状态更改时,或者在管理员中为应用程序检查复选框时,它会触发类方法。我在管理员中搜索了覆盖模型,但找不到任何东西。这是管理员:

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

非常感谢您阅读本文。

4

1 回答 1

0

我现在找到了解决方案(对不起,如果我最初的问题不是很清楚)。事实证明,我需要覆盖 Application 模型中的保存功能。但是,这样做时又提出了另一个问题。如果用户更改了诸如客户名称之类的良性内容,那么即使没有真正的更改,类方法也会触发并创建新事务。因此,我们必须覆盖模型中的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)
于 2017-10-25T08:55:50.103 回答