Coderaemon
Coderaemon

Reputation: 3867

Can't access price of a Product in Django-Oscar?

Trying to access the price of a product, Using Docs. But getting Attribute error.

>>> from oscar.apps.partner import strategy, prices
>>> from oscar.apps.catalogue.models import *
>>> product = Product.objects.get(pk=1)
>>> info = strategy.fetch_for_product(product)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'module' object has no attribute 'fetch_for_product'

To see all attributes of strategy I do

  >>> dir(strategy)
  >>> ['Base', 'D', 'Default', 'DeferredTax', 'FixedRateTax', 'NoTax', 'PurchaseInfo', 
    'Selector', 'StockRequired', 'Structured', 'UK', 'US', 'UseFirstStockRecord', 
'__builtins__', '__doc__', '__file__', '__name__',
 '__package__', 'availability', 'namedtuple', 'prices']

So fetch_for_product is not in attributes of strategy. Now how can I access the price of a particular product?

Upvotes: 5

Views: 1786

Answers (2)

Umar Asghar
Umar Asghar

Reputation: 4064

You can make a new serializer with custom field to load the category product with price, primary image and title using SerializeMethodField.

from rest_framework import serializers

from oscar.apps.partner.strategy import Selector

class ProductsSerializer(serializers.ModelSerializer):
    price = serializers.SerializerMethodField()
    availability = serializers.SerializerMethodField()
    images = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields= ('id', 'title','availability', 'images', 'price',)

    def get_price(self, obj):
        strategy = Selector().strategy()
        price = vars(strategy.fetch_for_product(obj).price)
        price['final'] = price['excl_tax'] + price['tax']
        return price

    def get_availability(self, obj):
        strategy = Selector().strategy()
        availability = vars(strategy.fetch_for_product(obj).availability)
        try:
            return availability['num_available']
        except KeyError:
            return -1

    def get_images(self, obj):
        try:
            return ['https://127.0.0.1:8000/'+str(obj.primary_image().original)]
        except AttributeError:
            return []

Upvotes: 2

patrys
patrys

Reputation: 2769

What you import above is the strategy module. What you want is the strategy object instead. The easiest way to obtain the strategy is to ask the strategy selector for one:

from oscar.apps.partner.strategy import Selector

selector = Selector()
strategy = selector.strategy(request=..., user=...)
purchase_info = strategy.fetch_for_product(product=...)
price = purchase_info.price

The selector is useful as it allows you to use different strategies depending on the context (a particular user, request coming from a particular country etc.). In your own store you would override the Selector with your own implementation, by default it will return the Default strategy.

See the docs for more information.

Upvotes: 9

Related Questions