【问题标题】:(React and Django) Displaying products on the homepage is working fine, but when I click on any particular product, then the rendering is wrong(React 和 Django)在主页上显示产品工作正常,但是当我单击任何特定产品时,呈现错误
【发布时间】:2025-05-12 08:15:01
【问题描述】:

这篇文章是以下系列的第三部分——(你可以跳过前两部分,但是它可以作为参考)

  1. A large number of problems with React, Django, Django REST and Axios
  2. Products on the homepage are not being displayed properly (Django, Django Rest and React)
  3. (React and Django) Displaying products on the homepage is working fine, but when I click on any particular product, then the rendering is wrong

(注意:HomeScreen.Js 和 ProductScreen.js 的代码在第三部分更新,因此与前两部分显示的这些文件的代码不同)

我的主页是这样的——

但是当我点击任何特定产品时,我会得到这个结果 -

我正在和我的朋友咨询这个问题,他告诉我,我的 React 代码应该没问题,问题应该在 Django 内部的某个地方。

当我检查我的命令提示符(从中运行我的 Django 服务器)时 - 当我尝试显示产品编号 1 时,我得到了这个输出 - [11/Mar/2021 19:18:05] "GET /api/products/1 HTTP/1.1" 200 2123

请看一下代码,也许你会发现一些隐藏的错误。

HomeScreen.js -

import React, { useState, useEffect }  from "react";
import { Row, Col } from "react-bootstrap";
import Product from "../components/Product";
import axios from "axios"

function HomeScreen() {
  const [products, setProducts] = useState([])

  useEffect(() => {
    
    async function fetchProducts() {
     const { data } = await axios.get('/api/products/')
     setProducts(data)
    }  

    fetchProducts()
  },[] )

  return (
    <div>
      <h1>Latest Products</h1>
      <Row>
        {products.map((product) => (
          <Col key={product._id} sm={12} md={6} lg={4} xl={3}>
            <Product product={product} />
          </Col>
        ))}
      </Row>
    </div>
  );
}

export default HomeScreen;

ProductScreen.js -

import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Row, Col, Image, ListGroup, Button, Card } from "react-bootstrap";
import Rating from "../components/Rating";
import axios from "axios"

function ProductScreen({ match }) {

  const [product, setProduct] = useState([])

  useEffect(() => {
    
    async function fetchProduct() {
     const { data } = await axios.get(`/api/products/${match.params.id}`)
     setProduct(data)
    }  

    fetchProduct()
  },[] )

  return (
    <div>
      <Link to="/" className="btn btn-light my-3">
        Go Back
      </Link>
      <Row>
        <Col md={6}>
          <Image src={product.image} alt={product.name} fluid />
        </Col>

        <Col md={3}>
          <ListGroup variant="flush">
            <ListGroup.Item>
              <h3>{product.name}</h3>
            </ListGroup.Item>

            <ListGroup.Item>
              <Rating
                value={product.rating}
                text={`${product.numReviews} reviews`}
                color={"#f8e825"}
              />
            </ListGroup.Item>

            <ListGroup.Item>Price: ${product.price}</ListGroup.Item>

            <ListGroup.Item>Description: {product.description}</ListGroup.Item>
          </ListGroup>
        </Col>

        <Col md={3}>
          <Card>
            <ListGroup variant="flush">
              <ListGroup.Item>
                <Row>
                  <Col>Price:</Col>
                  <Col>
                    <strong>${product.price}</strong>
                  </Col>
                </Row>
              </ListGroup.Item>

              <ListGroup.Item>
                <Row>
                  <Col>Status:</Col>
                  <Col>
                    {product.countInStock > 0 ? "In Stock" : "Out of Stock"}
                  </Col>
                </Row>
              </ListGroup.Item>

              <ListGroup.Item>
                <Button
                  className="btn-block"
                  disabled={product.countInStock == 0}
                  type="button"
                >
                  Add to Cart
                </Button>
              </ListGroup.Item>
            </ListGroup>
          </Card>
        </Col>
      </Row>
    </div>
  );
}

export default ProductScreen;

package.json -

{
  "name": "frontend",
  "proxy": "http://127.0.0.1:8000",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/user-event": "^12.7.0",
    "axios": "^0.21.1",
    "react": "^17.0.1",
    "react-bootstrap": "^1.4.3",
    "react-dom": "^17.0.1",
    "react-router-bootstrap": "^0.25.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.2",
    "web-vitals": "^1.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

urls.py(在基本应用文件夹内)-

from django.conf.urls import url
from . import views

urlpatterns = [
    
    url('products/', views.getProducts, name="products"),
    url('products/<str:pk>/', views.getProduct, name="product"),
    url('routes/', views.getRoutes, name="routes"),
]

views.py -

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework.response import Response

from .products import products

# Create your views here.
@api_view(['GET'])
def getRoutes(request):
    routes = [
    '/api/products/',
    '/api/products/create/',

    'api/products/upload/',

    'api/products/<id>/reviews/',

    'api/products/top/',
    'api/products/<id>/',

    'api/products/delete/<id>/',
    'api/products/<update>/<id>/',

    ]
    return Response(routes)

@api_view(['GET'])
def getProducts(request):
    return Response(products)

@api_view(['GET'])
def getProduct(request, pk):
    product = None
    for i in products:
        if i['_id'] == pk:
            product = i
            break

    return Response(product)

如果您发现此错误的任何解决方案,请告诉我。非常感谢您最终的回答。

【问题讨论】:

    标签: python reactjs django django-views rendering


    【解决方案1】:

    通过将 Django 的版本从 3.1.6 更改为 3.1.4 解决了这个问题,我也更改了这个 -

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        
        url('products/', views.getProducts, name="products"),
        url('products/<str:pk>/', views.getProduct, name="product"),
        url('routes/', views.getRoutes, name="routes"),
    ]
    

    回到这个 -

    from django.urls import path
    from . import views
    
    urlpatterns = [
        
        path('products/', views.getProducts, name="products"),
        path('products/<str:pk>/', views.getProduct, name="product"),
        path('routes/', views.getRoutes, name="routes"),
    ]
    

    【讨论】: