I am currently making an API to return JSON for a product.
Currently using Django rest framework, I have successfully implemented the API to view all products via
path/api/products
to show a JSON of all products:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"url": "http://127.0.0.1:8000/api/products/1/",
"id": 1,
"brand": "Mars",
"name": "Barres",
"barcode": 5000159366168,
"category": "Snacks, Snacks sucrés, Cacao et dérivés, Confiseries, Barres, Confiseries chocolatées, Barres chocolatées, Barres chocolatées au caramel",
"allergens": "gluten,milk,soybeans",
"weight": 540.0,
"quantity": 1,
"footprint": 2.28655779803366e-06,
"perishable": false
},
{
"url": "http://127.0.0.1:8000/api/products/2/",
"id": 2,
"brand": "Twix",
"name": "Twix",
"barcode": 5000159366267,
"category": "Snacks, Snacks sucrés, Confiseries, Barres",
"allergens": "gluten,nuts",
"weight": 600.0,
"quantity": 1,
"footprint": 0.0,
"perishable": false
},
{
"url": "http://127.0.0.1:8000/api/products/3/",
"id": 3,
"brand": "Twix",
"name": "Twix salted caramel",
"barcode": 5000159528955,
"category": "Biscuits et gâteaux, Biscuit chocolat",
"allergens": "caramel, choclate, wheat",
"weight": 46.0,
"quantity": 1,
"footprint": 0.0,
"perishable": false
}
]
However, I would like to be able to receive the JSON object of only one product by barcode:
for example
path/api/products/5000159366168 or path/api/products/?barcode=5000159366168
to return only the product that matches the barcode:
{
"url": "http://127.0.0.1:8000/api/products/1/",
"id": 1,
"brand": "Mars",
"name": "Barres",
"barcode": 5000159366168,
"category": "Snacks, Snacks sucrés, Cacao et dérivés, Confiseries, Barres, Confiseries chocolatées, Barres chocolatées, Barres chocolatées au caramel",
"allergens": "gluten,milk,soybeans",
"weight": 540.0,
"quantity": 1,
"footprint": 2.28655779803366e-06,
"perishable": false
}
Here is my code:
my views.py:
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
my serializers.py:
from app1.models import Product
from rest_framework import serializers
class ProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Product
fields = ["url","id", "brand", "name", "barcode","category","allergens", "weight", "quantity", "footprint","perishable"]
my urls.py:
router = routers.DefaultRouter()
router.register(r'products', views.ProductViewSet)
urlpatterns = [
...
path('api/', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
CodePudding user response:
You need to override get_queryset() method to filter your data with your barcode or any other filter you want.
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
def get_queryset(self):
super(ProductViewSet, self).get_queryset()
barcode= request.query_params.get('barcode', None)
queryset = Product.objects.all()
if barcode:
queryset = Product.objects.filter(barcode=barcode)
return queryset
Notice: How I added if condition for barcode that only if barcode variable have some data in it, filter it otherwise simply return the normal queryset.
CodePudding user response:
With help from Asim Ejaz
Here is my working View.py class
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
def get_queryset(self):
super(ProductViewSet, self).get_queryset()
barcode = self.request.query_params.get('barcode', None)
print("Barcode = ", barcode)
print(self)
queryset = Product.objects.all()
if barcode:
queryset = Product.objects.filter(barcode=barcode)
return queryset
Notice: barcode = self.request
as request is not previously defined
If you too run into this error, ensure the request is typed in properly, in this case it should be, http://127.0.0.1:8000/api/products/?barcode=5000159366168