I have two models: Category, Products. And I want to create a separate url link like http://127.0.0.1:8000/api/categories/sneakers for each category to retrieve products from different urls. Using foreign key I can separate them but don't really know how to give them a url. Could you help me with this, please?
CodePudding user response:
You can do something like this:
As example:
Your models.py
class Category(models.Model):
name = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=50, unique=True)
price = models.IntegerField()
brand = models.CharField(max_length=20)
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
barcode = models.IntegerField(default=None, validators=[MinValueValidator(10000000), MaxValueValidator(99999999)], unique=True)
image = models.CharField(max_length=264)
def __str__(self):
return self.name
Your serializers.py
class ProductListSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('id', 'name')
class ProductDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('id', 'name', 'price', 'brand', 'category', 'barcode', 'image')
depth = 1
class CategoryListSerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name')
class CategoryDetailSerializer(serializers.ModelSerializer):
products = ProductDetailSerializer(many=True)
class Meta:
model = Category
fields = ('id', 'name', 'products')
Your views.py
class CategoryListAPIView(generics.ListAPIView):
queryset = Category.objects.all()
serializer_class = serializers.CategoryListSerializer
class CategoryDetailAPIView(generics.RetrieveAPIView):
queryset = Category.objects.all()
serializer_class = serializers.CategoryDetailSerializer
lookup_field = 'name'
class ProductListAPIView(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = serializers.ProductListSerializer
class ProductDetailAPIView(generics.RetrieveAPIView):
queryset = Product.objects.all()
serializer_class = serializers.ProductDetailSerializer
lookup_field = 'name'
Your urls.py
urlpatterns = [
path('categories/', views.CategoryListAPIView.as_view(), name='category-list'),
path('categories/<str:name>', views.CategoryDetailAPIView.as_view(), name='category-detail'),
path('products/', views.ProductListAPIView.as_view(), name='product-list'),
path('products/<str:name>', views.ProductDetailAPIView.as_view(), name='product-detail'),
]
CodePudding user response:
One solution is to register a URL with a placeholder that assigns part of the path to a variable:
# urls.py
urls = [
path('api/categories/<string:category>', views.product_by_category, name=product_by_category)
]
Now django will send a category
parameter to your view that you can use to get the products you want:
# views.py
def product_by_category(request, category):
# get the products and serialize them as JSON or render a template to HTML
pass
You will need to replace pass
with the appropriate logic to return the correct response.