带有附加参数的 Django 自定义模型方法

Posted

技术标签:

【中文标题】带有附加参数的 Django 自定义模型方法【英文标题】:Django Custom model method with additional parameters 【发布时间】:2020-08-24 20:57:45 【问题描述】:

我正在构建一个自行车租赁应用程序。

前端:用户选择开始和结束日期,并在列表视图中获取所有可用的自行车、带有类别和适当价格的自行车。

价格:价格是根据 2 个条件计算的。车辆类别和持续时间。(因为价格有持续时间。

1-3 天 = 145 美元运动

1-3 天 = 145 美元的滑板车

4-7 天 = 2004 运动版

4-7 天 = 2004 踏板车等

只能从前端表单中选择的日期来实现持续时间,然后将其转换为天数。

我需要将这些天作为持续时间来获得合适的价格并在列表视图中相应地显示在每个类别下。

模型.PY

类车辆类别:

@property
    def price(self, duration):
        for item in VehiclePrice.objects.all():
            If item.vehicle_category.title == self.title and (duration >= item.slab.start and duration <= item.slab.end):
            return item.net_price

VIEWS.PY

类 HomeView(ListView):

template_name = 'app/home.html'

def get(self, request): 


    if request.method == "GET":
        start_date =  request.GET.get('start_date')
        end_date =  request.GET.get('end_date')

        if start_date and end_date:
            start_date = datetime.strptime(start_date, "%m/%d/%Y").date()
            end_date = datetime.strptime(end_date, "%m/%d/%Y").date()

            duration = (end_date - start_date).days +1



        vehiclecategory= VehicleCategory.objects.all()

        context = 
            'vehiclecategory1': vehiclecategory.filter(main_category= 'E-Cycle'),
            'vehiclecategory2': vehiclecategory.filter(main_category= 'E-Scooter'),
            'form':CartQuantityForm(),
            'dateform': DateForm()
        


    return render(request, self.template_name, context )

这里我得到了持续时间,如何在模型方法价格参数中传递这个并让上面的查询集工作????“”“

【问题讨论】:

如果您希望 price() 成为方法,请删除 @property 装饰器。除非您定义了额外的 setter,否则您不能将参数传递给属性,但这很可能不是您想要使用的。 好吧,我只需要在模型VehicleCategory中添加价格,你认为我可以在模型中添加一个字段并编写一个方法吗? 您希望显示所有您的类别还是仅显示具有特定价格的类别? 所有类别。因为所有类别都会有价格。 【参考方案1】:

Views.py

template_name = 'app/home.html'

def get(self, request): 


    if request.method == "GET":
        start_date =  request.GET.get('start_date')
        end_date =  request.GET.get('end_date')

        vehiclecategory= VehicleCategory.objects.all()

        if start_date and end_date:
            start_date = datetime.strptime(start_date, "%m/%d/%Y").date()
            end_date = datetime.strptime(end_date, "%m/%d/%Y").date()

            duration = (end_date - start_date).days +1
            vehiclecategory = vehiclecategory.filter(slab__start__lte=duration, slab__end__gte=duration)


        context = 
            'vehiclecategory1': vehiclecategory.filter(main_category= 'E-Cycle'),
            'vehiclecategory2': vehiclecategory.filter(main_category= 'E-Scooter'),
            'form':CartQuantityForm(),
            'dateform': DateForm()
        


    return render(request, self.template_name, context )

【讨论】:

好的,但我的问题是,如何将持续时间参数传递给方法? 你可以像vehicle|custom_tag:duration这样传递参数,其中vehicle是你的对象,custom_tag是你的自定义模板标签,duration是你要传递的参数。 我想我误解了你的问题。我认为你根本不需要那种方法。你能分享你完整的列表视图课程吗? 我的帖子有完整的列表视图类【参考方案2】:

根据您提供的价格信息,需要满足以下条件:

VehiclePrice.title == VehicleCategory.title VehiclePrice.slab.start VehiclePrice.slab.end >= 持续时间

请注意,使用 @property 您不能将参数传递给您的函数,因为您将使用 obj.price 而不是 obj.price(duration) 调用它。

这将导致以下查询集:

def price(self, duration):
    return VehiclePrice.objects.filter(
        title=self.title,
        slab__start__lte=duration,
        slab__end__gte=duration).first()

这将返回满足此条件的第一个对象。请注意,如果没有找到价格first() 根据docs 返回None

如果您想在模板中调用此方法,您必须创建一个 custom template tag 并将持续时间传递给该标签才能返回价格。

另一种选择是获取视图中的所有类别并使用它们获取相关价格。

您还可以使用 annotate 将价格对象附加到您的模型中,因为以下链接可能会有所帮助:

https://***.com/a/47725075/6836173 https://***.com/a/38131573/6836173

【讨论】:

以上是关于带有附加参数的 Django 自定义模型方法的主要内容,如果未能解决你的问题,请参考以下文章

带有自定义用户模型加载夹具错误的 Django 项目

使用带有附加参数的自定义规则验证 Laravel 中的数组

Django:使用带有 executemany 和 MySQL 的自定义原始 SQL 插入

带有来自模型的自定义验证消息的 Django 1.5 基于类的视图

2016-11-11坚持学习Day24WPF 自定义控件 附加属性 自定义事件

Django Admin后台管理