首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >DRF - django_filters -Using自定义方法

DRF - django_filters -Using自定义方法
EN

Stack Overflow用户
提问于 2020-05-18 11:24:15
回答 2查看 3K关注 0票数 0

我有个这样的模特:

代码语言:javascript
运行
复制
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函数为每个协议返回真或假

我有这样一个简单的过滤器:

代码语言:javascript
运行
复制
class AgreementFilter(filters.FilterSet):
    file_no = filters.NumberFilter(lookup_expr='icontains')

    class Meta:
        model = Agreement
        fields = ['file_no',] 

我认为不能在属性字段上进行筛选,因为Django过滤器在数据库级别上运行。那么,如果协议模型对象是有效的,无效的,或者是真的还是假的,那么如何使它工作呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-25 06:42:13

通过使用“方法”参数来指定自定义方法- 参见django-过滤器文档,我成功地编写了一个自定义筛选器来过滤过期和有效的协议。

代码语言:javascript
运行
复制
from datetime import timedelta
from django.db.models import F, Case, When, BooleanField
from django_filters import rest_framework as filters

class AgreementFilter(filters.FilterSet):

    file_no = filters.NumberFilter(lookup_expr='icontains')
    is_expired = filters.BooleanFilter(method='filter_is_expired')

    class Meta:
        model = Agreement
        fields = ['file_no',] 

      def filter_is_expired(self, queryset, name, value):
        if value is not None:
            queryset = queryset.annotate(

                expired=Case(When(contract_date__lt=timezone.now().date() - (timedelta(days=365) * F('contract_time')),
                             then=True), default=False, output_field=BooleanField())).filter(expired=value)
        return queryset

如果通过计算协议的对象为true或false,Queryset将返回:

已过期协议的

代码语言:javascript
运行
复制
http://127.0.0.1:8000/api/agreement/?is_expired=True

以及有效协议的

代码语言:javascript
运行
复制
http://127.0.0.1:8000/api/agreement/?is_expired=False
票数 0
EN

Stack Overflow用户

发布于 2020-05-19 17:13:55

您可以在Agreement模型中添加新字段,该模型保留协议的到期日期:

代码语言:javascript
运行
复制
expiry_date = models.DateField()

如果contract_time字段是合同仍然有效的年份,并且在添加新合同时知道该字段,那么您可以像现在一样计算到期日期,并将其添加到expiry_date字段,而不需要属性装饰器。

现在,您希望在添加新记录时自动完成此操作,为此您可以使用pre_save 信号

代码语言:javascript
运行
复制
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,这将是相当容易的,在前端只使用当前日期和传递它作为过滤器参数,以显示仅协议的日期大于当前日期。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61868500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档