I'm trying to fetch subcategories from api, based on PAREND ID, using Vue and Django
So, I have 2 categories:
- Phone Brands
- Phone Models
Example:
Category: Sony, id:1 < Related subcategory: XZ3, XZ2, XZ...
Category: Samsung, id:2 < Related subcategory: S10, S9, S8...
So when the user click on 'Sony, id:1' category(router-link), I want all data based on that Category(parent)ID to be displayed on the screen(inside component). What is happening now, when I pass ID from parent to child component, response returns only 1 objects, that matches ID which I get from parent ID. Like, Sony(parent category) have ID:1, XZ3 (child category)have ID:1 too, so it show only matched ID inside component, nothing else
DJANGO
views.py:
from rest_framework import serializers
from . models import Specs, Models, Brands
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from . serializers import ModelsSerializer, SpecsSerializer, BrandsSerializer
# Create your views here.
@api_view(['GET'])
def BrandsView(request):
brand = Brands.objects.all()
serializer = BrandsSerializer(brand, many=True)
return Response(serializer.data)
@api_view(['GET'])
def ModelsView(request, pk):
model = Models.objects.get(pk=pk)
serializer = ModelsSerializer(model, many=False)
return Response(serializer.data)
@api_view(['GET'])
def SpecsView(request, pk):
specs = Specs.objects.get(pk=pk)
serializer = SpecsSerializer(specs, many=False)
return Response(serializer.data)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.BrandsView),
path('models/<pk>/', views.ModelsView),
path('specs/<pk>/', views.SpecsView)
]
models.py
from django.db import models
from django.db.models.deletion import CASCADE
from django.urls import base, reverse
# from django_resized import ResizedImageField
from django.utils import timezone
# Create your models here.
class Brands(models.Model):
brand = models.CharField(max_length=20)
def __str__(self):
return(f'{ self.brand }')
class Models(models.Model):
brand = models.ForeignKey('Brands', on_delete=models.CASCADE, null=True)
model = models.CharField(max_length=100)
createdOn = models.DateField(default=timezone.now)
warranty = models.BooleanField()
damaged = models.BooleanField()
repaired = models.BooleanField()
firstOwner = models.BooleanField()
price = models.IntegerField()
def __str__(self):
return(f'{ self.brand } - { self.model } / { self.price }e / Created: { self.createdOn }')
class Specs(models.Model):
model = models.ForeignKey('Models', on_delete=models.CASCADE, null=True)
dimensions = models.CharField(max_length=50)
weight = models.CharField(max_length=10)
screen = models.CharField(max_length=200)
cpu = models.CharField(max_length=100)
gpu = models.CharField(max_length=100)
mainCam = models.CharField(max_length=50)
selfieCam = models.CharField(max_length=50)
video = models.CharField(max_length=100)
battery = models.CharField(max_length=10)
fastCharging = models.BooleanField()
def __str__(self):
return(f'{ self.model }')
serializers.py
from django.db import models
from django.db.models import fields
from . models import Specs, Models, Brands
from rest_framework import serializers
class BrandsSerializer(serializers.ModelSerializer):
class Meta:
model = Brands
fields = '__all__'
class ModelsSerializer(serializers.ModelSerializer):
class Meta:
model = Models
fields = '__all__'
class SpecsSerializer(serializers.ModelSerializer):
class Meta:
model = Specs
fields = '__all__'
VUE
index.js
import { createRouter, createWebHistory } from 'vue-router'
import About from '../views/About.vue'
import Models from '../views/Models.vue'
import Specs from '../views/Specs.vue'
import Brands from '../views/Brands.vue'
const routes = [
{
path: '/',
name: 'Brands',
component: Brands
},
{
path: '/models/:id',
name: 'Models',
component: Models,
props: true
},
{
path: '/specs/:id',
name: 'Specs',
component: Specs,
props: true
},
{
path: '/about',
name: 'About',
component: About
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
brands.vue
<template>
<div>
<h1> Brands </h1>
<div v-for="brand in brands" v-bind:key="brand.brand">
<router-link :to="{ name: 'Models', params: {id: brand.id} }">
{{ brand }}
</router-link>
</div>
</div>
</template>
import axios from 'axios'
export default {
data(){
return {
brands: []
}
},
mounted(){
axios.get('http://localhost:8000/')
.then(response => {
this.brands = response.data
})
},
}
Models.vue
<template>
<div>
<h1> Models </h1>
<div v-if="models">
<hr>
<table>
<tr>
<th> Model </th>
<th> Created </th>
<th> Warranty </th>
<th> Damaged </th>
<th> Repaired </th>
<th> First Owner </th>
<th> Price </th>
<!-- <th> More Specs </th> -->
</tr>
<tr>
<td> {{ models.model }} </td>
<td> {{ models.createdOn }} </td>
<td> {{ models.warranty }} </td>
<td> {{ models.damaged }} </td>
<td> {{ models.repaired }} </td>
<td> {{ models.firstOwner }} </td>
<td> {{ models.price }}e </td>
<th>
<!-- <router-link :to="{ name: 'Specs', params: {id: model.id} }">
HERE
</router-link> -->
</th>
</tr>
</table>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
props: ['id'],
// template: ['id'],
data(){
return {
models: []
}
},
mounted(){
axios.get('http://localhost:8000/models/' + this.id)
.then(response => {
this.models = response.data
})
}
}
</script>
<style scoped>
.models{
background-color: lightcyan;
border: 10px;
}
</style>
Specs.vue
<template>
<div v-if="specs" class="specs">
<ul>
<li> <b>Model:</b> {{ specs.model }} </li> <br>
<li> <b>Dimensions:</b> {{ specs.dimensions }} </li> <br>
<li> <b>Weight:</b> {{ specs.weight }} </li> <br>
<li> <b>Screen:</b> {{ specs.screen }} </li> <br>
<li> <b>Cpu:</b> {{ specs.cpu }} </li> <br>
<li> <b>Gpu:</b> {{ specs.gpu }} </li> <br>
<li> <b>Main Camera:</b> {{ specs.mainCam }} </li> <br>
<li> <b>Front Camera:</b> {{ specs.selfieCam }} </li> <br>
<li> <b>Video:</b> {{ specs.video }} </li> <br>
<li> <b>Battery:</b> {{ specs.battery }} </li> <br>
<li> <b>Fast Charging:</b> {{ specs.fastCharging }} </li> <br>
</ul>
<hr>
<router-link to="/"> Back to HOME </router-link>
</div>
</template>
<script>
import axios from 'axios'
export default {
props: ['id'],
data(){
return {
specs: [],
}
},
mounted(){
axios.get('http://localhost:8000/specs/' + this.id)
.then(response => {
this.specs = response.data
})
}
}
</script>
<style scoped>
.specs ul li {
list-style-type: none;
float: left;
}
/* .th {
border: 1px solid;
border-radius: 10px;
padding: 20px;
margin: 10% auto;
box-shadow: 5px 5px 10px 5px ;
background-color: aliceblue;
} */
.specs {
background-color: lightcyan;
border: 10px;
padding: 10px;
}
</style>
Brands
serializer, you can show the nestedModels
information. Have a look here to get an idea on how to do it – bdbd