【问题标题】:I want to fetch all subcategories based on my parent ID category. Using Django/Vuejs. More info bellow我想根据我的父 ID 类别获取所有子类别。使用 Django/Vuejs。更多信息如下
【发布时间】:2021-10-03 18:25:39
【问题描述】:

我正在尝试使用 Vue 和 Django 根据 PAREND ID 从 api 获取子类别

所以,我有 2 个类别:

  • 手机品牌
  • 手机型号

例子:

类别:索尼,id:1

类别:三星,id:2

因此,当用户单击“Sony,id:1”类别(路由器链接)时,我希望基于该类别(父)ID 的所有数据都显示在屏幕上(组件内部)。现在发生了什么,当我将 ID 从父组件传递到子组件时,响应仅返回 1 个对象,该对象与我从父 ID 获得的 ID 匹配。比如,Sony(父类)有 ID:1,XZ3(子类)也有 ID:1,所以它只显示组件内匹配的 ID,没有别的


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 }')

序列化器.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>
从'axios'导入axios 导出默认 { 数据(){ 返回 { 品牌: [] } }, 挂载(){ axios.get('http://localhost:8000/') .then(响应 => { this.brands = response.data }) }, }

模型.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 序列化程序中,您可以显示嵌套的Models 信息。看看here 了解如何操作

标签: javascript python django api vue.js


【解决方案1】:

您需要在 Brands 模型和 Models 模型之间创建嵌套序列化程序。因此,您可以将以下序列化程序类添加到您的 serializers.py,将视图添加到您的 views.py,并将 url 路径添加到您的 urls.py。当然,您可以随意命名类、函数和 url 路由。另外,我建议您阅读 DRF 文档中的“嵌套序列化”一章。

// serializers.py
class Brands_ModelsSerializer(serializers.ModelSerializer):
    models = ModelsSerializer(source="models_set", many=True)
    class Meta:
        model = Brands
        fields = ['models']

// views.py
@api_view(['GET'])
def brand_with_models(request, pk):
    brand_models = Brands.objects.get(pk=pk)
    serializer = Brands_ModelsSerializer(brand_models)
    return Response(serializer.data)

// urls.py
path('brand_models/<pk>/', views.brand_with_models)

【讨论】:

  • 所以,这是关于序列化程序的。发生了很多事情,我无法弄清楚问题可能出在哪里。非常感谢!
  • @DejanJovanovic,不客气。如果这回答了您的问题,请考虑投票/接受答案。
  • 像魅力一样工作!我的声望现在是 11,但只要我达到 15,我肯定会投票!
猜你喜欢
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 2017-05-14
  • 2015-09-18
  • 1970-01-01
相关资源
最近更新 更多