django - DRF - django_filters - 使用自定义方法
问题描述
我有一个这样的模型:
class Agreement(models.Model):
file_no = models.IntegerField(primary_key=True)
contract_date = models.DateField()
contract_time = models.IntegerField()
@property
def calculate_expiry_date(self):
return self.contract_date + relativedelta(years=self.contract_time)
@property
def is_expired(self):
return (self.contract_date + relativedelta(years=self.contract_time)) < timezone.now().date()
is_expired
函数为每个协议返回 true 或 false
我有一个像这样的简单过滤器:
class AgreementFilter(filters.FilterSet):
file_no = filters.NumberFilter(lookup_expr='icontains')
class Meta:
model = Agreement
fields = ['file_no',]
我认为我无法过滤属性字段,因为 Django 过滤器在数据库级别运行。那么,如果协议模型对象有效或无效或真或假,我怎样才能使其工作呢?
解决方案
您可以向模型添加新字段,以Agreement
保持协议的到期日期:
expiry_date = models.DateField()
如果contract_time
字段是合同有效期的年数,并且您在添加新合同时知道它,那么您可以像现在一样计算到期日期并将其添加到expiry_date
字段中,而无需属性装饰器。
现在您希望在添加新记录时自动完成,为此您可以使用 pre_save信号。
from django.dispatch import receiver
from django.db.models import signals
@receiver(signals.pre_save, sender=WorkDone)
def calculate_expiry_date(sender, instance, **kwargs):
instance.expiry_date = instances.contract_date + \
relativedelta(years=instance.contract_time)
对于过滤部分,您可以使用当前日期来过滤记录。由于您使用的是 DRF,这将非常容易,在前端只需使用当前日期并将其作为过滤器参数传递,以显示仅显示日期大于当前日期的协议。