0

I am building a bike rental ap.

frontend: user selects the start and end dates and get all the available bikes in a list view, bikes with categories and appropriate price.

Price: price is calculated on 2 conditions. Vehiclecategory and duration.(as price has duration slabs.

1-3 days = 145$ sporty

1-3 days = 145$ scooter

4-7 days = 2004 sporty

4-7 days = 2004 scooter etc.

Duration can only be achieved from the chosen dates from the form in front-end, which gets converted to days.

I need to pass these days as duration to get the appropriate price and display it under each category accordingly in a list view.

MODELS.PY

class VehicleCategory:

@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

class 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 )

here I get the duration, how can I pass this in the model method price parameter and get the above Queryset to work????"""

san
  • 11
  • 8
  • If you want `price()` to be a method, remove the `@property` decorator. You can't pass a parameter to a property unless you defined an extra setter, but that's most likely not what you want to use. – wfehr May 09 '20 at 08:27
  • alright, I just need to add price to the model VehicleCategory, do u think I can add a field in model and write a method? – san May 09 '20 at 08:51
  • Do you want *all* your categories to be shown or only those with a certain price? – wfehr May 09 '20 at 09:05
  • all categories. cos all categories will have a price. – san May 09 '20 at 09:16

2 Answers2

1

From the informations you gave the price needs the following conditions to be true:

  • VehiclePrice.title == VehicleCategory.title
  • VehiclePrice.slab.start <= duration
  • VehiclePrice.slab.end >= duration

Note that with @property you can't pass arguments to your function since you will call it with obj.price instead of obj.price(duration).

This would result in the following QuerySet:

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

This returns the first object that meets this conditions. Note that if no prices are found first() returns None according to the docs.

If you want to call this method in your template you have to create a custom template tag and pass duration to that tag in order to return the price.

Another option is to get all the categories in your view and fetch the depending prices with them.

You can also work with annotate to attach the price-object to your model, for that maybe the following links help:

wfehr
  • 2,185
  • 10
  • 21
-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 )
Jeet
  • 362
  • 1
  • 5
  • ok, but my question is, how to I pass the duration parameter to the method? – san May 09 '20 at 09:18
  • you can pass parameter like this `vehicle|custom_tag:duration`, where `vehicle` is your object, `custom_tag` is your custom template tag and `duration` is parameter which you want to pass. – Jeet May 09 '20 at 09:29
  • I think I misunderstood your question. I think you don't need that method at all. Can you share you full listview class? – Jeet May 09 '20 at 09:59
  • my post has the full list view class – san May 10 '20 at 02:43