You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django中如何判断客户月度房产付款到期日已到并筛选待付款客户

Django房产分期订阅系统到期客户筛选实现方案

现有代码问题修正

首先梳理现有模型的两处可优化点:

  1. Payment模型中时间字段为datetime,原get_pending_customer方法中误用created_at字段会触发字段不存在报错
  2. 缺少每月固定还款额、还款周期规则的核心字段,无法直接计算到期时间

模型补充与功能实现

第一步:补充必要字段与核心方法

修改后的models.py完整代码如下:

from django.db import models
from django.db.models import Sum
from datetime import datetime, timedelta
from decimal import Decimal
from dateutil.relativedelta import relativedelta # 处理自然月偏移,避免28/30/31天误差

class Property(models.Model):
    """房产模型"""
    area = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=17, decimal_places=2, default=0.0,)
    created_on = models.DateTimeField(auto_now_add=True)

class Customer(models.Model):
    """客户模型"""
    name = models.CharField(max_length=255)
    prop_select = models.ForeignKey(Property, on_delete=models.SET_NULL, null=True)
    created_on = models.DateTimeField(auto_now_add=True)
    remaning_amount = models.DecimalField(max_digits=17, decimal_places=2, default=0.0)
    # 补充核心业务字段:每月固定还款额、首次还款到期日
    monthly_payment = models.DecimalField(max_digits=17, decimal_places=2, default=0.0)
    first_due_date = models.DateField()

    def save(self, *args, **kwargs):
        if self.prop_select:
            property_price = self.prop_select.price
            payment_done_by_customer = Payment.objects.filter(customer=self).aggregate(Sum('amount'))['amount__sum'] or Decimal('0')
            self.remaning_amount = property_price - payment_done_by_customer
        super(Customer, self).save(*args, **kwargs)

    def is_payment_due(self):
        """判断当前客户当期还款是否到期"""
        # 已经结清的客户直接返回未到期
        if self.remaning_amount <= 0:
            return False
        # 计算已完成还款次数
        paid_count = self.payment.count()
        # 计算当期应还款日期:首次还款日叠加已还款次数对应的自然月
        current_due_date = self.first_due_date + relativedelta(months=paid_count)
        # 若当前日期超过应还款日则判定为到期
        return datetime.now().date() >= current_due_date

    def is_overdue(self):
        """判断客户是否到期未还款"""
        if not self.is_payment_due():
            return False
        paid_count = self.payment.count()
        current_due_date = self.first_due_date + relativedelta(months=paid_count)
        # 检查到期日后是否有对应足额还款记录
        has_paid = self.payment.filter(datetime__date__gte=current_due_date, amount__gte=self.monthly_payment).exists()
        return not has_paid

    @classmethod
    def get_overdue_customers(cls):
        """批量筛选所有逾期未还款的客户"""
        return [c for c in cls.objects.filter(remaning_amount__gt=0) if c.is_overdue()]

class Payment(models.Model):
    """还款记录模型"""
    customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL, related_name='payment')
    datetime = models.DateTimeField(auto_now_add=True)
    amount = models.DecimalField(max_digits=17, decimal_places=2, default=0.0)

注:代码中使用的relativedelta来自python-dateutil第三方库,可通过pip install python-dateutil安装,用于解决2月、大小月天数不同导致的还款日偏移误差,如果你不需要精确到自然月,也可以直接用timedelta(days=30)替换

功能使用说明

  • 获取所有当期付款已到期的客户:遍历所有未结清客户,调用is_payment_due()方法,返回True即为到期客户
  • 直接筛选所有到期未支付的客户:调用Customer.get_overdue_customers()即可拿到结果列表
  • 若数据量较大不需要单独判断单个客户状态,也可以直接通过Django ORM的annotate和条件查询实现批量筛选,性能更高

内容的提问来源于stack exchange,提问作者afi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 23:09:02