Add product with options not working
babanazar opened this issue · comments
Hi,
I have forked and cloned django oscar api. When I try to call /basket/add-service/
with options, it is not working. I see it on request.data but it does not appear in p_ser.validated_data property.
Can you please help?
EDIT:
By /basket/add-service/
I meant /basket/add-product/
Hi Babanazar,
I don’t know where this add-service
endpoint is coming from but this is not part of oscarapi. How you can add options to a product is to be seen in the unit tests:
There is also an example to be found in the documentation.
@babanazar Did the examples mentioned above help you?
@maerteijn Thank you for your answer.
But unfortunately, I still can not solve the issue. I see the 'options' in request.data variable but it does not exist in p_ser.validated_data. Thus it is ignored and not added.
I have been debugging lately. I think my issue is similar to issue in the link.
https://stackoverflow.com/questions/68687339/django-rest-framework-cant-identify-serializer-field-name
I share screenshot of code where I think my input does not match. Here in match = regex.match(field)
, match is None
even if field = 'options'
.
@babanazar When I run the test mentioned above and manually inspect the options, I can see they are there:
(oscarapi) martijn@neopro:~/Dev/oss/django-oscar-api (master)$ sandbox/manage.py test oscarapi.tests.unit.testbasket.BasketTest.test_add_put_product_option
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
ipdb> l
122 quantity = p_ser.validated_data["quantity"]
123 options = p_ser.validated_data.get("options", [])
124
125 import ipdb; ipdb.set_trace()
126
--> 127 basket_valid, message = self.validate(basket, product, quantity, options)
128 if not basket_valid:
129 return Response(
130 {"reason": message}, status=status.HTTP_406_NOT_ACCEPTABLE
131 )
132
ipdb> options
[OrderedDict([('option', <Option: Color>), ('value', 'red')])]
So this is not an Oscar API issue, so what did you do in your project? Did you overrride the views or serializers, and if so, please provide what you changed? And what is this add-service
endpoint?
@maerteijn thank you for response.
I forked and modified the project. I renamed product
model to service
. I want to build a platform that sells services instead of products.
The rest of the project is functional. This part also passes the tests but I can not manage to add options via postman request.
Ok, please try to follow a similar scenario with the requests
library as described in the documentation.
Is it still not possible to add options? (check: Did you provide the correct option_url
)?
@maerteijn , I followed exactly the same steps described in the documentation. I still can not add options.
I provide the log of my steps in the attachment.
Can you please help me solve the issue with customizaiton?
@babanazar Ehm sorry, but your log is very messy and when you are trying to print the content of the basket lines, they are empty. That should ring a bell:
>> response = session.post('http://localhost:8000/api/basket/add-service/', json=data)
>>> response = session.get('http://localhost:8000/api/basket/')
>>> lines_url = response.json()['lines']
>>> response = session.get(lines_url)
>>> print(response.content)
b'[]'
When there is nothing in your basket, there are no options of course. Please check the output of the response your first line response = session.post('http://localhost:8000/api/basket/add-service/', json=data)
as it was not succesful adding anything to your basket.
Please use the browsable api at http://localhost:8000/api/basket/ to check if something is in your basket lines at all. With a vanilla Oscar API install you can post this to the http://localhost:8000/api/basket/add-product/ endpoint :
{
"url": "http://localhost:8000/api/products/1/",
"quantity": 1,
"options": [{
"option": "http://localhost:8000/api/options/1/", "value": "blue"
}]
}
Your basket result looks like this then:
{
"id": 2,
"status": "Open",
"lines": "http://localhost:8000/api/baskets/2/lines/",
"url": "http://localhost:8000/api/baskets/2/",
"total_excl_tax": "10.00",
"total_excl_tax_excl_discounts": "10.00",
"total_incl_tax": "10.00",
"total_incl_tax_excl_discounts": "10.00",
"total_tax": "0.00",
"currency": "EUR",
"voucher_discounts": [],
"offer_discounts": [],
"is_tax_known": true
}
And when you follow the lines url you should see something like this:
[
{
"url": "http://localhost:8000/api/baskets/2/lines/5/",
"product": "http://localhost:8000/api/products/1/",
"quantity": 1,
"attributes": [
{
"url": "http://localhost:8000/api/baskets/2/lines/5/lineattributes/2/",
"value": "blue",
"option": "http://localhost:8000/api/options/1/"
}
],
"price_currency": "EUR",
"price_excl_tax": "10.00",
"price_incl_tax": "10.00",
"price_incl_tax_excl_discounts": "10.00",
"price_excl_tax_excl_discounts": "10.00",
"is_tax_known": true,
"warning": null,
"basket": "http://localhost:8000/api/baskets/2/",
"stockrecord": "http://localhost:8000/api/products/1/stockrecords/1/",
"date_created": "2021-12-14T19:33:35.588563Z",
"date_updated": "2021-12-14T19:33:35.588625Z"
}
]
As you can see, the option becomes a line attribute with the posted value blue
.
I share screenshot of code where I think my input does not match. Here in match = regex.match(field), match is None even if field = 'options'.
I don't think your problem has anything to do with https://stackoverflow.com/questions/68687339/django-rest-framework-cant-identify-serializer-field-name
I forked and modified the project. I renamed product model to service. I want to build a platform that sells services instead of products.
I would recommend not to do that. Just rename some of the endpoints if you are exposing your api to other developers, but keep the django model names etc. It will cause nothing but trouble with the Oscar ecosystem.
It worked when I tried steps in the documentation in the command line. It also worked with raw data in postman. I think the issue is with my data format in x-www-form-urlencoded form. As a result, the issue is solved. Thanks for your guidance.