Reputation: 49
Goal
I am trying to create a simple Stock management Django REST API. When I specify by id in the urls.py, it successfully retrieves all the data. However, I would like to use the name of the product to retrieve data instead of the id number. I am new for Django, so if anybody could help me out I appreciate it.
Tried
I tried str:name instead of int:pk
-> Error: AssertionError: Expected view StockDetail to be called with a URL keyword argument named "pk". Fix your URL conf, or set the .lookup_field
attribute on the view correctly.
When I added to lookup_fields = ('name')
->Error: 'StockDetailView' has no attribute '_meta'
When I added class Meta: under StockDetail in the views.py
it still gave me the same error
I have seen some answers for similar questions using assigning names to slug and using the slug instead of id. I tried by looking at some posts on StackOverflow, but could not able to implement to the goal. If using slug is the case, please demonstrate slug using my code.
Again, I am new to django, so I might be silly question, but I appreciate for the help.
models.py
from django.db import models
# Create your models here.
class Stock(models.Model):
name = models.CharField(max_length=50)
stock_number = models.IntegerField('Number of Stocks', )
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return self.name
views.py
from rest_framework import generics
from .models import Stock
from .serializers import StockSerializer
class StockList(generics.ListCreateAPIView):
queryset = Stock.objects.all()
serializer_class = StockSerializer
class StockDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Stock.objects.all()
serializer_class = StockSerializer
Serializers.py
from rest_framework import serializers
from .models import Stock
class StockSerializer(serializers.ModelSerializer):
class Meta:
fields = ('id', 'name', 'stock_number', 'price')
model = Stock
urls.py
from django.urls import path
from .views import StockList, StockDetail
urlpatterns = [
path('<int:ok>/', StockDetail.as_view()),
path('', StockList.as_view()),
]
Upvotes: 1
Views: 80
Reputation: 2863
First of all, note that name
field is not unique. So you shouldn't try to get one object with just a name.
But, assuming that name
is unique, lookup_field
should not be a tuple instance:
models:
class Stock(models.Model):
name = models.CharField(max_length=50, unique=True)
...
views:
class StockDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Stock.objects.all()
serializer_class = StockSerializer
lookup_field = 'name'
urls:
...
path('<str:name>/', StockDetail.as_view()),
And if your name
is not unique(makes more sense), use your StockList
and override get_queryset()
:
class StockList(generics.ListCreateAPIView):
serializer_class = StockSerializer
def get_queryset(self):
name = self.kwargs['name']
return Stock.objects.filter(name=name)
Upvotes: 1